| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2019-2024, Jacques Gagnon | ||
| 3 | * SPDX-License-Identifier: Apache-2.0 | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <esp_timer.h> | ||
| 8 | #include "bluetooth/host.h" | ||
| 9 | #include "ps3.h" | ||
| 10 | |||
| 11 | static const uint8_t bt_init_magic[] = { | ||
| 12 | 0x42, 0x03, 0x00, 0x00 | ||
| 13 | }; | ||
| 14 | |||
| 15 | static const uint8_t ps3_config[] = { | ||
| 16 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 17 | 0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, | ||
| 18 | 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, | ||
| 19 | 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, | ||
| 20 | 0x00, 0x00, 0x00 | ||
| 21 | }; | ||
| 22 | |||
| 23 | 2 | static void bt_hid_cmd_ps3_bt_init(struct bt_dev *device) { | |
| 24 | 2 | struct bt_hidp_ps3_bt_init *bt_init = (struct bt_hidp_ps3_bt_init *)bt_hci_pkt_tmp.hidp_data; | |
| 25 | |||
| 26 | 2 | memcpy((void *)bt_init, bt_init_magic, sizeof(*bt_init)); | |
| 27 | |||
| 28 | 2 | bt_hid_cmd(device->acl_handle, device->ctrl_chan.dcid, BT_HIDP_SET_FE, BT_HIDP_PS3_BT_INIT, sizeof(*bt_init)); | |
| 29 | 2 | } | |
| 30 | |||
| 31 | 2 | static void bt_hid_ps3_init_callback(void *arg) { | |
| 32 | 2 | struct bt_dev *device = (struct bt_dev *)arg; | |
| 33 | 2 | struct bt_data *bt_data = &bt_adapter.data[device->ids.id]; | |
| 34 | |||
| 35 | 2 | printf("# %s\n", __FUNCTION__); | |
| 36 | |||
| 37 | 2 | esp_timer_delete(device->timer_hdl); | |
| 38 | 2 | device->timer_hdl = NULL; | |
| 39 | 2 | bt_hid_cmd_ps3_set_conf(device, bt_data->base.output); | |
| 40 | |||
| 41 | 2 | atomic_set_bit(&device->flags, BT_DEV_HID_INIT_DONE); | |
| 42 | 2 | } | |
| 43 | |||
| 44 | 2 | void bt_hid_cmd_ps3_set_conf(struct bt_dev *device, void *report) { | |
| 45 | 2 | struct bt_hidp_ps3_set_conf *set_conf = (struct bt_hidp_ps3_set_conf *)bt_hci_pkt_tmp.hidp_data; | |
| 46 | 2 | memcpy((void *)set_conf, report, sizeof(*set_conf)); | |
| 47 | 2 | bt_hid_cmd(device->acl_handle, device->ctrl_chan.dcid, BT_HIDP_SET_OUT, BT_HIDP_PS3_SET_CONF, sizeof(*set_conf)); | |
| 48 | 2 | } | |
| 49 | |||
| 50 | 2 | void bt_hid_ps3_init(struct bt_dev *device) { | |
| 51 | 2 | struct bt_data *bt_data = &bt_adapter.data[device->ids.id]; | |
| 52 | 2 | struct bt_hidp_ps3_set_conf *set_conf = (struct bt_hidp_ps3_set_conf *)bt_data->base.output; | |
| 53 | 2 | printf("# %s\n", __FUNCTION__); | |
| 54 | |||
| 55 | 2 | memcpy((void *)set_conf, ps3_config, sizeof(ps3_config)); | |
| 56 | 2 | set_conf->leds = (bt_hid_led_dev_id_map[device->ids.out_idx] << 1); | |
| 57 | |||
| 58 | /* PS3 ctrl not yet ready to RX config, delay 20ms */ | ||
| 59 | 2 | const esp_timer_create_args_t ps3_timer_args = { | |
| 60 | .callback = &bt_hid_ps3_init_callback, | ||
| 61 | .arg = (void *)device, | ||
| 62 | .name = "ps3_init_timer" | ||
| 63 | }; | ||
| 64 | 2 | esp_timer_create(&ps3_timer_args, (esp_timer_handle_t *)&device->timer_hdl); | |
| 65 | 2 | esp_timer_start_once(device->timer_hdl, 1000000); | |
| 66 | |||
| 67 | 2 | bt_hid_cmd_ps3_bt_init(device); | |
| 68 | 2 | } | |
| 69 | |||
| 70 | 28 | void bt_hid_ps3_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint32_t len) { | |
| 71 | 28 | uint32_t hidp_data_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE | |
| 72 | + sizeof(struct bt_l2cap_hdr) + sizeof(struct bt_hidp_hdr)); | ||
| 73 | |||
| 74 |
1/2✓ Branch 0 (2→3) taken 28 times.
✗ Branch 1 (2→6) not taken.
|
28 | switch (bt_hci_acl_pkt->sig_hdr.code) { |
| 75 | 28 | case BT_HIDP_DATA_IN: | |
| 76 |
1/2✓ Branch 0 (3→4) taken 28 times.
✗ Branch 1 (3→6) not taken.
|
28 | switch (bt_hci_acl_pkt->hidp_hdr.protocol) { |
| 77 | 28 | case BT_HIDP_PS3_STATUS: | |
| 78 | #ifdef CONFIG_BLUERETRO_ADAPTER_RUMBLE_TEST | ||
| 79 | struct bt_hidp_ps3_set_conf rumble; | ||
| 80 | memcpy(&rumble, ps3_config, sizeof(rumble)); | ||
| 81 | if (bt_hci_acl_pkt->hidp_data[17] || bt_hci_acl_pkt->hidp_data[18]) { | ||
| 82 | rumble.r_rumble_pow = 0x01; | ||
| 83 | } | ||
| 84 | if (bt_hci_acl_pkt->hidp_data[17]) { | ||
| 85 | rumble.l_rumble_pow = bt_hci_acl_pkt->hidp_data[17]; | ||
| 86 | rumble.l_rumble_len = 0xFF; | ||
| 87 | } | ||
| 88 | if (bt_hci_acl_pkt->hidp_data[18]) { | ||
| 89 | rumble.r_rumble_len = 0xFF; | ||
| 90 | } | ||
| 91 | bt_hid_cmd_ps3_set_conf(device, &rumble); | ||
| 92 | #else | ||
| 93 |
1/2✓ Branch 0 (4→5) taken 28 times.
✗ Branch 1 (4→6) not taken.
|
28 | if (bt_hci_acl_pkt->hidp_data[0] != 0xFF) { |
| 94 | 28 | bt_host_bridge(device, bt_hci_acl_pkt->hidp_hdr.protocol, bt_hci_acl_pkt->hidp_data, hidp_data_len); | |
| 95 | } | ||
| 96 | #endif | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | 28 | } | |
| 102 |