diff --git a/chatpad/SConstruct b/chatpad/SConstruct new file mode 100644 index 0000000..d293270 --- /dev/null +++ b/chatpad/SConstruct @@ -0,0 +1,11 @@ +env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb", "boost_thread"]) +env.Program("chatpad", ["chatpad.cpp"]) + +env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"]) +env.Program("chatpad2", ["chatpad2.cpp"]) + +env = Environment(CXXFLAGS=["-Werror", "-Wall"], LIBS=["usb-1.0", "boost_thread"]) +env.Program("reset", ["reset.cpp"]) + +# EOF # + diff --git a/chatpad/chatpad.cpp b/chatpad/chatpad.cpp new file mode 100644 index 0000000..5a08319 --- /dev/null +++ b/chatpad/chatpad.cpp @@ -0,0 +1,114 @@ +#include <boost/thread.hpp> +#include <boost/format.hpp> +#include <usb.h> +#include <iostream> +#include <stdexcept> + +struct usb_device* find_controller() +{ + struct usb_bus* busses = usb_get_busses(); + + for (struct usb_bus* bus = busses; bus; bus = bus->next) + { + for (struct usb_device* dev = bus->devices; dev; dev = dev->next) + { + if (dev->descriptor.idVendor == 0x045e && + dev->descriptor.idProduct == 0x028e) + { + return dev; + } + } + } + return 0; +} + +void read_thread(struct usb_dev_handle* handle) +{ + uint8_t data[5]; + while(true) + { + std::cout << "reading" << std::endl; + int len = usb_interrupt_read(handle, 6, reinterpret_cast<char*>(data), sizeof(data), 0); + if (len < 0) + { + std::cout << "Error in read_thread" << std::endl; + return; + } + else + { + std::cout << "read: " << len << "/32: data: " << std::flush; + for(int i = 0; i < len; ++i) + { + std::cout << boost::format("0x%02x ") % int(data[i]); + } + std::cout << std::endl; + } + } +} + +int main() +{ + try + { + usb_init(); + usb_find_busses(); + usb_find_devices(); + + struct usb_device* dev = find_controller(); + + if (!dev) + { + throw std::runtime_error("Couldn't find controller"); + } + else + { + std::cout << "Controller found, ready to go" << std::endl; + + struct usb_dev_handle* handle = usb_open(dev); + if (!handle) + { + throw std::runtime_error("Failed to open controller"); + } + + int err = usb_claim_interface(handle, 2); + std::cout << "Claim: " << err << std::endl; + + boost::thread thread(boost::bind(&read_thread, handle)); + + while(true) + { + usb_control_msg(handle, 0x41, 0x0, 0x1f, 0x02, 0, NULL, 0); + std::cout << "0x1f" << std::endl; + sleep(1); + + usb_control_msg(handle, 0x41, 0x0, 0x1e, 0x02, 0, NULL, 0); + std::cout << "0x1e" << std::endl; + sleep(1); + + //usb_control_msg(handle, 0x41, 0x0, 0x15, 0x02, 0, NULL, 0); + //std::cout << "led and long sleep" << std::endl; + usb_control_msg(handle, 0x41, 0x0, 0x1b, 0x02, 0, NULL, 0); + sleep(1); + + + usb_control_msg(handle, 0x41, 0x0, 0x1b, 0x02, 0, NULL, 0); + sleep(1); + + usb_control_msg(handle, 0x41, 0x0, 0x1b, 0x02, 0, NULL, 0); + sleep(1); + + //std::usb_reset(usb_dev_handle *dev); + } + + usb_close(handle); + } + } + catch(const std::exception& err) + { + std::cout << "Error: " << err.what() << std::endl; + } + + return 0; +} + +/* EOF */ diff --git a/chatpad/chatpad2.cpp b/chatpad/chatpad2.cpp new file mode 100644 index 0000000..44a3ad9 --- /dev/null +++ b/chatpad/chatpad2.cpp @@ -0,0 +1,286 @@ +#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> + +class Main +{ +private: + libusb_context* m_ctx; + libusb_device_handle* m_handle; + + uint8_t old_buttons; + uint8_t old_dpad; + +public: + Main() : + m_ctx(0), + m_handle(0), + old_buttons(0), + old_dpad(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 reset() + { + std::cout << "reset()" << std::endl; + libusb_reset_device(m_handle); + libusb_close(m_handle); + m_handle = 0; + sleep(1); + init_device_handle(); + } + + 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; + } + + void main_loop() + { + if (0) + { + ctrl_msg(0x1f); + sleep(1); + + ctrl_msg(0x1e); + sleep(1); + + ctrl_msg(0x1b); + sleep(1); + + ctrl_msg(0x1b); + sleep(1); + + ctrl_msg(0x1f); + sleep(1); + + ctrl_msg(0x18); + sleep(1); + + ctrl_msg(0x10); + sleep(1); + + ctrl_msg(0x03); + sleep(1); + } + + while(true) + { + sleep(1); + } + } + + void read_thread(const std::string& prefix, int endpoint, boost::function<void (uint8_t*)> callback) + { + boost::scoped_array<uint8_t> data; + + int data_len = 32; + if (endpoint == 6) + { + data.reset(new uint8_t[32]); + } + else + { + data.reset(new uint8_t[32]); + } + + while(true) + { + //std::cout << "reading" << std::endl; + int transfered = -1; + + //int ret = libusb_interrupt_transfer(m_handle, 6 | LIBUSB_ENDPOINT_IN, + //data, sizeof(data), + //&transfered, 0); + + int ret = libusb_interrupt_transfer(m_handle, endpoint | LIBUSB_ENDPOINT_IN, + data.get(), data_len, + &transfered, 0); + switch(ret) + { + case 0: // success + { + if (transfered != 20) + { + std::cout << prefix << "read(" << endpoint << "): " << transfered << "/32: data: " << std::flush; + for(int i = 0; i < transfered; ++i) + { + std::cout << boost::format("0x%02x ") % int(data[i]); + } + std::cout << std::endl; + } + + if (callback) + { + callback(data.get()); + } + } + break; + + case LIBUSB_ERROR_TIMEOUT: + std::cout << "read_thread: timeout" << std::endl; + break; + + case LIBUSB_ERROR_PIPE: + std::cout << "read_thread: pipe" << std::endl; + break; + + case LIBUSB_ERROR_OVERFLOW: + std::cout << "read_thread: overflow" << std::endl; + break; + + case LIBUSB_ERROR_NO_DEVICE: + std::cout << "read_thread: no device" << std::endl; + break; + + default: + std::cout << "read_thread: unknown: " << ret << std::endl; + break; + } + } + } + + void process_input(uint8_t* data) + { + uint8_t buttons = data[3]; + uint8_t dpad = data[2]; + + // only keep data that changed + buttons = buttons & (buttons ^ old_buttons); + dpad = dpad & (dpad ^ old_dpad); + + old_buttons = buttons; + old_dpad = dpad; + + switch(dpad) + { + case 0x04: // left + break; + + case 0x08: // right + break; + + case 0x01: // up + break; + + case 0x02: // down + break; + + case 0x20: // back + break; + + case 0x10: // start + break; + + case 0x40: // left stick + break; + + case 0x80: // right stick + break; + } + + switch(buttons) + { + case 0x10: // a + ctrl_msg(0x1f); + break; + + case 0x20: // b + ctrl_msg(0x1e); + break; + + case 0x40: // x + ctrl_msg(0x1b); + break; + + case 0x80: // y + ctrl_msg(0x10); + break; + + case 0x01: // lb + ctrl_msg(0x05); + break; + + case 0x02: // rb + ctrl_msg(0x06); + break; + + case 0x04: // guide + ctrl_msg(0x17); + break; + } + } + + void run() + { + init_libusb(); + init_device_handle(); + + { + boost::thread thread(boost::bind(&Main::read_thread, this, "cpad: ", 6, boost::function<void (uint8_t*)>())); + + boost::function<void (uint8_t*)> cb = boost::bind(&Main::process_input, this, _1); + boost::thread thread2(boost::bind(&Main::read_thread, this, "data: ", 1, cb)); + 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 */ diff --git a/chatpad/reset.cpp b/chatpad/reset.cpp new file mode 100644 index 0000000..108ed46 --- /dev/null +++ b/chatpad/reset.cpp @@ -0,0 +1,31 @@ +#include <libusb-1.0/libusb.h> +#include <iostream> +#include <stdexcept> + +int main() +{ + libusb_context* ctx = 0; + libusb_device_handle* handle = 0; + + if (libusb_init(&ctx) != 0) + { + throw std::runtime_error("Libusb went wrong"); + } + + handle = libusb_open_device_with_vid_pid(ctx, 0x045e, 0x028e); + + if (!handle) + { + std::cout << "Couldn't find device" << std::endl; + } + else + { + std::cout << "Resetting" << std::endl; + libusb_reset_device(handle); + libusb_close(handle); + } + libusb_exit(ctx); + + return 0; +} +