From 444288d5332cce3f6a8ef9269f368567cdcdd98c Mon Sep 17 00:00:00 2001 From: cathery Date: Mon, 11 Nov 2019 22:42:24 +0300 Subject: [PATCH] Begin implementing Xbox One Adapter --- .../include/Controllers/XboxOneAdapter.h | 15 +++ .../Controllers/XboxOneAdapter/Firmware.h | 9 ++ .../source/Controllers/XboxOneAdapter.cpp | 93 ++++++++++++++----- .../Controllers/XboxOneAdapter/Firmware.cpp | 1 + MakefileSysmodule | 2 +- 5 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 ControllerUSB/include/Controllers/XboxOneAdapter/Firmware.h create mode 100644 ControllerUSB/source/Controllers/XboxOneAdapter/Firmware.cpp diff --git a/ControllerUSB/include/Controllers/XboxOneAdapter.h b/ControllerUSB/include/Controllers/XboxOneAdapter.h index fdd32cc..28f9bfe 100644 --- a/ControllerUSB/include/Controllers/XboxOneAdapter.h +++ b/ControllerUSB/include/Controllers/XboxOneAdapter.h @@ -7,11 +7,25 @@ //https://github.com/quantus/xbox-one-controller-protocol //https://cs.chromium.org/chromium/src/device/gamepad/xbox_controller_mac.mm +enum VendorRequest +{ + MT_VEND_DEV_MODE = 0x1, + MT_VEND_WRITE = 0x2, + MT_VEND_MULTI_WRITE = 0x6, + MT_VEND_MULTI_READ = 0x7, + MT_VEND_READ_EEPROM = 0x9, + MT_VEND_WRITE_FCE = 0x42, + MT_VEND_WRITE_CFG = 0x46, + MT_VEND_READ_CFG = 0x47, +}; + class XboxOneAdapter : public IController { private: + IUSBEndpoint *m_inPipePacket = nullptr; IUSBEndpoint *m_inPipe = nullptr; IUSBEndpoint *m_outPipe = nullptr; + IUSBInterface *m_interface = nullptr; public: XboxOneAdapter(std::unique_ptr &&interface); @@ -26,4 +40,5 @@ public: virtual ControllerType GetType() { return CONTROLLER_XBOXONEW; } Status SendInitBytes(); + Status ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request = MT_VEND_MULTI_WRITE); }; \ No newline at end of file diff --git a/ControllerUSB/include/Controllers/XboxOneAdapter/Firmware.h b/ControllerUSB/include/Controllers/XboxOneAdapter/Firmware.h new file mode 100644 index 0000000..047c8fe --- /dev/null +++ b/ControllerUSB/include/Controllers/XboxOneAdapter/Firmware.h @@ -0,0 +1,9 @@ +#pragma once +#include + +#define MT_FW_RESOURCE "Firmware.bin" +#define MT_MCU_ILM_OFFSET 0x80000 +#define MT_MCU_DLM_OFFSET 0x100000 + 0x10800 +#define MT_FW_CHUNK_SIZE 0x3800 +#define MT_DMA_COMPLETE 0xc0000000 +#define MT_FW_LOAD_IVB 0x12 diff --git a/ControllerUSB/source/Controllers/XboxOneAdapter.cpp b/ControllerUSB/source/Controllers/XboxOneAdapter.cpp index 1be0270..5b4c155 100644 --- a/ControllerUSB/source/Controllers/XboxOneAdapter.cpp +++ b/ControllerUSB/source/Controllers/XboxOneAdapter.cpp @@ -1,4 +1,5 @@ #include "Controllers/XboxOneAdapter.h" +#include "Controllers/XboxOneAdapter/Firmware.h" #include #include "../../source/log.h" @@ -44,55 +45,60 @@ Status XboxOneAdapter::OpenInterfaces() if (S_FAILED(rc)) return rc; - /* - - if (interface->GetDescriptor()->bInterfaceProtocol != 208) + if (interface->GetDescriptor()->bInterfaceProtocol != 255) continue; if (interface->GetDescriptor()->bNumEndpoints < 2) continue; - */ + + m_interface = interface.get(); + + if (!m_inPipePacket) + { + IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 3); + if (inEndpoint) + { + rc = inEndpoint->Open(); + if (S_FAILED(rc)) + return 3333; + + m_inPipePacket = inEndpoint; + } + } if (!m_inPipe) { - for (uint8_t i = 0; i != 15; ++i) + IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 4); + if (inEndpoint) { - IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, i); - if (inEndpoint) - { - rc = inEndpoint->Open(); - if (S_FAILED(rc)) - return 5555; + rc = inEndpoint->Open(); + if (S_FAILED(rc)) + return 4444; - m_inPipe = inEndpoint; - break; - } + m_inPipe = inEndpoint; } } if (!m_outPipe) { - for (uint8_t i = 0; i != 15; ++i) + IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, 3); + if (outEndpoint) { - IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, i); - if (outEndpoint) - { - rc = outEndpoint->Open(); - if (S_FAILED(rc)) - return 6666; + rc = outEndpoint->Open(); + if (S_FAILED(rc)) + return 5555; - m_outPipe = outEndpoint; - break; - } + m_outPipe = outEndpoint; } } } - if (!m_inPipe || !m_outPipe) + if (!m_inPipe || !m_outPipe || !m_inPipePacket) return 69; return rc; } + void XboxOneAdapter::CloseInterfaces() { //m_device->Reset(); @@ -101,5 +107,42 @@ void XboxOneAdapter::CloseInterfaces() Status XboxOneAdapter::SendInitBytes() { + Status rc; + rc = ControlWrite(m_interface, 0x9018, 0, MT_VEND_WRITE_CFG); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x0800, 0x01); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x09a0, 0x400230); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x09a4, 0x01); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x09a8, 0x01); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x09c4, 0x44); + if (S_FAILED(rc)) + return rc; + rc = ControlWrite(m_interface, 0x0a6c, 0x03); + if (S_FAILED(rc)) + return rc; + return 0; +} + +Status XboxOneAdapter::ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request) +{ + Status rc; + if (request == MT_VEND_DEV_MODE) + { + rc = interface->ControlTransfer(0x42, request, address, 0, 0, nullptr); + } + else + { + rc = interface->ControlTransfer(0x42, request, address, 0, sizeof(uint32_t), &value); + } + return rc; } \ No newline at end of file diff --git a/ControllerUSB/source/Controllers/XboxOneAdapter/Firmware.cpp b/ControllerUSB/source/Controllers/XboxOneAdapter/Firmware.cpp new file mode 100644 index 0000000..088a77a --- /dev/null +++ b/ControllerUSB/source/Controllers/XboxOneAdapter/Firmware.cpp @@ -0,0 +1 @@ +#include "Controllers/XboxOneAdapter/Firmware.h" diff --git a/MakefileSysmodule b/MakefileSysmodule index 9665842..afb2e56 100644 --- a/MakefileSysmodule +++ b/MakefileSysmodule @@ -39,7 +39,7 @@ include $(DEVKITPRO)/libnx/switch_rules #--------------------------------------------------------------------------------- TARGET := sys-con BUILD := buildSysmodule -SOURCES := source SwitchUSB/source ControllerUSB/source ControllerUSB/source/Controllers inih +SOURCES := source SwitchUSB/source ControllerUSB/source ControllerUSB/source/Controllers ControllerUSB/source/Controllers/XboxOneAdapter inih DATA := data INCLUDES := include SwitchUSB/include ControllerUSB/include inih #ROMFS := romfs