diff --git a/Makefile b/Makefile index 713d0e536..2a8c6c66e 100644 --- a/Makefile +++ b/Makefile @@ -328,7 +328,7 @@ clean: download_lwNBD echo " -ds34bt" $(MAKE) -C modules/ds34bt clean echo " -pademu" - $(MAKE) -C modules/pademu USE_DS3USB=1 USE_DS3BT=1 USE_DS4USB=1 USE_DS4BT=1 clean + $(MAKE) -C modules/pademu USE_DS3=1 USE_DS4=1 clean echo "-pc tools" $(MAKE) -C pc clean @@ -521,7 +521,7 @@ $(EE_ASM_DIR)ds34usb.c: modules/ds34usb/iop/ds34usb.irx | $(EE_ASM_DIR) $(BIN2C) $< $@ $(*F)_irx modules/pademu/pademu.irx: modules/pademu - $(MAKE) USE_DS3USB=1 USE_DS3BT=1 USE_DS4USB=1 USE_DS4BT=1 -C $< all + $(MAKE) USE_DS3=1 USE_DS4=1 -C $< all $(EE_ASM_DIR)pademu.c: modules/pademu/pademu.irx $(BIN2C) $< $@ $(*F)_irx diff --git a/modules/pademu/Makefile b/modules/pademu/Makefile index 9aced9587..219894a96 100644 --- a/modules/pademu/Makefile +++ b/modules/pademu/Makefile @@ -2,24 +2,14 @@ IOP_OBJS = pademu_common.o pademu.o sys_utils.o imports.o exports.o padmacro.o IOP_BIN = pademu.irx -ifeq ($(USE_DS3USB),1) -IOP_CFLAGS += -DDS3USB -IOP_OBJS += ds3usb.o +ifeq ($(USE_DS3),1) +IOP_CFLAGS += -DUSE_DS3 +IOP_OBJS += ds3usb.o ds3bt.o endif -ifeq ($(USE_DS3BT),1) -IOP_CFLAGS += -DDS3BT -IOP_OBJS += ds3bt.o -endif - -ifeq ($(USE_DS4USB),1) -IOP_CFLAGS += -DDS4USB -IOP_OBJS += ds4usb.o -endif - -ifeq ($(USE_DS4BT),1) -IOP_CFLAGS += -DDS4BT -IOP_OBJS += ds4bt.o +ifeq ($(USE_DS4),1) +IOP_CFLAGS += -DUSE_DS4 +IOP_OBJS += ds4usb.o ds4bt.o endif ifeq ($(VMC),1) diff --git a/modules/pademu/ds3bt.c b/modules/pademu/ds3bt.c index 2e870b631..b454d3f95 100644 --- a/modules/pademu/ds3bt.c +++ b/modules/pademu/ds3bt.c @@ -187,7 +187,6 @@ static int bt_disconnect(int devId) return 0; } - #define OUTPUT_01_REPORT_SIZE 48 static const u8 hid_cmd_payload_led_arguments[] = {0xff, 0x27, 0x10, 0x00, 0x32}; @@ -514,7 +513,7 @@ static void HCI_event_task(int result) if (i >= MAX_PADS) { break; } - pad_status_set(DS3BT_STATE_CONNECTED, i); + ds3pad_status_set(DS3BT_STATE_CONNECTED, i); hci_remote_name(ds3pad[i].bdaddr); } else { DPRINTF("\t Error 0x%02X \n", hci_buf[2]); @@ -588,9 +587,9 @@ static void HCI_event_task(int result) DPRINTF("\n\t Link = 0x%02X \n", hci_buf[11]); DPRINTF("\t Class = 0x%02X 0x%02X 0x%02X \n", hci_buf[8], hci_buf[9], hci_buf[10]); for (i = 0; i < MAX_PADS; i++) { // find free slot - if (!pad_status_check(DS3BT_STATE_RUNNING, i) && ds3pad[i].enabled) { - if (pad_status_check(DS3BT_STATE_CONNECTED, i)) { - if (pad_status_check(DS3BT_STATE_DISCONNECTING, i)) // if we're waiting for hci disconnect event + if (!ds3pad_status_check(DS3BT_STATE_RUNNING, i) && ds3pad[i].enabled) { + if (ds3pad_status_check(DS3BT_STATE_CONNECTED, i)) { + if (ds3pad_status_check(DS3BT_STATE_DISCONNECTING, i)) // if we're waiting for hci disconnect event continue; else hci_disconnect(ds3pad[i].hci_handle); // try to disconnect @@ -616,9 +615,9 @@ static void HCI_event_task(int result) } } } - pad_status_clear(DS3BT_STATE_CONNECTED, pad); - pad_status_clear(DS3BT_STATE_RUNNING, pad); - pad_status_clear(DS3BT_STATE_DISCONNECTING, pad); + ds3pad_status_clear(DS3BT_STATE_CONNECTED, pad); + ds3pad_status_clear(DS3BT_STATE_RUNNING, pad); + ds3pad_status_clear(DS3BT_STATE_DISCONNECTING, pad); hci_accept_connection(ds3pad[pad].bdaddr); break; @@ -706,7 +705,7 @@ static void hci_event_cb(int resultCode, int bytes, void *arg) /* L2CAP Commands */ /************************************************************/ -static int L2CAP_Command(u16 handle, u16 scid, u8 *data, u8 length) +static int L2CAP_Command(u16 handle, u8 *data, u8 length) { l2cap_cmd_buf[0] = (u8)(handle & 0xff); // HCI handle with PB,BC flag l2cap_cmd_buf[1] = (u8)(((handle >> 8) & 0x0f) | 0x20); @@ -714,9 +713,9 @@ static int L2CAP_Command(u16 handle, u16 scid, u8 *data, u8 length) l2cap_cmd_buf[3] = (u8)((4 + length) >> 8); l2cap_cmd_buf[4] = (u8)(length & 0xff); // L2CAP header: Length l2cap_cmd_buf[5] = (u8)(length >> 8); - l2cap_cmd_buf[6] = (u8)(scid & 0xff); // L2CAP header: Channel ID - l2cap_cmd_buf[7] = (u8)(scid >> 8); // L2CAP Signalling channel over ACL-U logical link - + l2cap_cmd_buf[6] = 0x01; // L2CAP header: Channel ID + l2cap_cmd_buf[7] = 0x00; // L2CAP Signalling channel over ACL-U logical link + mips_memcpy(&l2cap_cmd_buf[8], data, length); // output on endpoint 2 @@ -743,7 +742,7 @@ static int l2cap_connection_response(u16 handle, u8 rxid, u16 dcid, u16 scid, u8 if (result != 0) cmd_buf[10] = 0x01; // Authentication pending - return L2CAP_Command(handle, 1, cmd_buf, 12); + return L2CAP_Command(handle, cmd_buf, 12); } static int l2cap_config_request(u16 handle, u8 rxid, u16 dcid) @@ -767,7 +766,7 @@ static int l2cap_config_request(u16 handle, u8 rxid, u16 dcid) cmd_buf[10] = 0xFF; // Config Opt: data cmd_buf[11] = 0xFF; - return L2CAP_Command(handle, 1, cmd_buf, 12); + return L2CAP_Command(handle, cmd_buf, 12); } static int l2cap_config_response(u16 handle, u8 rxid, u16 scid) @@ -789,7 +788,7 @@ static int l2cap_config_response(u16 handle, u8 rxid, u16 scid) cmd_buf[12] = 0xA0; cmd_buf[13] = 0x02; - return L2CAP_Command(handle, 1, cmd_buf, 14); + return L2CAP_Command(handle, cmd_buf, 14); } static int l2cap_disconnection_request(u16 handle, u8 rxid, u16 dcid, u16 scid) @@ -805,7 +804,7 @@ static int l2cap_disconnection_request(u16 handle, u8 rxid, u16 dcid, u16 scid) cmd_buf[6] = (u8)(scid & 0xff); // Source CID cmd_buf[7] = (u8)(scid >> 8); - return L2CAP_Command(handle, 1, cmd_buf, 8); + return L2CAP_Command(handle, cmd_buf, 8); } static int l2cap_disconnection_response(u16 handle, u8 rxid, u16 scid, u16 dcid) @@ -821,7 +820,7 @@ static int l2cap_disconnection_response(u16 handle, u8 rxid, u16 scid, u16 dcid) cmd_buf[6] = (u8)(scid & 0xff); // Source CID cmd_buf[7] = (u8)(scid >> 8); - return L2CAP_Command(handle, 1, cmd_buf, 8); + return L2CAP_Command(handle, cmd_buf, 8); } #define CMD_DELAY 2 @@ -923,7 +922,7 @@ static int L2CAP_event_task(int result, int bytes) ds3pad[pad].oldled[3] = 0; DelayThread(CMD_DELAY); hid_LEDRumbleCommand(ds3pad[pad].oldled, 0, 0, pad); - pad_status_set(DS3BT_STATE_RUNNING, pad); + ds3pad_status_set(DS3BT_STATE_RUNNING, pad); pademu_connect(&padf[pad]); } ds3pad[pad].btn_delay = 0xFF; @@ -933,10 +932,10 @@ static int L2CAP_event_task(int result, int bytes) DPRINTF("Disconnect Request SCID = 0x%04X \n", (l2cap_buf[12] | (l2cap_buf[13] << 8))); if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == control_dcid) { - pad_status_set(DS3BT_STATE_DISCONNECTING, pad); + ds3pad_status_set(DS3BT_STATE_DISCONNECTING, pad); l2cap_disconnection_response(ds3pad[pad].hci_handle, l2cap_buf[9], control_dcid, ds3pad[pad].control_scid); } else if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == interrupt_dcid) { - pad_status_set(DS3BT_STATE_DISCONNECTING, pad); + ds3pad_status_set(DS3BT_STATE_DISCONNECTING, pad); l2cap_disconnection_response(ds3pad[pad].hci_handle, l2cap_buf[9], interrupt_dcid, ds3pad[pad].interrupt_scid); } break; @@ -945,10 +944,10 @@ static int L2CAP_event_task(int result, int bytes) DPRINTF("Disconnect Response SCID = 0x%04X \n", (l2cap_buf[12] | (l2cap_buf[13] << 8))); if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == ds3pad[pad].control_scid) { - pad_status_set(DS3BT_STATE_DISCONNECTING, pad); + ds3pad_status_set(DS3BT_STATE_DISCONNECTING, pad); hci_disconnect(ds3pad[pad].hci_handle); } else if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == ds3pad[pad].interrupt_scid) { - pad_status_set(DS3BT_STATE_DISCONNECTING, pad); + ds3pad_status_set(DS3BT_STATE_DISCONNECTING, pad); identifier++; l2cap_disconnection_request(ds3pad[pad].hci_handle, identifier, ds3pad[pad].control_scid, control_dcid); } @@ -979,15 +978,15 @@ static void l2cap_event_cb(int resultCode, int bytes, void *arg) ret = L2CAP_event_task(resultCode, bytes); if (ret < MAX_PADS) { - if (pad_status_check(DS3BT_STATE_RUNNING, ret)) { - if (pad_status_check(DS3BT_STATE_DISCONNECT_REQUEST, ret)) { + if (ds3pad_status_check(DS3BT_STATE_RUNNING, ret)) { + if (ds3pad_status_check(DS3BT_STATE_DISCONNECT_REQUEST, ret)) { if (!ds3pad[ret].isfake) { identifier++; l2cap_disconnection_request(ds3pad[ret].hci_handle, identifier, ds3pad[ret].interrupt_scid, interrupt_dcid); } else { hci_disconnect(ds3pad[ret].hci_handle); } - pad_status_clear(DS3BT_STATE_DISCONNECT_REQUEST, ret); + ds3pad_status_clear(DS3BT_STATE_DISCONNECT_REQUEST, ret); } else if (ds3pad[ret].update_rum) { hid_LEDRumbleCommand(ds3pad[ret].oldled, ds3pad[ret].lrum, ds3pad[ret].rrum, ret); ds3pad[ret].update_rum = 0; @@ -1006,6 +1005,21 @@ static void l2cap_event_cb(int resultCode, int bytes, void *arg) /* HID Commands */ /************************************************************/ +static int HID_command(u16 handle, u16 scid, u8 *data, u8 length) +{ + l2cap_cmd_buf[0] = (u8)(handle & 0xff); // HCI handle with PB,BC flag + l2cap_cmd_buf[1] = (u8)(((handle >> 8) & 0x0f) | 0x20); + l2cap_cmd_buf[2] = (u8)((4 + length) & 0xff); // HCI ACL total data length + l2cap_cmd_buf[3] = (u8)((4 + length) >> 8); + l2cap_cmd_buf[4] = (u8)(length & 0xff); // L2CAP header: Length + l2cap_cmd_buf[5] = (u8)(length >> 8); + l2cap_cmd_buf[6] = (u8)(scid & 0xff); // L2CAP header: Channel ID + l2cap_cmd_buf[7] = (u8)(scid >> 8); + mips_memcpy(&l2cap_cmd_buf[8], data, length); + // output on endpoint 2 + return sceUsbdBulkTransfer(bt_dev.outEndp, l2cap_cmd_buf, (8 + length), NULL, NULL); +} + static int hid_initDS34(int pad) { u8 init_buf[PS3_F4_REPORT_LEN + 2]; @@ -1019,7 +1033,7 @@ static int hid_initDS34(int pad) init_buf[5] = 0x00; size += PS3_F4_REPORT_LEN; - return L2CAP_Command(ds3pad[pad].hci_handle, ds3pad[pad].control_scid, init_buf, size); + return HID_command(ds3pad[pad].hci_handle, ds3pad[pad].control_scid, init_buf, size); } /** @@ -1071,7 +1085,7 @@ static int hid_LEDRumbleCommand(u8 *led, u8 lrum, u8 rrum, int pad) ds3pad[pad].oldled[2] = led[2]; ds3pad[pad].oldled[3] = led[3]; - return L2CAP_Command(ds3pad[pad].hci_handle, ds3pad[pad].control_scid, led_buf, size); + return HID_command(ds3pad[pad].hci_handle, ds3pad[pad].control_scid, led_buf, size); } static void hid_readReport(u8 *data, int bytes, int pad_idx) @@ -1248,12 +1262,12 @@ void ds3bt_reset() if (bt_dev.status & DS3BT_STATE_USB_AUTHORIZED) { for (pad = 0; pad < MAX_PADS; pad++) { WaitSema(bt_dev.hid_sema); - pad_status_set(DS3BT_STATE_DISCONNECT_REQUEST, pad); + ds3pad_status_set(DS3BT_STATE_DISCONNECT_REQUEST, pad); SignalSema(bt_dev.hid_sema); while (1) { DelayThread(500); WaitSema(bt_dev.hid_sema); - if (!pad_status_check(DS3BT_STATE_RUNNING, pad)) { + if (!ds3pad_status_check(DS3BT_STATE_RUNNING, pad)) { SignalSema(bt_dev.hid_sema); break; } diff --git a/modules/pademu/ds3bt.h b/modules/pademu/ds3bt.h index 5d706b2e4..f44a10163 100644 --- a/modules/pademu/ds3bt.h +++ b/modules/pademu/ds3bt.h @@ -39,9 +39,9 @@ enum eDS34BTStatus { DS3BT_STATE_DISCONNECT_REQUEST = 0x20, }; -#define pad_status_clear(flag, pad) ds3pad[pad].status &= ~flag -#define pad_status_set(flag, pad) ds3pad[pad].status |= flag -#define pad_status_check(flag, pad) (ds3pad[pad].status & flag) +#define ds3pad_status_clear(flag, pad) ds3pad[pad].status &= ~flag +#define ds3pad_status_set(flag, pad) ds3pad[pad].status |= flag +#define ds3pad_status_check(flag, pad) (ds3pad[pad].status & flag) #define hci_event_flag_clear(flag) hci_event_flag &= ~flag #define hci_event_flag_set(flag) hci_event_flag |= flag diff --git a/modules/pademu/ds3usb.c b/modules/pademu/ds3usb.c index abf1ec759..6f11211d5 100644 --- a/modules/pademu/ds3usb.c +++ b/modules/pademu/ds3usb.c @@ -93,7 +93,7 @@ static int usb_probe(int devId) return 1; } - if (device->idVendor == DS34_VID && (device->idProduct == DS3_PID)) + if (device->idVendor == DS_VID && (device->idProduct == DS3_PID)) return 1; return 0; @@ -146,7 +146,7 @@ static int usb_connect(int devId) endpoint = (UsbEndpointDescriptor *)sceUsbdScanStaticDescriptor(devId, NULL, USB_DT_ENDPOINT); - do { + while (epCount-- > 0) { if (endpoint->bmAttributes == USB_ENDPOINT_XFER_INT) { if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN && ds3pad[pad].interruptEndp < 0) { ds3pad[pad].interruptEndp = sceUsbdOpenPipe(devId, endpoint); @@ -159,8 +159,7 @@ static int usb_connect(int devId) } endpoint = (UsbEndpointDescriptor *)((char *)endpoint + endpoint->bLength); - - } while (epCount--); + } if (ds3pad[pad].interruptEndp < 0 || ds3pad[pad].outEndp < 0) { usb_release(pad); diff --git a/modules/pademu/ds4bt.c b/modules/pademu/ds4bt.c index a5dc3675f..0c94dc757 100644 --- a/modules/pademu/ds4bt.c +++ b/modules/pademu/ds4bt.c @@ -34,7 +34,6 @@ static void bt_config_set(int result, int count, void *arg); static UsbDriver bt_driver = {NULL, NULL, "ds4bt", bt_probe, bt_connect, bt_disconnect}; static bt_device bt_dev = {-1, -1, -1, -1, -1, -1, DS4BT_STATE_USB_DISCONNECTED}; - static void ds4pad_clear(int pad); static void ds4pad_init(); static int ds4bt_get_status(struct pad_funcs *pf); @@ -88,6 +87,9 @@ static int bt_probe(int devId) return 0; } + if (device->idVendor == DS_VID && (device->idProduct == DS4_PID || device->idProduct == DS4_PID_SLIM)) + return 1; + return 1; } @@ -187,7 +189,6 @@ static int bt_disconnect(int devId) return 0; } - #define OUTPUT_01_REPORT_SIZE 48 static u8 rgbled_patterns[][2][3] = @@ -510,7 +511,7 @@ static void HCI_event_task(int result) if (i >= MAX_PADS) { break; } - pad_status_set(DS4BT_STATE_CONNECTED, i); + ds4pad_status_set(DS4BT_STATE_CONNECTED, i); hci_remote_name(ds4pad[i].bdaddr); } else { DPRINTF("\t Error 0x%02X \n", hci_buf[2]); @@ -587,9 +588,9 @@ static void HCI_event_task(int result) DPRINTF("\n\t Link = 0x%02X \n", hci_buf[11]); DPRINTF("\t Class = 0x%02X 0x%02X 0x%02X \n", hci_buf[8], hci_buf[9], hci_buf[10]); for (i = 0; i < MAX_PADS; i++) { // find free slot - if (!pad_status_check(DS4BT_STATE_RUNNING, i) && ds4pad[i].enabled) { - if (pad_status_check(DS4BT_STATE_CONNECTED, i)) { - if (pad_status_check(DS4BT_STATE_DISCONNECTING, i)) // if we're waiting for hci disconnect event + if (!ds4pad_status_check(DS4BT_STATE_RUNNING, i) && ds4pad[i].enabled) { + if (ds4pad_status_check(DS4BT_STATE_CONNECTED, i)) { + if (ds4pad_status_check(DS4BT_STATE_DISCONNECTING, i)) // if we're waiting for hci disconnect event continue; else hci_disconnect(ds4pad[i].hci_handle); // try to disconnect @@ -615,9 +616,9 @@ static void HCI_event_task(int result) } } } - pad_status_clear(DS4BT_STATE_CONNECTED, pad); - pad_status_clear(DS4BT_STATE_RUNNING, pad); - pad_status_clear(DS4BT_STATE_DISCONNECTING, pad); + ds4pad_status_clear(DS4BT_STATE_CONNECTED, pad); + ds4pad_status_clear(DS4BT_STATE_RUNNING, pad); + ds4pad_status_clear(DS4BT_STATE_DISCONNECTING, pad); hci_accept_connection(ds4pad[pad].bdaddr); break; @@ -705,7 +706,7 @@ static void hci_event_cb(int resultCode, int bytes, void *arg) /* L2CAP Commands */ /************************************************************/ -static int L2CAP_Command(u16 handle, u16 scid, u8 *data, u8 length) +static int L2CAP_Command(u16 handle, u8 *data, u8 length) { l2cap_cmd_buf[0] = (u8)(handle & 0xff); // HCI handle with PB,BC flag l2cap_cmd_buf[1] = (u8)(((handle >> 8) & 0x0f) | 0x20); @@ -713,8 +714,8 @@ static int L2CAP_Command(u16 handle, u16 scid, u8 *data, u8 length) l2cap_cmd_buf[3] = (u8)((4 + length) >> 8); l2cap_cmd_buf[4] = (u8)(length & 0xff); // L2CAP header: Length l2cap_cmd_buf[5] = (u8)(length >> 8); - l2cap_cmd_buf[6] = (u8)(scid & 0xff); // L2CAP header: Channel ID - l2cap_cmd_buf[7] = (u8)(scid >> 8); // L2CAP Signalling channel over ACL-U logical link + l2cap_cmd_buf[6] = 0x01; // L2CAP header: Channel ID + l2cap_cmd_buf[7] = 0x00; // L2CAP Signalling channel over ACL-U logical link mips_memcpy(&l2cap_cmd_buf[8], data, length); @@ -735,7 +736,7 @@ static int l2cap_connection_request(u16 handle, u8 rxid, u16 scid, u16 psm) cmd_buf[6] = (u8)(scid & 0xff); // Source CID (PS Remote) cmd_buf[7] = (u8)(scid >> 8); - return L2CAP_Command(handle, 1, cmd_buf, 8); + return L2CAP_Command(handle, cmd_buf, 8); } static int l2cap_connection_response(u16 handle, u8 rxid, u16 dcid, u16 scid, u8 result) @@ -758,7 +759,7 @@ static int l2cap_connection_response(u16 handle, u8 rxid, u16 dcid, u16 scid, u8 if (result != 0) cmd_buf[10] = 0x01; // Authentication pending - return L2CAP_Command(handle, 1, cmd_buf, 12); + return L2CAP_Command(handle, cmd_buf, 12); } static int l2cap_config_request(u16 handle, u8 rxid, u16 dcid) @@ -782,7 +783,7 @@ static int l2cap_config_request(u16 handle, u8 rxid, u16 dcid) cmd_buf[10] = 0xFF; // Config Opt: data cmd_buf[11] = 0xFF; - return L2CAP_Command(handle, 1, cmd_buf, 12); + return L2CAP_Command(handle, cmd_buf, 12); } static int l2cap_config_response(u16 handle, u8 rxid, u16 scid) @@ -804,7 +805,7 @@ static int l2cap_config_response(u16 handle, u8 rxid, u16 scid) cmd_buf[12] = 0xA0; cmd_buf[13] = 0x02; - return L2CAP_Command(handle, 1, cmd_buf, 14); + return L2CAP_Command(handle, cmd_buf, 14); } static int l2cap_disconnection_request(u16 handle, u8 rxid, u16 dcid, u16 scid) @@ -820,7 +821,7 @@ static int l2cap_disconnection_request(u16 handle, u8 rxid, u16 dcid, u16 scid) cmd_buf[6] = (u8)(scid & 0xff); // Source CID cmd_buf[7] = (u8)(scid >> 8); - return L2CAP_Command(handle, 1, cmd_buf, 8); + return L2CAP_Command(handle, cmd_buf, 8); } static int l2cap_disconnection_response(u16 handle, u8 rxid, u16 scid, u16 dcid) @@ -836,7 +837,7 @@ static int l2cap_disconnection_response(u16 handle, u8 rxid, u16 scid, u16 dcid) cmd_buf[6] = (u8)(scid & 0xff); // Source CID cmd_buf[7] = (u8)(scid >> 8); - return L2CAP_Command(handle, 1, cmd_buf, 8); + return L2CAP_Command(handle, cmd_buf, 8); } #define CMD_DELAY 2 @@ -946,7 +947,7 @@ static int L2CAP_event_task(int result, int bytes) ds4pad[pad].oldled[3] = 0; DelayThread(CMD_DELAY); hid_LEDRumbleCommand(ds4pad[pad].oldled, 0, 0, pad); - pad_status_set(DS4BT_STATE_RUNNING, pad); + ds4pad_status_set(DS4BT_STATE_RUNNING, pad); pademu_connect(&padf[pad]); } ds4pad[pad].btn_delay = 0xFF; @@ -956,10 +957,10 @@ static int L2CAP_event_task(int result, int bytes) DPRINTF("Disconnect Request SCID = 0x%04X \n", (l2cap_buf[12] | (l2cap_buf[13] << 8))); if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == control_dcid) { - pad_status_set(DS4BT_STATE_DISCONNECTING, pad); + ds4pad_status_set(DS4BT_STATE_DISCONNECTING, pad); l2cap_disconnection_response(ds4pad[pad].hci_handle, l2cap_buf[9], control_dcid, ds4pad[pad].control_scid); } else if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == interrupt_dcid) { - pad_status_set(DS4BT_STATE_DISCONNECTING, pad); + ds4pad_status_set(DS4BT_STATE_DISCONNECTING, pad); l2cap_disconnection_response(ds4pad[pad].hci_handle, l2cap_buf[9], interrupt_dcid, ds4pad[pad].interrupt_scid); } break; @@ -968,10 +969,10 @@ static int L2CAP_event_task(int result, int bytes) DPRINTF("Disconnect Response SCID = 0x%04X \n", (l2cap_buf[12] | (l2cap_buf[13] << 8))); if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == ds4pad[pad].control_scid) { - pad_status_set(DS4BT_STATE_DISCONNECTING, pad); + ds4pad_status_set(DS4BT_STATE_DISCONNECTING, pad); hci_disconnect(ds4pad[pad].hci_handle); } else if ((l2cap_buf[12] | (l2cap_buf[13] << 8)) == ds4pad[pad].interrupt_scid) { - pad_status_set(DS4BT_STATE_DISCONNECTING, pad); + ds4pad_status_set(DS4BT_STATE_DISCONNECTING, pad); identifier++; l2cap_disconnection_request(ds4pad[pad].hci_handle, identifier, ds4pad[pad].control_scid, control_dcid); } @@ -1002,8 +1003,8 @@ static void l2cap_event_cb(int resultCode, int bytes, void *arg) ret = L2CAP_event_task(resultCode, bytes); if (ret < MAX_PADS) { - if (pad_status_check(DS4BT_STATE_RUNNING, ret)) { - if (pad_status_check(DS4BT_STATE_DISCONNECT_REQUEST, ret)) { + if (ds4pad_status_check(DS4BT_STATE_RUNNING, ret)) { + if (ds4pad_status_check(DS4BT_STATE_DISCONNECT_REQUEST, ret)) { if (!ds4pad[ret].isfake) { interrupt_dcid = 0x0071; identifier++; @@ -1011,7 +1012,7 @@ static void l2cap_event_cb(int resultCode, int bytes, void *arg) } else { hci_disconnect(ds4pad[ret].hci_handle); } - pad_status_clear(DS4BT_STATE_DISCONNECT_REQUEST, ret); + ds4pad_status_clear(DS4BT_STATE_DISCONNECT_REQUEST, ret); } else if (ds4pad[ret].update_rum) { hid_LEDRumbleCommand(ds4pad[ret].oldled, ds4pad[ret].lrum, ds4pad[ret].rrum, ret); ds4pad[ret].update_rum = 0; @@ -1026,6 +1027,22 @@ static void l2cap_event_cb(int resultCode, int bytes, void *arg) /************************************************************/ /* HID Commands */ /************************************************************/ +static int HID_command(u16 handle, u16 scid, u8 *data, u8 length) +{ + l2cap_cmd_buf[0] = (u8)(handle & 0xff); // HCI handle with PB,BC flag + l2cap_cmd_buf[1] = (u8)(((handle >> 8) & 0x0f) | 0x20); + l2cap_cmd_buf[2] = (u8)((4 + length) & 0xff); // HCI ACL total data length + l2cap_cmd_buf[3] = (u8)((4 + length) >> 8); + l2cap_cmd_buf[4] = (u8)(length & 0xff); // L2CAP header: Length + l2cap_cmd_buf[5] = (u8)(length >> 8); + l2cap_cmd_buf[6] = (u8)(scid & 0xff); // L2CAP header: Channel ID + l2cap_cmd_buf[7] = (u8)(scid >> 8); + + mips_memcpy(&l2cap_cmd_buf[8], data, length); + + // output on endpoint 2 + return sceUsbdBulkTransfer(bt_dev.outEndp, l2cap_cmd_buf, (8 + length), NULL, NULL); +} static int hid_initDS34(int pad) { @@ -1035,7 +1052,7 @@ static int hid_initDS34(int pad) init_buf[0] = HID_THDR_GET_REPORT_FEATURE; // THdr init_buf[1] = PS4_02_REPORT_ID; // Report I - return L2CAP_Command(ds4pad[pad].hci_handle, ds4pad[pad].control_scid, init_buf, size); + return HID_command(ds4pad[pad].hci_handle, ds4pad[pad].control_scid, init_buf, size); } /** @@ -1079,7 +1096,7 @@ static int hid_LEDRumbleCommand(u8 *led, u8 lrum, u8 rrum, int pad) ds4pad[pad].oldled[2] = led[2]; ds4pad[pad].oldled[3] = led[3]; - return L2CAP_Command(ds4pad[pad].hci_handle, ds4pad[pad].control_scid, led_buf, size); + return HID_command(ds4pad[pad].hci_handle, ds4pad[pad].control_scid, led_buf, size); } static void hid_readReport(u8 *data, int bytes, int pad_idx) @@ -1236,12 +1253,12 @@ void ds4bt_reset() if (bt_dev.status & DS4BT_STATE_USB_AUTHORIZED) { for (pad = 0; pad < MAX_PADS; pad++) { WaitSema(bt_dev.hid_sema); - pad_status_set(DS4BT_STATE_DISCONNECT_REQUEST, pad); + ds4pad_status_set(DS4BT_STATE_DISCONNECT_REQUEST, pad); SignalSema(bt_dev.hid_sema); while (1) { DelayThread(500); WaitSema(bt_dev.hid_sema); - if (!pad_status_check(DS4BT_STATE_RUNNING, pad)) { + if (!ds4pad_status_check(DS4BT_STATE_RUNNING, pad)) { SignalSema(bt_dev.hid_sema); break; } @@ -1251,4 +1268,4 @@ void ds4bt_reset() DelayThread(1000000); bt_disconnect(bt_dev.devId); } -} +} \ No newline at end of file diff --git a/modules/pademu/ds4bt.h b/modules/pademu/ds4bt.h index af0d4bc8b..485032d74 100644 --- a/modules/pademu/ds4bt.h +++ b/modules/pademu/ds4bt.h @@ -39,9 +39,9 @@ enum eDS4BTStatus { DS4BT_STATE_DISCONNECT_REQUEST = 0x20, }; -#define pad_status_clear(flag, pad) ds4pad[pad].status &= ~flag -#define pad_status_set(flag, pad) ds4pad[pad].status |= flag -#define pad_status_check(flag, pad) (ds4pad[pad].status & flag) +#define ds4pad_status_clear(flag, pad) ds4pad[pad].status &= ~flag +#define ds4pad_status_set(flag, pad) ds4pad[pad].status |= flag +#define ds4pad_status_check(flag, pad) (ds4pad[pad].status & flag) #define hci_event_flag_clear(flag) hci_event_flag &= ~flag #define hci_event_flag_set(flag) hci_event_flag |= flag diff --git a/modules/pademu/ds4usb.c b/modules/pademu/ds4usb.c index 24c42ef10..5cb952147 100644 --- a/modules/pademu/ds4usb.c +++ b/modules/pademu/ds4usb.c @@ -73,7 +73,7 @@ static int usb_probe(int devId) return 1; } - if (device->idVendor == DS34_VID && (device->idProduct == DS4_PID || device->idProduct == DS4_PID_SLIM)) + if (device->idVendor == DS_VID && (device->idProduct == DS4_PID || device->idProduct == DS4_PID_SLIM)) return 1; return 0; diff --git a/modules/pademu/pademu.c b/modules/pademu/pademu.c index 72ac198df..3e3301c3e 100644 --- a/modules/pademu/pademu.c +++ b/modules/pademu/pademu.c @@ -12,25 +12,17 @@ static struct pad_funcs *padf[MAX_PORTS]; -#ifdef DS3BT +#ifdef USE_DS3 #include "ds3bt.h" -#endif - -#ifdef DS3USB - #include "ds3usb.h" #endif -#ifdef DS4BT +#ifdef USE_DS4 #include "ds4bt.h" -#endif - -#ifdef DS4USB - #include "ds4usb.h" #endif @@ -146,16 +138,12 @@ int _start(int argc, char *argv[]) pademu_setup(pad_enable, pad_vibration); -#ifdef DS3BT +#ifdef USE_DS3 ds3bt_init(pad_enable, pad_options); -#endif -#ifdef DS3USB ds3usb_init(pad_enable, pad_options); #endif -#ifdef DS4BT +#ifdef USE_DS4 ds4bt_init(pad_enable, pad_options); -#endif -#ifdef DS4USB ds4usb_init(pad_enable, pad_options); #endif @@ -198,16 +186,12 @@ void pademu_disconnect(struct pad_funcs *pf) void _exit(int mode) { -#ifdef DS3BT +#ifdef USE_DS3 ds3bt_reset(); -#endif -#ifdef DS3USB ds3usb_reset(); #endif -#ifdef DS4BT +#ifdef USE_DS4 ds4bt_reset(); -#endif -#ifdef DS4USB ds4usb_reset(); #endif } diff --git a/modules/pademu/pademu_common.h b/modules/pademu/pademu_common.h index bdea52adb..e25dd4d3c 100644 --- a/modules/pademu/pademu_common.h +++ b/modules/pademu/pademu_common.h @@ -7,7 +7,7 @@ #define USB_PROTOCOL_BLUETOOTH_PROG 0x01 #define SONY_VID 0x12ba // Sony -#define DS34_VID 0x054C // Sony Corporation +#define DS_VID 0x054C // Sony Corporation #define DS3_PID 0x0268 // PS3 Controller #define DS4_PID 0x05C4 // PS4 Controller #define DS4_PID_SLIM 0x09CC // PS4 Slim Controller