#define XINPUT #ifdef XINPUT #include #endif #ifndef XINPUT #define DEBUG #endif //#define DEBUG //doesn't work with XInput // 5V (red) // GND (black) #define DATA1 2 // (brown) #define CMD1 3 // (orange) #define ATT1 4 // (yellow) #define CLK1 5 // (blue) #define JOYSTICK_STATE_SIZE 6 //data[0] //bit0 = select //bit1 = L3 //bit2 = R3 //bit3 = start //bit4 = up //bit5 = right //bit6 = down //bit7 = left //data[1} //bit0 = L2 //bit1 = R2 //bit2 = L1 //bit3 = R1 //bit4 = T //bit5 = O //bit6 = X //bit7 = S #define PS_select (data[0] & ( 1 << 0 )) #define PS_L3 (data[0] & ( 1 << 1 )) #define PS_R3 (data[0] & ( 1 << 2 )) #define PS_start (data[0] & ( 1 << 3 )) #define PS_up (data[0] & ( 1 << 4 )) #define PS_right (data[0] & ( 1 << 5 )) #define PS_down (data[0] & ( 1 << 6 )) #define PS_left (data[0] & ( 1 << 7 )) #define PS_L2 (data[1] & ( 1 << 0 )) #define PS_R2 (data[1] & ( 1 << 1 )) #define PS_L1 (data[1] & ( 1 << 2 )) #define PS_R1 (data[1] & ( 1 << 3 )) #define PS_T (data[1] & ( 1 << 4 )) #define PS_O (data[1] & ( 1 << 5 )) #define PS_X (data[1] & ( 1 << 6 )) #define PS_S (data[1] & ( 1 << 7 )) #define PS_LX (((uint16_t)data[4]*257)-32768) // 0..255 -> -32768..32767 #define PS_LY (((255-(uint16_t)data[5])*257)-32768) // 0..255 -> 32767..-32768 #define PS_RX (((uint16_t)data[2]*257)-32768) // 0..255 -> -32768..32767 #define PS_RY (((255-(uint16_t)data[3])*257)-32768) // 0..255 -> 32767..-32768 uint8_t head; uint8_t type; uint8_t padding; uint8_t data[JOYSTICK_STATE_SIZE]; uint8_t olddata[JOYSTICK_STATE_SIZE]; uint8_t flag; uint8_t shift(uint8_t _dataOut) // Does the actual shifting, both in and out simultaneously { uint8_t _temp = 0; uint8_t _dataIn = 0; uint8_t _delay = 6; //2 unstable; //clock 250kHz delayMicroseconds(100); //max acknowledge waiting time 100us for (uint8_t _i = 0; _i <= 7; _i++) { if ( _dataOut & (1 << _i) ) // write bit digitalWrite(CMD1, HIGH); else digitalWrite(CMD1, LOW); digitalWrite(CLK1, LOW); // read bit delayMicroseconds(_delay); _temp = digitalRead(DATA1); if (_temp) { _dataIn = _dataIn | (B00000001 << _i); } digitalWrite(CLK1, HIGH); delayMicroseconds(_delay); } return _dataIn; } void setup() { pinMode(DATA1, INPUT_PULLUP); pinMode(CMD1, OUTPUT); pinMode(ATT1, OUTPUT); pinMode(CLK1, OUTPUT); #ifdef DEBUG Serial.begin(115200); while(!Serial); #endif #ifdef XINPUT XInput.setAutoSend(false); XInput.begin(); #endif olddata[0] = 0xff; olddata[1] = 0xff; } void loop() { // http://problemkaputt.de/psx-spx.htm#controllerandmemorycardsignals // first: read gamepad normally digitalWrite(ATT1, LOW); //digitalWrite(ATT2, LOW); head = shift(0x01); type = shift(0x42); padding = shift(0x01); //read multitap in next command data[0] = ~shift(0x00); //buttons data[1] = ~shift(0x00); //buttons data[2] = shift(0x00); //right analog data[3] = shift(0x00); //right analog data[4] = shift(0x00); //left analog data[5] = shift(0x00); //left analog digitalWrite(ATT1, HIGH); #ifdef DEBUG Serial.print(" type: 0x"); Serial.print(type, HEX); Serial.print(" data: b"); Serial.print(data[0], BIN); Serial.print(" b"); Serial.print(data[1], BIN); Serial.print(" 0x"); Serial.print(data[2], HEX); Serial.print(" 0x"); Serial.print(data[3], HEX); Serial.print(" 0x"); Serial.print(data[4], HEX); Serial.print(" 0x"); Serial.print(data[5], HEX); Serial.println(); Serial.flush(); delay(500); #endif #ifdef XINPUT if (data[0] != olddata[0]) { if (PS_select) XInput.press(BUTTON_BACK); else XInput.release(BUTTON_BACK); //btn_7 if (PS_start) XInput.press(BUTTON_START); else XInput.release(BUTTON_START); //btn_8 if (PS_L3) XInput.press(BUTTON_L3); else XInput.release(BUTTON_L3); //btn_9 if (PS_R3) XInput.press(BUTTON_R3); else XInput.release(BUTTON_R3); //btn_10 XInput.setDpad(PS_up, PS_down, PS_left, PS_right); olddata[0] = data[0]; } if (data[1] != olddata[1]) { if (PS_X) XInput.press(BUTTON_A); else XInput.release(BUTTON_A); //btn_1 if (PS_O) XInput.press(BUTTON_B); else XInput.release(BUTTON_B); //btn_2 if (PS_S) XInput.press(BUTTON_X); else XInput.release(BUTTON_X); //btn_3 if (PS_T) XInput.press(BUTTON_Y); else XInput.release(BUTTON_Y); //btn_4 if (PS_L1) XInput.press(BUTTON_LB); else XInput.release(BUTTON_LB); //btn_5 if (PS_R1) XInput.press(BUTTON_RB); else XInput.release(BUTTON_RB); //btn_6 if (PS_L2) XInput.setTrigger(TRIGGER_LEFT, 255); else XInput.setTrigger(TRIGGER_LEFT, 0); if (PS_R2) XInput.setTrigger(TRIGGER_RIGHT, 255); else XInput.setTrigger(TRIGGER_RIGHT, 0); olddata[1] = data[1]; } XInput.setJoystick(JOY_LEFT, PS_LX, PS_LY); //left-right: -32768..32767, down-up: 32767..-32768 XInput.setJoystick(JOY_RIGHT, PS_RX, PS_RY); //left-right: -32768..32767, down-up: 32767..-32768 #endif XInput.send(); delayMicroseconds(1000); }