Experimental chatpad code
This commit is contained in:
parent
0243d0d37f
commit
79df37fc95
3 changed files with 265 additions and 7 deletions
|
@ -1,10 +1,13 @@
|
|||
env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb", "boost_thread"])
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb", "boost_thread"])
|
||||
env.Program("chatpad", ["chatpad.cpp"])
|
||||
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"])
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
|
||||
env.Program("chatpad2", ["chatpad2.cpp"])
|
||||
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"])
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
|
||||
env.Program("chatpad3", ["chatpad3.cpp"])
|
||||
|
||||
env = Environment(CXXFLAGS=["-Werror", "-Wall", "-g", "-O0"], LIBS=["usb-1.0", "boost_thread"])
|
||||
env.Program("reset", ["reset.cpp"])
|
||||
|
||||
# EOF #
|
||||
|
|
|
@ -15,12 +15,15 @@ private:
|
|||
uint8_t old_buttons;
|
||||
uint8_t old_dpad;
|
||||
|
||||
bool m_running;
|
||||
|
||||
public:
|
||||
Main() :
|
||||
m_ctx(0),
|
||||
m_handle(0),
|
||||
old_buttons(0),
|
||||
old_dpad(0)
|
||||
old_dpad(0),
|
||||
m_running(false)
|
||||
{}
|
||||
|
||||
~Main()
|
||||
|
@ -42,6 +45,8 @@ public:
|
|||
{
|
||||
m_handle = libusb_open_device_with_vid_pid(m_ctx, 0x045e, 0x028e);
|
||||
|
||||
set_configuration();
|
||||
|
||||
std::cout << "handle: " << m_handle << std::endl;
|
||||
if (!m_handle)
|
||||
{
|
||||
|
@ -53,6 +58,39 @@ public:
|
|||
|
||||
err = libusb_claim_interface(m_handle, 0);
|
||||
std::cout << "Claim: " << err << std::endl;
|
||||
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void set_configuration()
|
||||
{
|
||||
old_buttons = 0;
|
||||
old_dpad = 0;
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
libusb_release_interface(m_handle, 0);
|
||||
libusb_release_interface(m_handle, 2);
|
||||
}
|
||||
|
||||
int ret = libusb_set_configuration(m_handle, 1);
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
case 0:
|
||||
std::cout << "set_configuration(): success" << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << "set_configuration(): " << ret << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
libusb_claim_interface(m_handle, 0);
|
||||
libusb_claim_interface(m_handle, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void reset()
|
||||
|
@ -60,9 +98,13 @@ public:
|
|||
std::cout << "reset()" << std::endl;
|
||||
libusb_reset_device(m_handle);
|
||||
libusb_close(m_handle);
|
||||
libusb_exit(m_ctx);
|
||||
m_handle = 0;
|
||||
sleep(1);
|
||||
init_device_handle();
|
||||
m_ctx = 0;
|
||||
old_buttons = 0;
|
||||
old_dpad = 0;
|
||||
|
||||
execl("./chatpad2", "./chatpad2", NULL);
|
||||
}
|
||||
|
||||
void ctrl_msg(uint8_t value)
|
||||
|
@ -153,6 +195,9 @@ public:
|
|||
{
|
||||
callback(data.get());
|
||||
}
|
||||
|
||||
// if (endpoint == 6)
|
||||
// std::cout << "Clear Halt: " << libusb_clear_halt(m_handle, endpoint) << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -172,6 +217,10 @@ public:
|
|||
std::cout << "read_thread: no device" << std::endl;
|
||||
break;
|
||||
|
||||
case LIBUSB_ERROR_OTHER: // happens on reset
|
||||
std::cout << "read_thread: other error" << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << "read_thread: unknown: " << ret << std::endl;
|
||||
break;
|
||||
|
@ -194,21 +243,26 @@ public:
|
|||
switch(dpad)
|
||||
{
|
||||
case 0x04: // left
|
||||
ctrl_msg(0x08);
|
||||
break;
|
||||
|
||||
case 0x08: // right
|
||||
ctrl_msg(0x09);
|
||||
break;
|
||||
|
||||
case 0x01: // up
|
||||
ctrl_msg(0x0a);
|
||||
break;
|
||||
|
||||
case 0x02: // down
|
||||
ctrl_msg(0x0b);
|
||||
break;
|
||||
|
||||
case 0x20: // back
|
||||
break;
|
||||
|
||||
case 0x10: // start
|
||||
set_configuration();
|
||||
break;
|
||||
|
||||
case 0x40: // left stick
|
||||
|
@ -245,7 +299,7 @@ public:
|
|||
break;
|
||||
|
||||
case 0x04: // guide
|
||||
ctrl_msg(0x17);
|
||||
reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
201
chatpad/chatpad3.cpp
Normal file
201
chatpad/chatpad3.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
#include <boost/thread.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
|
||||
class Main
|
||||
{
|
||||
private:
|
||||
libusb_context* m_ctx;
|
||||
libusb_device_handle* m_handle;
|
||||
|
||||
public:
|
||||
Main() :
|
||||
m_ctx(0),
|
||||
m_handle(0)
|
||||
{}
|
||||
|
||||
~Main()
|
||||
{
|
||||
}
|
||||
|
||||
void init_libusb()
|
||||
{
|
||||
if (libusb_init(&m_ctx) != 0)
|
||||
{
|
||||
throw std::runtime_error("Libusb went wrong");
|
||||
}
|
||||
|
||||
std::cout << "Debug to max" << std::endl;
|
||||
libusb_set_debug(m_ctx, 3);
|
||||
}
|
||||
|
||||
void init_device_handle()
|
||||
{
|
||||
m_handle = libusb_open_device_with_vid_pid(m_ctx, 0x045e, 0x028e);
|
||||
|
||||
std::cout << "handle: " << m_handle << std::endl;
|
||||
if (!m_handle)
|
||||
{
|
||||
throw std::runtime_error("Couldn't find controller");
|
||||
}
|
||||
|
||||
int err = libusb_claim_interface(m_handle, 2);
|
||||
std::cout << "Claim: " << err << std::endl;
|
||||
|
||||
err = libusb_claim_interface(m_handle, 0);
|
||||
std::cout << "Claim: " << err << std::endl;
|
||||
}
|
||||
|
||||
void ctrl_msg(uint8_t value)
|
||||
{
|
||||
int ret = libusb_control_transfer(m_handle,
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE,
|
||||
LIBUSB_REQUEST_GET_STATUS,
|
||||
value, 0x02, NULL, 0, 0);
|
||||
std::cout << "ctrl_msg: " << ret << boost::format(" %02x") % int(value) << std::endl;
|
||||
}
|
||||
|
||||
static void callback_wrap(libusb_transfer* transfer)
|
||||
{
|
||||
static_cast<Main*>(transfer->user_data)->callback(transfer);
|
||||
}
|
||||
|
||||
void callback(libusb_transfer* transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
|
||||
std::cout << "data transfer not completed: " << transfer->status << std::endl;
|
||||
}
|
||||
|
||||
unsigned char* data = transfer->buffer;
|
||||
std::cout << "callback(" << transfer->actual_length << "): ";
|
||||
for(int i = 0; i < transfer->actual_length; ++i)
|
||||
{
|
||||
std::cout << boost::format("0x%02x ") % int(data[i]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// done with the transfer, so clean it up
|
||||
// libusb_free_transfer(transfer);
|
||||
|
||||
// request more data
|
||||
request_controller_data(LIBUSB_ENDPOINT_ADDRESS_MASK & transfer->endpoint);
|
||||
}
|
||||
|
||||
static void control_callback_wrap(libusb_transfer* transfer)
|
||||
{
|
||||
static_cast<Main*>(transfer->user_data)->control_callback(transfer);
|
||||
}
|
||||
|
||||
void control_callback(libusb_transfer* transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void request_controller_data(int endpoint)
|
||||
{
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
if (!transfer)
|
||||
{
|
||||
std::cout << "Couldn't alloc transfer" << std::endl;
|
||||
}
|
||||
|
||||
unsigned char* buffer = static_cast<unsigned char*>(malloc(8+32));
|
||||
|
||||
libusb_fill_interrupt_transfer(transfer,
|
||||
m_handle,
|
||||
endpoint | LIBUSB_ENDPOINT_IN,
|
||||
buffer, // buffer
|
||||
8+32, // length,
|
||||
&Main::callback_wrap,
|
||||
this, // userdata
|
||||
0 // timeout
|
||||
);
|
||||
|
||||
transfer->flags =
|
||||
LIBUSB_TRANSFER_FREE_BUFFER |
|
||||
LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
|
||||
int ret = libusb_submit_transfer(transfer);
|
||||
if (ret != 0)
|
||||
{
|
||||
std::cout << "Error with libusb_submit_transfer: " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void request_control(unsigned char value)
|
||||
{
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
if (!transfer)
|
||||
{
|
||||
std::cout << "Couldn't alloc transfer" << std::endl;
|
||||
}
|
||||
|
||||
unsigned char* buffer = static_cast<unsigned char*>(malloc(LIBUSB_CONTROL_SETUP_SIZE));
|
||||
libusb_fill_control_transfer(transfer, m_handle, buffer,
|
||||
&Main::control_callback_wrap,
|
||||
this,
|
||||
0);
|
||||
|
||||
libusb_fill_control_setup(buffer,
|
||||
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE,
|
||||
LIBUSB_REQUEST_GET_STATUS,
|
||||
value,
|
||||
2,
|
||||
0);
|
||||
|
||||
transfer->flags =
|
||||
LIBUSB_TRANSFER_FREE_BUFFER |
|
||||
LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
|
||||
int ret = libusb_submit_transfer(transfer);
|
||||
if (ret != 0)
|
||||
{
|
||||
std::cout << "Error with libusb_submit_transfer: " << ret << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void main_loop()
|
||||
{
|
||||
request_controller_data(1);
|
||||
request_controller_data(6);
|
||||
request_control(0x1f);
|
||||
request_control(0x1b);
|
||||
while(true)
|
||||
{
|
||||
std::cout << "Handle events: " << libusb_handle_events(m_ctx) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
init_libusb();
|
||||
init_device_handle();
|
||||
|
||||
main_loop();
|
||||
|
||||
libusb_close(m_handle);
|
||||
libusb_exit(m_ctx);
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
Main app;
|
||||
app.run();
|
||||
}
|
||||
catch(const std::exception& err)
|
||||
{
|
||||
std::cout << "Error: " << err.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Reference in a new issue