diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4d266c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Ignore VS Code folders +.vscode +.build diff --git a/CD32ControllerUSB/CD32ControllerUSB.ino b/CD32ControllerUSB/CD32ControllerUSB.ino index b5b6932..284313c 100644 --- a/CD32ControllerUSB/CD32ControllerUSB.ino +++ b/CD32ControllerUSB/CD32ControllerUSB.ino @@ -47,8 +47,8 @@ // (Second controller port for future reference) // 1 15 PB1 // 2 14 PB3 -// 3 16 PB2 -// 4 10 PB6 +// 3 2 PD1 +// 4 5 PC6 // 5 A2 PF5 // 6 7 PE6 (Important: Connect this pin via a 220Ω resistor!) // 7 VCC diff --git a/SNESControllersUSB/README.md b/SNESControllersUSB/README.md index b208d78..56ce7fd 100644 --- a/SNESControllersUSB/README.md +++ b/SNESControllersUSB/README.md @@ -9,7 +9,7 @@ With this simple to build adapter you can connect NES gamepads to a PC, Raspber - Micro USB cable ## Wiring -![Assemble1](images/nes-usb-adapter-wiring.png) +![Assemble1](images/snes-usb-adapter-wiring.png) ## License This project is licensed under the GNU General Public License v3.0. diff --git a/SNESControllersUSB/images/snes-usb-adapter-wiring.png b/SNESControllersUSB/images/snes-usb-adapter-wiring.png new file mode 100644 index 0000000..a443ebf Binary files /dev/null and b/SNESControllersUSB/images/snes-usb-adapter-wiring.png differ diff --git a/SegaTwoControllersUSB/README.md b/SegaTwoControllersUSB/README.md new file mode 100644 index 0000000..2a67d5d --- /dev/null +++ b/SegaTwoControllersUSB/README.md @@ -0,0 +1,25 @@ +# DaemonBite Sega Controllers To USB Adapter +## Introduction +This is a simple to build adapter for connecting two Mega Drive (Genesis), Master System (+ Atari and C= controllers) to USB. It supports 3 and 6-button Mega Drive controllers and 1 and 2-button SMS/Atari/C= controllers. + +The input lag for this adapter is minimal. Here is the result from a test with a 1ms polling rate on a MiSTer (one port version): + +| Controller | Samples | Average | Max | Min | Std Dev | +| ------ | ------ | ------ | ------ | ------ | ------ | +| Original 3-Button Mega Drive Controller | 2342 | 0.75ms | 1.28ms | 0.24ms | 0.29ms | +| 8bitdo M30 Wireless 2.4G | 2348 | 4.54ms | 8.05ms | 2.22ms | 1.31ms | + +## Parts you need +- Arduino Pro Micro (ATMega32U4) +- 2x Male end of Mega Drive controller extension (or DSUB 9Pin Male connectors and some wires) +- Heat shrink tube (Ø ~20mm) +- Micro USB cable + +## Wiring +![Assemble1](images/sega-usb-2x-adapter-wiring.png) + +## License +This project is licensed under the GNU General Public License v3.0. + +## Credits +The Mega Drive gamepad interface is based on this repository : https://github.com/jonthysell/SegaController but almost entirely rewritten and a lot of optimisations have been made. diff --git a/SegaTwoControllersUSB/SegaControllers32U4.cpp b/SegaTwoControllersUSB/SegaControllers32U4.cpp index e0a01b0..958f0b5 100644 --- a/SegaTwoControllersUSB/SegaControllers32U4.cpp +++ b/SegaTwoControllersUSB/SegaControllers32U4.cpp @@ -33,25 +33,28 @@ SegaControllers32U4::SegaControllers32U4(void) { - // Setup select pin as output high (16, PB2) - DDRB |= B00000100; // output - PORTB |= B00000100; // high + // Setup select pin as output high (6, PD7) + DDRD |= B10000000; // output + PORTD |= B10000000; // high // Setup select pin as output high (5, PC6) DDRC |= B01000000; // output PORTC |= B01000000; // high - // Setup input pins (A0,A1,A2,A3,14,15,16 or PF7,PF6,PF5,PF4,PB3,PB1,PB2) + // Setup input pins (A0,A1,A2,A3,14,15 or PF7,PF6,PF5,PF4,PB3,PB1) DDRF &= ~B11110000; // input PORTF |= B11110000; // high to enable internal pull-up DDRB &= ~B00001010; // input PORTB |= B00001010; // high to enable internal pull-up - // Setup input pins (TXO,RXI,2,3,4,6 or PD3,PD2,PD1,PD0,PD4,PD7) - DDRD &= ~B10011111; // input - PORTD |= B10011111; // high to enable internal pull-up + // Setup input pins (TXO,RXI,2,3,4,6 or PD3,PD2,PD1,PD0,PD4,PE6) + DDRD &= ~B00011111; // input + PORTD |= B00011111; // high to enable internal pull-up + DDRE &= ~B01000000; // input + PORTE |= B01000000; // high to enable internal pull-up _inputReg1 = 0; _inputReg2 = 0; _inputReg3 = 0; + _inputReg4 = 0; for(byte i=0; i<=1; i++) { _currentState[i] = 0; @@ -77,7 +80,7 @@ word SegaControllers32U4::getStateMD1() // Set the select pin low/high _pinSelect[0] = !_pinSelect[0]; - (!_pinSelect[0]) ? PORTB &= ~B00000100 : PORTB |= B00000100; // Set LOW on even cycle, HIGH on uneven cycle + (!_pinSelect[0]) ? PORTD &= ~B10000000 : PORTD |= B10000000; // Set LOW on even cycle, HIGH on uneven cycle // Short delay to stabilise outputs in controller delayMicroseconds(SC_CYCLE_DELAY); @@ -166,6 +169,7 @@ word SegaControllers32U4::getStateMD2() // Read input register(s) _inputReg3 = PIND; + _inputReg4 = PINE; if(_ignoreCycles[1] <= 0) { @@ -192,7 +196,7 @@ word SegaControllers32U4::getStateMD2() (bitRead(_inputReg3, DB9_PIN3_BIT2) == LOW) ? _currentState[1] |= SC_BTN_LEFT : _currentState[1] &= ~SC_BTN_LEFT; (bitRead(_inputReg3, DB9_PIN4_BIT2) == LOW) ? _currentState[1] |= SC_BTN_RIGHT : _currentState[1] &= ~SC_BTN_RIGHT; (bitRead(_inputReg3, DB9_PIN6_BIT2) == LOW) ? _currentState[1] |= SC_BTN_B : _currentState[1] &= ~SC_BTN_B; - (bitRead(_inputReg3, DB9_PIN9_BIT2) == LOW) ? _currentState[1] |= SC_BTN_C : _currentState[1] &= ~SC_BTN_C; + (bitRead(_inputReg4, DB9_PIN9_BIT2) == LOW) ? _currentState[1] |= SC_BTN_C : _currentState[1] &= ~SC_BTN_C; } } else // No Mega Drive controller is connected, use SMS/Atari mode @@ -206,7 +210,7 @@ word SegaControllers32U4::getStateMD2() if (bitRead(_inputReg3, DB9_PIN3_BIT2) == LOW) { _currentState[1] |= SC_BTN_LEFT; } if (bitRead(_inputReg3, DB9_PIN4_BIT2) == LOW) { _currentState[1] |= SC_BTN_RIGHT; } if (bitRead(_inputReg3, DB9_PIN6_BIT2) == LOW) { _currentState[1] |= SC_BTN_A; } - if (bitRead(_inputReg3, DB9_PIN9_BIT2) == LOW) { _currentState[1] |= SC_BTN_B; } + if (bitRead(_inputReg4, DB9_PIN9_BIT2) == LOW) { _currentState[1] |= SC_BTN_B; } } } else // Select pin is LOW @@ -223,7 +227,7 @@ word SegaControllers32U4::getStateMD2() if(!_sixButtonMode[1]) { (bitRead(_inputReg3, DB9_PIN6_BIT2) == LOW) ? _currentState[1] |= SC_BTN_A : _currentState[1] &= ~SC_BTN_A; - (bitRead(_inputReg3, DB9_PIN9_BIT2) == LOW) ? _currentState[1] |= SC_BTN_START : _currentState[1] &= ~SC_BTN_START; + (bitRead(_inputReg4, DB9_PIN9_BIT2) == LOW) ? _currentState[1] |= SC_BTN_START : _currentState[1] &= ~SC_BTN_START; } } } diff --git a/SegaTwoControllersUSB/SegaControllers32U4.h b/SegaTwoControllersUSB/SegaControllers32U4.h index 34833d1..f585303 100644 --- a/SegaTwoControllersUSB/SegaControllers32U4.h +++ b/SegaTwoControllersUSB/SegaControllers32U4.h @@ -56,7 +56,7 @@ enum DB9_PIN3_BIT2 = 1, DB9_PIN4_BIT2 = 0, DB9_PIN6_BIT2 = 4, - DB9_PIN9_BIT2 = 7 + DB9_PIN9_BIT2 = 6 }; const byte SC_INPUT_PINS = 6; @@ -83,6 +83,7 @@ class SegaControllers32U4 { byte _inputReg1; byte _inputReg2; byte _inputReg3; + byte _inputReg4; }; #endif diff --git a/SegaTwoControllersUSB/SegaTwoControllersUSB.ino b/SegaTwoControllersUSB/SegaTwoControllersUSB.ino index 584f78e..d1e7775 100644 --- a/SegaTwoControllersUSB/SegaTwoControllersUSB.ino +++ b/SegaTwoControllersUSB/SegaTwoControllersUSB.ino @@ -38,7 +38,7 @@ // 3 A2 PF5 // 4 A3 PF4 // 6 14 PB3 -// 7 16 PB2 (6 PD7) +// 7 6 PD7 // 9 15 PB1 // 1 TXO PD3 @@ -47,7 +47,7 @@ // 4 3 PD0 // 6 4 PD4 // 7 5 PC6 -// 9 6 PD7 +// 9 7 PE6 SegaControllers32U4 controllers; diff --git a/SegaTwoControllersUSB/images/sega-usb-2x-adapter-wiring.png b/SegaTwoControllersUSB/images/sega-usb-2x-adapter-wiring.png new file mode 100644 index 0000000..e0a0331 Binary files /dev/null and b/SegaTwoControllersUSB/images/sega-usb-2x-adapter-wiring.png differ