mirror of
https://github.com/cathery/sys-con.git
synced 2024-10-06 06:19:43 +00:00
More work on Xbox one adapter
This commit is contained in:
parent
4b59d5541e
commit
b3c995fe66
@ -39,6 +39,10 @@ public:
|
|||||||
|
|
||||||
virtual ControllerType GetType() { return CONTROLLER_XBOXONEW; }
|
virtual ControllerType GetType() { return CONTROLLER_XBOXONEW; }
|
||||||
|
|
||||||
|
Status LoadFirmwarePart(uint32_t offset, uint8_t *start, uint8_t *end);
|
||||||
Status SendInitBytes();
|
Status SendInitBytes();
|
||||||
Status ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request = MT_VEND_MULTI_WRITE);
|
Status ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request = MT_VEND_MULTI_WRITE);
|
||||||
|
|
||||||
|
static void LoadConfig(const ControllerConfig *config, const char *path);
|
||||||
|
virtual ControllerConfig *GetConfig();
|
||||||
};
|
};
|
@ -7,3 +7,45 @@
|
|||||||
#define MT_FW_CHUNK_SIZE 0x3800
|
#define MT_FW_CHUNK_SIZE 0x3800
|
||||||
#define MT_DMA_COMPLETE 0xc0000000
|
#define MT_DMA_COMPLETE 0xc0000000
|
||||||
#define MT_FW_LOAD_IVB 0x12
|
#define MT_FW_LOAD_IVB 0x12
|
||||||
|
|
||||||
|
#define MT_FCE_DMA_ADDR 0x0230
|
||||||
|
#define MT_FCE_DMA_LEN 0x0234
|
||||||
|
#define MT_USB_DMA_CFG 0x0238
|
||||||
|
|
||||||
|
#define MT_USB_U3DMA_CFG 0x9018
|
||||||
|
#define MT_FCE_PSE_CTRL 0x0800
|
||||||
|
#define MT_TX_CPU_FROM_FCE_BASE_PTR 0x09a0
|
||||||
|
#define MT_TX_CPU_FROM_FCE_MAX_COUNT 0x09a4
|
||||||
|
#define MT_TX_CPU_FROM_FCE_CPU_DESC_IDX 0x09a8
|
||||||
|
#define MT_FCE_PDMA_GLOBAL_CONF 0x09c4
|
||||||
|
#define MT_FCE_SKIP_FS 0x0a6c
|
||||||
|
|
||||||
|
struct FwHeader
|
||||||
|
{
|
||||||
|
uint32_t ilmLength;
|
||||||
|
uint32_t dlmLength;
|
||||||
|
uint16_t buildVersion;
|
||||||
|
uint16_t firmwareVersion;
|
||||||
|
uint32_t padding;
|
||||||
|
char buildTime[16];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
union DmaConfig {
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t rxBulkAggTimeout : 8;
|
||||||
|
uint32_t rxBulkAggLimit : 8;
|
||||||
|
uint32_t udmaTxWlDrop : 1;
|
||||||
|
uint32_t wakeupEnabled : 1;
|
||||||
|
uint32_t rxDropOrPad : 1;
|
||||||
|
uint32_t txClear : 1;
|
||||||
|
uint32_t txopHalt : 1;
|
||||||
|
uint32_t rxBulkAggEnabled : 1;
|
||||||
|
uint32_t rxBulkEnabled : 1;
|
||||||
|
uint32_t txBulkEnabled : 1;
|
||||||
|
uint32_t epOutValid : 6;
|
||||||
|
uint32_t rxBusy : 1;
|
||||||
|
uint32_t txBusy : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint32_t value;
|
||||||
|
};
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
#include "Controllers/XboxOneAdapter/Firmware.h"
|
#include "Controllers/XboxOneAdapter/Firmware.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "../../source/log.h"
|
#include "../../source/log.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include "cstring"
|
||||||
|
|
||||||
|
static ControllerConfig _xboxoneadapterConfig{};
|
||||||
|
static char firmwarePath[100];
|
||||||
|
|
||||||
XboxOneAdapter::XboxOneAdapter(std::unique_ptr<IUSBDevice> &&interface)
|
XboxOneAdapter::XboxOneAdapter(std::unique_ptr<IUSBDevice> &&interface)
|
||||||
: IController(std::move(interface))
|
: IController(std::move(interface))
|
||||||
@ -108,41 +113,115 @@ void XboxOneAdapter::CloseInterfaces()
|
|||||||
Status XboxOneAdapter::SendInitBytes()
|
Status XboxOneAdapter::SendInitBytes()
|
||||||
{
|
{
|
||||||
Status rc;
|
Status rc;
|
||||||
rc = ControlWrite(m_interface, 0x9018, 0, MT_VEND_WRITE_CFG);
|
DmaConfig config = {};
|
||||||
if (S_FAILED(rc))
|
|
||||||
return rc;
|
config.rxBulkEnabled = 1;
|
||||||
rc = ControlWrite(m_interface, 0x0800, 0x01);
|
config.txBulkEnabled = 1;
|
||||||
if (S_FAILED(rc))
|
|
||||||
return rc;
|
ControlWrite(m_interface, MT_USB_U3DMA_CFG, config.value, MT_VEND_WRITE_CFG);
|
||||||
rc = ControlWrite(m_interface, 0x09a0, 0x400230);
|
ControlWrite(m_interface, MT_FCE_PSE_CTRL, 0x01);
|
||||||
if (S_FAILED(rc))
|
ControlWrite(m_interface, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
|
||||||
return rc;
|
ControlWrite(m_interface, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x01);
|
||||||
rc = ControlWrite(m_interface, 0x09a4, 0x01);
|
ControlWrite(m_interface, MT_TX_CPU_FROM_FCE_CPU_DESC_IDX, 0x01);
|
||||||
if (S_FAILED(rc))
|
ControlWrite(m_interface, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
|
||||||
return rc;
|
ControlWrite(m_interface, MT_FCE_SKIP_FS, 0x03);
|
||||||
rc = ControlWrite(m_interface, 0x09a8, 0x01);
|
|
||||||
if (S_FAILED(rc))
|
WriteToLog("firmware path: ", firmwarePath);
|
||||||
return rc;
|
if (!firmwarePath || *firmwarePath == '\0')
|
||||||
rc = ControlWrite(m_interface, 0x09c4, 0x44);
|
{
|
||||||
if (S_FAILED(rc))
|
WriteToLog("But the string is empty!");
|
||||||
return rc;
|
return 256;
|
||||||
rc = ControlWrite(m_interface, 0x0a6c, 0x03);
|
}
|
||||||
|
|
||||||
|
std::ifstream fs(firmwarePath, std::ios::binary);
|
||||||
|
if (fs.fail())
|
||||||
|
return 235;
|
||||||
|
|
||||||
|
WriteToLog("Opening file...");
|
||||||
|
|
||||||
|
std::vector<uint8_t> firmware(std::istreambuf_iterator<char>(fs), {});
|
||||||
|
|
||||||
|
WriteToLog("File opened!");
|
||||||
|
|
||||||
|
fs.close();
|
||||||
|
|
||||||
|
WriteToLog("writing ", firmware.size(), " bytes...");
|
||||||
|
|
||||||
|
FwHeader *header = reinterpret_cast<FwHeader *>(firmware.data());
|
||||||
|
|
||||||
|
uint8_t *ilmStart = reinterpret_cast<uint8_t *>(header) + sizeof(FwHeader);
|
||||||
|
uint8_t *dlmStart = ilmStart + header->ilmLength;
|
||||||
|
uint8_t *dlmEnd = dlmStart + header->dlmLength;
|
||||||
|
|
||||||
|
WriteToLog("Writing 1st part");
|
||||||
|
|
||||||
|
rc = LoadFirmwarePart(MT_MCU_ILM_OFFSET, ilmStart, dlmStart);
|
||||||
if (S_FAILED(rc))
|
if (S_FAILED(rc))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
WriteToLog("Writing 2nd part");
|
||||||
|
rc = LoadFirmwarePart(MT_MCU_DLM_OFFSET, dlmStart, dlmEnd);
|
||||||
|
if (S_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
WriteToLog("Wrote");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status XboxOneAdapter::LoadFirmwarePart(uint32_t offset, uint8_t *start, uint8_t *end)
|
||||||
|
{
|
||||||
|
// Send firmware in chunks
|
||||||
|
Status rc = -1;
|
||||||
|
for (uint8_t *chunk = start; chunk < end; chunk += MT_FW_CHUNK_SIZE)
|
||||||
|
{
|
||||||
|
uint32_t address = (uint32_t)(offset + chunk - start);
|
||||||
|
uint32_t remaining = (uint32_t)(end - chunk);
|
||||||
|
uint16_t length = remaining > MT_FW_CHUNK_SIZE ? MT_FW_CHUNK_SIZE : remaining;
|
||||||
|
|
||||||
|
rc = ControlWrite(m_interface, MT_FCE_DMA_ADDR, address, MT_VEND_WRITE_CFG);
|
||||||
|
if (S_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = ControlWrite(m_interface, MT_FCE_DMA_LEN, length << 16, MT_VEND_WRITE_CFG);
|
||||||
|
if (S_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
uint8_t data[length + 8]{0x00, 0x38, 0x00, 0x10};
|
||||||
|
|
||||||
|
for (int i = 0; i != length; ++i)
|
||||||
|
{
|
||||||
|
data[i + 4] = chunk[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = m_outPipe->Write(data, sizeof(data));
|
||||||
|
if (S_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
Status XboxOneAdapter::ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request)
|
Status XboxOneAdapter::ControlWrite(IUSBInterface *interface, uint16_t address, uint32_t value, VendorRequest request)
|
||||||
{
|
{
|
||||||
Status rc;
|
Status rc;
|
||||||
if (request == MT_VEND_DEV_MODE)
|
if (request == MT_VEND_DEV_MODE)
|
||||||
{
|
{
|
||||||
rc = interface->ControlTransfer(0x42, request, address, 0, 0, nullptr);
|
rc = interface->ControlTransfer(0x40, request, address, 0, 0, nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = interface->ControlTransfer(0x42, request, address, 0, sizeof(uint32_t), &value);
|
rc = interface->ControlTransfer(0x40, request, address, 0, sizeof(uint32_t), &value);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XboxOneAdapter::LoadConfig(const ControllerConfig *config, const char *path)
|
||||||
|
{
|
||||||
|
_xboxoneadapterConfig = *config;
|
||||||
|
strcpy(firmwarePath, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerConfig *XboxOneAdapter::GetConfig()
|
||||||
|
{
|
||||||
|
return &_xboxoneadapterConfig;
|
||||||
|
}
|
1
config/sys-con/config_xboxoneadapter.ini
Normal file
1
config/sys-con/config_xboxoneadapter.ini
Normal file
@ -0,0 +1 @@
|
|||||||
|
firmware_path = /config/sys-con/firmware/XboxOneAdapter.bin
|
BIN
config/sys-con/firmware/XboxOneAdapter.bin
Normal file
BIN
config/sys-con/firmware/XboxOneAdapter.bin
Normal file
Binary file not shown.
@ -14,6 +14,7 @@
|
|||||||
#define XBOXCONFIG "config_xboxorig.ini"
|
#define XBOXCONFIG "config_xboxorig.ini"
|
||||||
#define XBOX360CONFIG "config_xbox360.ini"
|
#define XBOX360CONFIG "config_xbox360.ini"
|
||||||
#define XBOXONECONFIG "config_xboxone.ini"
|
#define XBOXONECONFIG "config_xboxone.ini"
|
||||||
|
#define XBOXONEADAPTERCONFIG "config_xboxoneadapter.ini"
|
||||||
#define DUALSHOCK3CONFIG "config_dualshock3.ini"
|
#define DUALSHOCK3CONFIG "config_dualshock3.ini"
|
||||||
#define DUALSHOCK4CONFIG "config_dualshock4.ini"
|
#define DUALSHOCK4CONFIG "config_dualshock4.ini"
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ static ControllerButton _StringToKey(const char *text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ControllerConfig temp_config;
|
static ControllerConfig temp_config;
|
||||||
|
static char firmwarePath[100];
|
||||||
|
|
||||||
static int _ParseConfigLine(void *dummy, const char *section, const char *name, const char *value)
|
static int _ParseConfigLine(void *dummy, const char *section, const char *name, const char *value)
|
||||||
{
|
{
|
||||||
@ -92,6 +94,11 @@ static int _ParseConfigLine(void *dummy, const char *section, const char *name,
|
|||||||
temp_config.swapDPADandLSTICK = (strcmp(value, "true") ? false : true);
|
temp_config.swapDPADandLSTICK = (strcmp(value, "true") ? false : true);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(name, "firmware_path") == 0)
|
||||||
|
{
|
||||||
|
strcpy(firmwarePath, value);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -120,6 +127,11 @@ void LoadAllConfigs()
|
|||||||
else
|
else
|
||||||
WriteToLog("Failed to read from xbox one config!");
|
WriteToLog("Failed to read from xbox one config!");
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOXONEADAPTERCONFIG)))
|
||||||
|
XboxOneAdapter::LoadConfig(&temp_config, firmwarePath);
|
||||||
|
else
|
||||||
|
WriteToLog("Failed to read from xbox one adapter config!");
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOX360CONFIG)))
|
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOX360CONFIG)))
|
||||||
{
|
{
|
||||||
Xbox360Controller::LoadConfig(&temp_config);
|
Xbox360Controller::LoadConfig(&temp_config);
|
||||||
@ -147,6 +159,7 @@ bool CheckForFileChanges()
|
|||||||
static time_t xboxConfigLastModified;
|
static time_t xboxConfigLastModified;
|
||||||
static time_t xbox360ConfigLastModified;
|
static time_t xbox360ConfigLastModified;
|
||||||
static time_t xboxOneConfigLastModified;
|
static time_t xboxOneConfigLastModified;
|
||||||
|
static time_t xboxOneAdapterConfigLastModified;
|
||||||
static time_t dualshock3ConfigLastModified;
|
static time_t dualshock3ConfigLastModified;
|
||||||
static time_t dualshock4ConfigLastModified;
|
static time_t dualshock4ConfigLastModified;
|
||||||
struct stat result;
|
struct stat result;
|
||||||
@ -192,5 +205,11 @@ bool CheckForFileChanges()
|
|||||||
dualshock4ConfigLastModified = result.st_mtime;
|
dualshock4ConfigLastModified = result.st_mtime;
|
||||||
filesChanged = true;
|
filesChanged = true;
|
||||||
}
|
}
|
||||||
|
if (stat(CONFIG_PATH XBOXONEADAPTERCONFIG, &result) == 0)
|
||||||
|
if (xboxOneAdapterConfigLastModified != result.st_mtime)
|
||||||
|
{
|
||||||
|
xboxOneAdapterConfigLastModified = result.st_mtime;
|
||||||
|
filesChanged = true;
|
||||||
|
}
|
||||||
return filesChanged;
|
return filesChanged;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user