mirror of
https://github.com/cathery/sys-con.git
synced 2025-03-14 01:27:37 +00:00
USB memory optimizations + progress on #3
This commit is contained in:
parent
3baa0ad672
commit
f3d8991710
@ -24,6 +24,8 @@ public:
|
||||
virtual Status Open() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual Status ControlTransfer(uint8_t bmRequestType, uint8_t bmRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *buffer) = 0;
|
||||
|
||||
virtual IUSBEndpoint *GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index);
|
||||
virtual InterfaceDescriptor *GetDescriptor();
|
||||
|
||||
|
@ -19,9 +19,6 @@ Status Dualshock3Controller::Initialize()
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
rc = SendInitBytes();
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
void Dualshock3Controller::Exit()
|
||||
@ -36,52 +33,54 @@ Status Dualshock3Controller::OpenInterfaces()
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
//This will open each interface and try to acquire Xbox One controller's in and out endpoints, if it hasn't already
|
||||
//Open each interface, send it a setup packet and get the endpoints if it succeeds
|
||||
std::vector<std::unique_ptr<IUSBInterface>> &interfaces = m_device->GetInterfaces();
|
||||
for (auto &&interface : interfaces)
|
||||
{
|
||||
rc = interface->Open();
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
//TODO: check for numEndpoints before trying to open them!
|
||||
if (interface->GetDescriptor()->bNumEndpoints >= 2)
|
||||
{
|
||||
IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 1);
|
||||
if (inEndpoint->GetDescriptor()->bLength != 0)
|
||||
uint8_t initBytes[] = {0x42, 0x0C, 0x00, 0x00};
|
||||
rc = interface->ControlTransfer(0x21, 0x09, 0x03F4, 0, 0x04, initBytes);
|
||||
if (S_FAILED(rc))
|
||||
return 60;
|
||||
|
||||
IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 0);
|
||||
if (inEndpoint)
|
||||
{
|
||||
rc = inEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
return 5555;
|
||||
return 61;
|
||||
|
||||
m_inPipe = inEndpoint;
|
||||
}
|
||||
|
||||
IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, 1);
|
||||
if (outEndpoint->GetDescriptor()->bLength != 0)
|
||||
if (outEndpoint)
|
||||
{
|
||||
rc = outEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
return 6666;
|
||||
return 62;
|
||||
|
||||
m_outPipe = outEndpoint;
|
||||
}
|
||||
|
||||
if (!m_inPipe || !m_outPipe)
|
||||
return 69;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_inPipe || !m_outPipe)
|
||||
return 69;
|
||||
|
||||
return rc;
|
||||
}
|
||||
void Dualshock3Controller::CloseInterfaces()
|
||||
{
|
||||
m_device->Reset();
|
||||
//m_device->Reset();
|
||||
m_device->Close();
|
||||
}
|
||||
|
||||
Status Dualshock3Controller::GetInput()
|
||||
{
|
||||
return 9;
|
||||
/*
|
||||
uint8_t input_bytes[64];
|
||||
|
||||
@ -89,55 +88,11 @@ Status Dualshock3Controller::GetInput()
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
uint8_t type = input_bytes[0];
|
||||
m_buttonData = *reinterpret_cast<Dualshock3ButtonData *>(input_bytes);
|
||||
|
||||
if (type == XBONEINPUT_BUTTON) //Button data
|
||||
{
|
||||
m_buttonData = *reinterpret_cast<Dualshock3ButtonData *>(input_bytes);
|
||||
}
|
||||
else if (type == XBONEINPUT_GUIDEBUTTON) //Guide button status
|
||||
{
|
||||
m_buttonData.sync = input_bytes[4];
|
||||
|
||||
//Xbox one S needs to be sent an ack report for guide buttons
|
||||
//TODO: needs testing
|
||||
if (input_bytes[1] == 0x30)
|
||||
{
|
||||
rc = WriteAckGuideReport(input_bytes[2]);
|
||||
if (S_FAILED(rc))
|
||||
return rc;
|
||||
}
|
||||
//TODO: add ack check and send ack report!
|
||||
}
|
||||
|
||||
return rc;
|
||||
*/
|
||||
}
|
||||
|
||||
Status Dualshock3Controller::SendInitBytes()
|
||||
{
|
||||
/*
|
||||
UCHAR hidCommandEnable[DS3_HID_COMMAND_ENABLE_SIZE] =
|
||||
{
|
||||
0x42, 0x0C, 0x00, 0x00
|
||||
};
|
||||
|
||||
Context,
|
||||
BmRequestHostToDevice,
|
||||
BmRequestClass,
|
||||
SetReport,
|
||||
Ds3FeatureStartDevice,
|
||||
0,
|
||||
hidCommandEnable,
|
||||
DS3_HID_COMMAND_ENABLE_SIZE
|
||||
|
||||
*/
|
||||
uint8_t init_bytes[]{
|
||||
0x05,
|
||||
0x20, 0x00, 0x01, 0x00};
|
||||
|
||||
Status rc = m_outPipe->Write(init_bytes, sizeof(init_bytes));
|
||||
return rc;
|
||||
return 9;
|
||||
}
|
||||
|
||||
float Dualshock3Controller::NormalizeTrigger(uint16_t value)
|
||||
|
@ -46,7 +46,7 @@ Status Xbox360Controller::OpenInterfaces()
|
||||
if (!m_inPipe)
|
||||
{
|
||||
IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 0);
|
||||
if (inEndpoint->GetDescriptor()->bLength != 0)
|
||||
if (inEndpoint)
|
||||
{
|
||||
rc = inEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
@ -59,7 +59,7 @@ Status Xbox360Controller::OpenInterfaces()
|
||||
if (!m_outPipe)
|
||||
{
|
||||
IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, 0);
|
||||
if (outEndpoint->GetDescriptor()->bLength != 0)
|
||||
if (outEndpoint)
|
||||
{
|
||||
rc = outEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
@ -191,8 +191,8 @@ NormalizedButtonData Xbox360Controller::GetNormalizedButtonData()
|
||||
return normalData;
|
||||
}
|
||||
|
||||
Status Xbox360Controller::SetRumble(uint8_t strong_magnitude,uint8_t weak_magnitude)
|
||||
Status Xbox360Controller::SetRumble(uint8_t strong_magnitude, uint8_t weak_magnitude)
|
||||
{
|
||||
uint8_t rumbleData[]{0x00,sizeof(Xbox360RumbleData), 0x00, strong_magnitude, weak_magnitude, 0x00, 0x00, 0x00};
|
||||
uint8_t rumbleData[]{0x00, sizeof(Xbox360RumbleData), 0x00, strong_magnitude, weak_magnitude, 0x00, 0x00, 0x00};
|
||||
return m_outPipe->Write(rumbleData, sizeof(rumbleData));
|
||||
}
|
@ -47,7 +47,7 @@ Status XboxOneController::OpenInterfaces()
|
||||
if (interface->GetDescriptor()->bNumEndpoints >= 2)
|
||||
{
|
||||
IUSBEndpoint *inEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_IN, 1);
|
||||
if (inEndpoint->GetDescriptor()->bLength != 0)
|
||||
if (inEndpoint)
|
||||
{
|
||||
rc = inEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
@ -57,7 +57,7 @@ Status XboxOneController::OpenInterfaces()
|
||||
}
|
||||
|
||||
IUSBEndpoint *outEndpoint = interface->GetEndpoint(IUSBEndpoint::USB_ENDPOINT_OUT, 1);
|
||||
if (outEndpoint->GetDescriptor()->bLength != 0)
|
||||
if (outEndpoint)
|
||||
{
|
||||
rc = outEndpoint->Open();
|
||||
if (S_FAILED(rc))
|
||||
|
@ -10,6 +10,8 @@ private:
|
||||
UsbHsClientIfSession m_ifSession;
|
||||
usb_endpoint_descriptor m_descriptor;
|
||||
|
||||
void *m_buffer;
|
||||
|
||||
public:
|
||||
//Pass the necessary information to be able to open the endpoint
|
||||
SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpoint_descriptor &desc);
|
||||
|
@ -11,8 +11,10 @@ private:
|
||||
UsbHsClientIfSession m_session{};
|
||||
UsbHsInterface m_interface{};
|
||||
|
||||
std::vector<std::unique_ptr<IUSBEndpoint>> m_inEndpoints;
|
||||
std::vector<std::unique_ptr<IUSBEndpoint>> m_outEndpoints;
|
||||
std::array<std::unique_ptr<IUSBEndpoint>, 15> m_inEndpoints;
|
||||
std::array<std::unique_ptr<IUSBEndpoint>, 15> m_outEndpoints;
|
||||
|
||||
void *m_controlTransferBuffer;
|
||||
|
||||
public:
|
||||
//Pass the specified interface to allow for opening the session
|
||||
@ -23,6 +25,8 @@ public:
|
||||
virtual Result Open();
|
||||
virtual void Close();
|
||||
|
||||
virtual Result ControlTransfer(u8 bmRequestType, u8 bmRequest, u16 wValue, u16 wIndex, u16 wLength, void *buffer);
|
||||
|
||||
// There are a total of 15 endpoints on a switch interface for each direction, get them by passing the desired parameters
|
||||
virtual IUSBEndpoint *GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index);
|
||||
|
||||
|
@ -7,10 +7,12 @@ SwitchUSBEndpoint::SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpo
|
||||
: m_ifSession(if_session),
|
||||
m_descriptor(desc)
|
||||
{
|
||||
m_buffer = memalign(0x1000, 0x100);
|
||||
}
|
||||
|
||||
SwitchUSBEndpoint::~SwitchUSBEndpoint()
|
||||
{
|
||||
free(m_buffer);
|
||||
Close();
|
||||
}
|
||||
|
||||
@ -30,47 +32,38 @@ void SwitchUSBEndpoint::Close()
|
||||
Result SwitchUSBEndpoint::Write(void *inBuffer, size_t bufferSize)
|
||||
{
|
||||
Result rc = -1;
|
||||
void *tmpbuf = memalign(0x1000, bufferSize);
|
||||
if (tmpbuf != nullptr)
|
||||
if (m_buffer != nullptr)
|
||||
{
|
||||
u32 transferredSize = 0;
|
||||
memset(tmpbuf, 0, bufferSize);
|
||||
memset(m_buffer, 0, bufferSize);
|
||||
|
||||
for (size_t byte = 0; byte != bufferSize; ++byte)
|
||||
{
|
||||
static_cast<uint8_t *>(tmpbuf)[byte] = static_cast<uint8_t *>(inBuffer)[byte];
|
||||
static_cast<uint8_t *>(m_buffer)[byte] = static_cast<uint8_t *>(inBuffer)[byte];
|
||||
}
|
||||
|
||||
rc = usbHsEpPostBuffer(&m_epSession, tmpbuf, bufferSize, &transferredSize);
|
||||
if (rc == 0xcc8c)
|
||||
rc = 0;
|
||||
|
||||
free(tmpbuf);
|
||||
rc = usbHsEpPostBuffer(&m_epSession, m_buffer, bufferSize, &transferredSize);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result SwitchUSBEndpoint::Read(void *outBuffer, size_t bufferSize)
|
||||
{
|
||||
void *tmpbuf = memalign(0x1000, bufferSize);
|
||||
if (tmpbuf == nullptr)
|
||||
if (m_buffer == nullptr)
|
||||
return -1;
|
||||
|
||||
u32 transferredSize;
|
||||
Result rc = usbHsEpPostBuffer(&m_epSession, tmpbuf, bufferSize, &transferredSize);
|
||||
memset(m_buffer, 0, bufferSize);
|
||||
|
||||
if (rc == 0xcc8c)
|
||||
rc = 0;
|
||||
Result rc = usbHsEpPostBuffer(&m_epSession, m_buffer, bufferSize, &transferredSize);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
for (size_t byte = 0; byte != bufferSize; ++byte)
|
||||
for (u32 byte = 0; byte != transferredSize; ++byte)
|
||||
{
|
||||
static_cast<uint8_t *>(outBuffer)[byte] = static_cast<uint8_t *>(tmpbuf)[byte];
|
||||
static_cast<uint8_t *>(outBuffer)[byte] = static_cast<uint8_t *>(m_buffer)[byte];
|
||||
}
|
||||
}
|
||||
|
||||
free(tmpbuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
#include "SwitchUSBInterface.h"
|
||||
#include "SwitchUSBEndpoint.h"
|
||||
#include <malloc.h>
|
||||
#include <cstring>
|
||||
|
||||
SwitchUSBInterface::SwitchUSBInterface(UsbHsInterface &interface)
|
||||
: m_interface(interface)
|
||||
{
|
||||
m_controlTransferBuffer = memalign(0x1000, 0x100);
|
||||
}
|
||||
|
||||
SwitchUSBInterface::~SwitchUSBInterface()
|
||||
{
|
||||
free(m_controlTransferBuffer);
|
||||
Close();
|
||||
}
|
||||
|
||||
@ -23,22 +27,22 @@ Result SwitchUSBInterface::Open()
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
|
||||
m_inEndpoints.clear();
|
||||
m_outEndpoints.clear();
|
||||
|
||||
m_inEndpoints.reserve(15);
|
||||
m_outEndpoints.reserve(15);
|
||||
|
||||
//For some reason output_endpoint_descs contains IN endpoints and input_endpoint_descs contains OUT endpoints
|
||||
//we're adjusting appropriately
|
||||
for (int i = 0; i != 15; ++i)
|
||||
{
|
||||
m_inEndpoints.push_back(std::make_unique<SwitchUSBEndpoint>(m_session, m_session.inf.inf.input_endpoint_descs[i]));
|
||||
usb_endpoint_descriptor &epdesc = m_session.inf.inf.input_endpoint_descs[i];
|
||||
if (epdesc.bLength != 0)
|
||||
{
|
||||
m_inEndpoints[i] = std::make_unique<SwitchUSBEndpoint>(m_session, epdesc);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i != 15; ++i)
|
||||
{
|
||||
m_outEndpoints.push_back(std::make_unique<SwitchUSBEndpoint>(m_session, m_session.inf.inf.output_endpoint_descs[i]));
|
||||
usb_endpoint_descriptor &epdesc = m_session.inf.inf.output_endpoint_descs[i];
|
||||
if (epdesc.bLength != 0)
|
||||
{
|
||||
m_outEndpoints[i] = std::make_unique<SwitchUSBEndpoint>(m_session, epdesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
@ -47,18 +51,50 @@ void SwitchUSBInterface::Close()
|
||||
{
|
||||
for (auto &&endpoint : m_inEndpoints)
|
||||
{
|
||||
endpoint->Close();
|
||||
if (endpoint)
|
||||
{
|
||||
endpoint->Close();
|
||||
endpoint.release();
|
||||
}
|
||||
}
|
||||
for (auto &&endpoint : m_outEndpoints)
|
||||
{
|
||||
endpoint->Close();
|
||||
if (endpoint)
|
||||
{
|
||||
endpoint->Close();
|
||||
endpoint.release();
|
||||
}
|
||||
}
|
||||
usbHsIfClose(&m_session);
|
||||
}
|
||||
|
||||
Result SwitchUSBInterface::ControlTransfer(u8 bmRequestType, u8 bmRequest, u16 wValue, u16 wIndex, u16 wLength, void *buffer)
|
||||
{
|
||||
if (m_controlTransferBuffer == nullptr)
|
||||
return -1;
|
||||
|
||||
u32 transferredSize;
|
||||
|
||||
for (u16 byte = 0; byte != wLength; ++byte)
|
||||
{
|
||||
static_cast<uint8_t *>(m_controlTransferBuffer)[byte] = static_cast<uint8_t *>(buffer)[byte];
|
||||
}
|
||||
|
||||
Result rc = usbHsIfCtrlXfer(&m_session, bmRequestType, bmRequest, wValue, wIndex, wLength, m_controlTransferBuffer, &transferredSize);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
memset(buffer, 0, wLength);
|
||||
for (u32 byte = 0; byte != transferredSize; ++byte)
|
||||
{
|
||||
static_cast<uint8_t *>(buffer)[byte] = static_cast<uint8_t *>(m_controlTransferBuffer)[byte];
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
IUSBEndpoint *SwitchUSBInterface::GetEndpoint(IUSBEndpoint::Direction direction, uint8_t index)
|
||||
{
|
||||
//TODO: replace this with a control transfer to get endpoint descriptor
|
||||
if (direction == IUSBEndpoint::USB_ENDPOINT_IN)
|
||||
return m_inEndpoints[index].get();
|
||||
else
|
||||
|
@ -15,7 +15,7 @@ struct VendorEvent
|
||||
|
||||
Result mainLoop()
|
||||
{
|
||||
Result rc;
|
||||
Result rc = 0;
|
||||
UsbHsInterface interfaces[16];
|
||||
s32 total_entries;
|
||||
std::vector<uint16_t> vendors = GetVendors();
|
||||
@ -120,7 +120,8 @@ Result mainLoop()
|
||||
}
|
||||
|
||||
UsbHsInterfaceFilter tempFilter;
|
||||
tempFilter.Flags = UsbHsInterfaceFilterFlags_idProduct;
|
||||
tempFilter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
|
||||
tempFilter.idVendor = event.vendor;
|
||||
tempFilter.idProduct = product;
|
||||
rc = usbHsQueryAvailableInterfaces(&tempFilter, interfaces, sizeof(interfaces), &total_entries);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user