-
-
- #include <Arduino.h>
- #include "USBHost_t36.h"
-
- #define print USBHost::print_
- #define println USBHost::println_
-
-
-
-
- JoystickController::product_vendor_mapping_t JoystickController::pid_vid_mapping[] = {
- { 0x045e, 0x02ea, XBOXONE, false },{ 0x045e, 0x02dd, XBOXONE, false },
- { 0x045e, 0x0719, XBOX360, false},
- { 0x054C, 0x0268, PS3, true},
- { 0x054C, 0x05C4, PS4, true}, {0x054C, 0x09CC, PS4, true }
- };
-
-
-
-
- void JoystickController::init()
- {
- contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
- contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t));
- contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
- driver_ready_for_device(this);
- USBHIDParser::driver_ready_for_hid_collection(this);
- }
-
-
- JoystickController::joytype_t JoystickController::mapVIDPIDtoJoystickType(uint16_t idVendor, uint16_t idProduct, bool exclude_hid_devices)
- {
- for (uint8_t i = 0; i < (sizeof(pid_vid_mapping)/sizeof(pid_vid_mapping[0])); i++) {
- if ((idVendor == pid_vid_mapping[i].idVendor) && (idProduct == pid_vid_mapping[i].idProduct)) {
- println("Match PID/VID: ", i, DEC);
- if (exclude_hid_devices && pid_vid_mapping[i].hidDevice) return UNKNOWN;
- return pid_vid_mapping[i].joyType;
- }
- }
- return UNKNOWN;
- }
-
-
-
-
-
- uint16_t JoystickController::idVendor()
- {
- if (device != nullptr) return device->idVendor;
- if (mydevice != nullptr) return mydevice->idVendor;
- return 0;
- }
-
- uint16_t JoystickController::idProduct()
- {
- if (device != nullptr) return device->idProduct;
- if (mydevice != nullptr) return mydevice->idProduct;
- return 0;
- }
-
- const uint8_t *JoystickController::manufacturer()
- {
- if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
- if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
- return nullptr;
- }
-
- const uint8_t *JoystickController::product()
- {
- if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
- if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
- return nullptr;
- }
-
- const uint8_t *JoystickController::serialNumber()
- {
- if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
- if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
- return nullptr;
- }
-
-
- bool JoystickController::setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeout)
- {
-
-
- rumble_lValue_ = lValue;
- rumble_rValue_ = rValue;
- rumble_timeout_ = timeout;
-
- switch (joystickType) {
- default:
- break;
- case PS3:
- return transmitPS3UserFeedbackMsg();
- case PS4:
- return transmitPS4UserFeedbackMsg();
- case XBOXONE:
-
- txbuf_[0] = 0x9;
- txbuf_[1] = 0x0;
- txbuf_[2] = 0x0;
- txbuf_[3] = 0x09;
- txbuf_[4] = 0x00;
- txbuf_[5] = 0x0f;
- txbuf_[6] = 0x0;
- txbuf_[7] = 0x0;
- txbuf_[8] = lValue;
- txbuf_[9] = rValue;
- txbuf_[10] = 0xff;
- txbuf_[11] = 0x00;
- txbuf_[12] = 0x00;
- if (!queue_Data_Transfer(txpipe_, txbuf_, 13, this)) {
- println("XBoxOne rumble transfer fail");
- }
- return true;
- case XBOX360:
- txbuf_[0] = 0x00;
- txbuf_[1] = 0x01;
- txbuf_[2] = 0x0F;
- txbuf_[3] = 0xC0;
- txbuf_[4] = 0x00;
- txbuf_[5] = lValue;
- txbuf_[6] = rValue;
- txbuf_[7] = 0x00;
- txbuf_[8] = 0x00;
- txbuf_[9] = 0x00;
- txbuf_[10] = 0x00;
- txbuf_[11] = 0x00;
- if (!queue_Data_Transfer(txpipe_, txbuf_, 12, this)) {
- println("XBox360 rumble transfer fail");
- }
- return true;
- }
- return false;
- }
-
- bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb)
- {
-
-
- if ((leds_[0] != lr) || (leds_[1] != lg) || (leds_[2] != lb)) {
- leds_[0] = lr;
- leds_[1] = lg;
- leds_[2] = lb;
-
- switch (joystickType) {
- case PS3:
- return transmitPS3UserFeedbackMsg();
- case PS4:
- return transmitPS4UserFeedbackMsg();
- case XBOX360:
-
-
-
-
- txbuf_[1] = 0x00;
- txbuf_[2] = 0x08;
- txbuf_[3] = 0x40 + lr;
- txbuf_[4] = 0x00;
- txbuf_[5] = 0x00;
- txbuf_[6] = 0x00;
- txbuf_[7] = 0x00;
- txbuf_[8] = 0x00;
- txbuf_[9] = 0x00;
- txbuf_[10] = 0x00;
- txbuf_[11] = 0x00;
- if (!queue_Data_Transfer(txpipe_, txbuf_, 12, this)) {
- println("XBox360 set leds fail");
- }
- return true;
- case XBOXONE:
- default:
- return false;
- }
- }
- return false;
- }
-
- bool JoystickController::transmitPS4UserFeedbackMsg() {
- if (!driver_) return false;
- uint8_t packet[32];
- memset(packet, 0, sizeof(packet));
-
- packet[0] = 0x05;
- packet[1]= 0xFF;
-
- packet[4] = rumble_lValue_;
- packet[5] = rumble_rValue_;
- packet[6] = leds_[0];
- packet[7] = leds_[1];
- packet[8] = leds_[2];
-
- Serial.printf("Joystick update Rumble/LEDs");
- return driver_->sendPacket(packet, 32);
- }
-
- static const uint8_t PS3_USER_FEEDBACK_INIT[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00 };
-
- bool JoystickController::transmitPS3UserFeedbackMsg() {
- if (!driver_) return false;
- memcpy(txbuf_, PS3_USER_FEEDBACK_INIT, 48);
-
- txbuf_[1] = rumble_lValue_? rumble_timeout_ : 0;
- txbuf_[2] = rumble_lValue_;
- txbuf_[3] = rumble_rValue_? rumble_timeout_ : 0;
- txbuf_[4] = rumble_rValue_;
- txbuf_[9] = leds_[0] << 1;
-
- return driver_->sendControlPacket(0x21, 9, 0x201, 0, 48, txbuf_);
- }
-
-
-
-
-
- hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
- {
-
- if (topusage != 0x10004 && topusage != 0x10005) return CLAIM_NO;
-
- if (mydevice != NULL && dev != mydevice) return CLAIM_NO;
-
-
- if (device != nullptr) return CLAIM_NO;
-
- mydevice = dev;
- collections_claimed++;
- anychange = true;
- driver_ = driver;
- driver_->setTXBuffers(txbuf_, nullptr, sizeof(txbuf_));
- connected_ = true;
-
-
- joystickType = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false);
- switch (joystickType) {
- case PS3:
- additional_axis_usage_page_ = 0x1;
- additional_axis_usage_start_ = 0x100;
- additional_axis_usage_count_ = 39;
- axis_change_notify_mask_ = (uint64_t)-1;
- break;
- case PS4:
- additional_axis_usage_page_ = 0xFF00;
- additional_axis_usage_start_ = 0x21;
- additional_axis_usage_count_ = 54;
- axis_change_notify_mask_ = (uint64_t)0xfffffffffffff3ffl;
- break;
- default:
- additional_axis_usage_page_ = 0;
- additional_axis_usage_start_ = 0;
- additional_axis_usage_count_ = 0;
- axis_change_notify_mask_ = 0x3ff;
- }
- Serial.printf("Claim Additional axis: %x %x %d\n", additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
- return CLAIM_REPORT;
- }
-
- void JoystickController::disconnect_collection(Device_t *dev)
- {
- if (--collections_claimed == 0) {
- mydevice = NULL;
- driver_ = nullptr;
- axis_mask_ = 0;
- axis_changed_mask_ = 0;
- }
- }
-
- void JoystickController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax)
- {
-
- }
-
- void JoystickController::hid_input_data(uint32_t usage, int32_t value)
- {
-
- uint32_t usage_page = usage >> 16;
- usage &= 0xFFFF;
- if (usage_page == 9 && usage >= 1 && usage <= 32) {
- uint32_t bit = 1 << (usage -1);
- if (value == 0) {
- if (buttons & bit) {
- buttons &= ~bit;
- anychange = true;
- }
- } else {
- if (!(buttons & bit)) {
- buttons |= bit;
- anychange = true;
- }
- }
- } else if (usage_page == 1 && usage >= 0x30 && usage <= 0x39) {
-
-
- uint32_t i = usage - 0x30;
- axis_mask_ |= (1 << i);
- if (axis[i] != value) {
- axis[i] = value;
- axis_changed_mask_ |= (1 << i);
- if (axis_changed_mask_ & axis_change_notify_mask_)
- anychange = true;
- }
- } else if (usage_page == additional_axis_usage_page_) {
-
-
- if ((usage >= additional_axis_usage_start_) && (usage < (additional_axis_usage_start_ + additional_axis_usage_count_))) {
-
- uint16_t usage_index = usage - additional_axis_usage_start_ + STANDARD_AXIS_COUNT;
- if (usage_index < (sizeof(axis)/sizeof(axis[0]))) {
- if (axis[usage_index] != value) {
- axis[usage_index] = value;
- if (usage_index > 63) usage_index = 63;
- axis_changed_mask_ |= ((uint64_t)1 << usage_index);
- if (axis_changed_mask_ & axis_change_notify_mask_)
- anychange = true;
- }
- axis_mask_ |= ((uint64_t)1 << usage_index);
- }
-
- }
-
- } else {
- Serial.printf("UP: usage_page=%x usage=%x add: %x %x %d\n", usage_page, usage, additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
-
- }
-
- }
-
- void JoystickController::hid_input_end()
- {
- if (anychange) {
- joystickEvent = true;
- }
- }
-
- bool JoystickController::hid_process_out_data(const Transfer_t *transfer)
- {
-
- return true;
- }
-
- void JoystickController::joystickDataClear() {
- joystickEvent = false;
- anychange = false;
- axis_changed_mask_ = 0;
- axis_mask_ = 0;
- }
-
-
-
-
-
-
- static uint8_t xboxone_start_input[] = {0x05, 0x20, 0x00, 0x01, 0x00};
- static uint8_t xbox360w_inquire_present[] = {0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- bool JoystickController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
- {
- println("JoystickController claim this=", (uint32_t)this, HEX);
-
-
- if (mydevice != NULL) return false;
- if (device != nullptr) return false;
-
-
- if (type != 1) return false;
- print_hexbytes(descriptors, len);
-
- JoystickController::joytype_t jtype = mapVIDPIDtoJoystickType(dev->idVendor, dev->idProduct, true);
- println("Jtype=", (uint8_t)jtype, DEC);
- if (jtype == UNKNOWN)
- return false;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if (len < 9+7+7) return false;
-
-
- uint32_t count_end_points = descriptors[4];
- if (count_end_points < 2) return false;
- if (descriptors[5] != 0xff) return false;
- rx_ep_ = 0;
- uint32_t txep = 0;
- uint8_t rx_interval = 0;
- uint8_t tx_interval = 0;
- rx_size_ = 0;
- tx_size_ = 0;
- uint32_t descriptor_index = 9;
- if (descriptors[descriptor_index+1] == 0x22) {
- if (descriptors[descriptor_index] != 0x14) return false;
- descriptor_index += descriptors[descriptor_index];
- }
- while (count_end_points-- && ((rx_ep_ == 0) || txep == 0)) {
- if (descriptors[descriptor_index] != 7) return false;
- if (descriptors[descriptor_index+1] != 5) return false;
- if ((descriptors[descriptor_index+3] == 3)
- && (descriptors[descriptor_index+4] <= 64)
- && (descriptors[descriptor_index+5] == 0)) {
-
- if (descriptors[descriptor_index+2] & 0x80 ) {
- rx_ep_ = descriptors[descriptor_index+2];
- rx_size_ = descriptors[descriptor_index+4];
- rx_interval = descriptors[descriptor_index+6];
- } else {
- txep = descriptors[descriptor_index+2];
- tx_size_ = descriptors[descriptor_index+4];
- tx_interval = descriptors[descriptor_index+6];
- }
- }
- descriptor_index += 7;
- }
- if ((rx_ep_ == 0) || (txep == 0)) return false;
- print("JoystickController, rx_ep_=", rx_ep_ & 15);
- print("(", rx_size_);
- print("), txep=", txep);
- print("(", tx_size_);
- println(")");
- rxpipe_ = new_Pipe(dev, 3, rx_ep_ & 15, 1, rx_size_, rx_interval);
- if (!rxpipe_) return false;
- txpipe_ = new_Pipe(dev, 3, txep, 0, tx_size_, tx_interval);
- if (!txpipe_) {
-
- return false;
- }
- rxpipe_->callback_function = rx_callback;
- queue_Data_Transfer(rxpipe_, rxbuf_, rx_size_, this);
-
- txpipe_->callback_function = tx_callback;
-
- if (jtype == XBOXONE) {
- queue_Data_Transfer(txpipe_, xboxone_start_input, sizeof(xboxone_start_input), this);
- connected_ = true;
- } else if (jtype == XBOX360) {
- queue_Data_Transfer(txpipe_, xbox360w_inquire_present, sizeof(xbox360w_inquire_present), this);
- connected_ = 0;
- }
- memset(axis, 0, sizeof(axis));
- joystickType = jtype;
- return true;
- }
-
- void JoystickController::control(const Transfer_t *transfer)
- {
- }
-
-
-
-
-
-
- void JoystickController::rx_callback(const Transfer_t *transfer)
- {
- if (!transfer->driver) return;
- ((JoystickController *)(transfer->driver))->rx_data(transfer);
- }
-
- void JoystickController::tx_callback(const Transfer_t *transfer)
- {
- if (!transfer->driver) return;
- ((JoystickController *)(transfer->driver))->tx_data(transfer);
- }
-
-
-
-
-
-
-
-
-
- typedef struct {
- uint8_t type;
- uint8_t const_0;
- uint16_t id;
-
-
-
-
-
-
-
- uint16_t buttons;
- int16_t axis[6];
- } xbox1data20_t;
-
- typedef struct {
- uint8_t state;
- uint8_t id_or_type;
- uint16_t controller_status;
- uint16_t unknown;
-
-
-
-
-
-
-
- uint16_t buttons;
- uint8_t lt;
- uint8_t rt;
- int16_t axis[4];
- } xbox360data_t;
-
- static const uint8_t xbox_axis_order_mapping[] = {4, 5, 0, 1, 2, 3};
-
- void JoystickController::rx_data(const Transfer_t *transfer)
- {
- print("JoystickController::rx_data: ");
- print_hexbytes((uint8_t*)transfer->buffer, transfer->length);
-
- if (joystickType == XBOXONE) {
-
- axis_mask_ = 0x3f;
- axis_changed_mask_ = 0;
- xbox1data20_t *xb1d = (xbox1data20_t *)transfer->buffer;
- if ((xb1d->type == 0x20) && (transfer->length >= sizeof (xbox1data20_t))) {
-
- if (xb1d->buttons != buttons) {
- buttons = xb1d->buttons;
- anychange = true;
- }
- for (uint8_t i = 0; i < sizeof (xbox_axis_order_mapping); i++) {
-
- int axis_value = (i < 2)? (int)(uint16_t)xb1d->axis[i] : xb1d->axis[i];
- if (axis_value != axis[xbox_axis_order_mapping[i]]) {
- axis[xbox_axis_order_mapping[i]] = axis_value;
- axis_changed_mask_ |= (1 << xbox_axis_order_mapping[i]);
- anychange = true;
- }
- }
- joystickEvent = true;
- }
-
- } else if (joystickType == XBOX360) {
-
- xbox360data_t *xb360d = (xbox360data_t *)transfer->buffer;
- if (xb360d->state == 0x08) {
- if (xb360d->id_or_type != connected_) {
- connected_ = xb360d->id_or_type;
- if (connected_) {
- println("XBox360w - Connected type:", connected_, HEX);
-
- setLEDs(2+rx_ep_/2);
-
- } else {
- println("XBox360w - disconnected");
- }
- }
- } else if((xb360d->id_or_type == 0x00) && (xb360d->controller_status & 0x1300)) {
-
- println("XBox360w - controllerStatus: ", xb360d->controller_status, HEX);
- } else if(xb360d->id_or_type == 0x01) {
-
-
-
-
- if (buttons != xb360d->buttons) {
- buttons = xb360d->buttons;
- anychange = true;
- }
- axis_mask_ = 0x3f;
- axis_changed_mask_ = 0;
-
- for (uint8_t i = 0; i < 4; i++) {
- if (axis[i] != xb360d->axis[i]) {
- axis[i] = xb360d->axis[i];
- axis_changed_mask_ |= (1 << i);
- anychange = true;
- }
- }
-
- if (axis[4] != xb360d->lt) {
- axis[4] = xb360d->lt;
- axis_changed_mask_ |= (1 << 4);
- anychange = true;
- }
-
- if (axis[5] != xb360d->rt) {
- axis[5] = xb360d->rt;
- axis_changed_mask_ |= (1 << 5);
- anychange = true;
- }
-
- if (anychange) joystickEvent = true;
- }
- }
-
- queue_Data_Transfer(rxpipe_, rxbuf_, rx_size_, this);
- }
-
- void JoystickController::tx_data(const Transfer_t *transfer)
- {
- }
-
- void JoystickController::disconnect()
- {
- axis_mask_ = 0;
- axis_changed_mask_ = 0;
-
- }
-
-
|