| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2019-2025, 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 "bluetooth/hci.h" | ||
| 10 | #include "tools/util.h" | ||
| 11 | #include "tests/cmds.h" | ||
| 12 | #include "bluetooth/mon.h" | ||
| 13 | #include "sw.h" | ||
| 14 | |||
| 15 | //#define SW_DISABLE_SHIP_EN | ||
| 16 | //#define SW_SET_NATIVE_EN | ||
| 17 | //#define SW_TRIGGER_TIME_EN | ||
| 18 | //#define SW_ENABLE_IMU_EN | ||
| 19 | //#define SW_SET_MCU_CFG_EN | ||
| 20 | #define SW_INIT_STATE_RETRY_MAX 10 | ||
| 21 | |||
| 22 | enum { | ||
| 23 | SW_INIT_STATE_READ_INFO = 0, | ||
| 24 | #ifdef SW_DISABLE_SHIP_EN | ||
| 25 | SW_INIT_STATE_DISABLE_SHIP, | ||
| 26 | #endif | ||
| 27 | SW_INIT_STATE_READ_CALIB, | ||
| 28 | #ifdef SW_SET_NATIVE_EN | ||
| 29 | SW_INIT_STATE_SET_NATIVE, | ||
| 30 | #endif | ||
| 31 | #ifdef SW_TRIGGER_TIME_EN | ||
| 32 | SW_INIT_STATE_TRIGGER_TIME, | ||
| 33 | #endif | ||
| 34 | #ifdef SW_ENABLE_IMU_EN | ||
| 35 | SW_INIT_STATE_ENABLE_IMU, | ||
| 36 | #endif | ||
| 37 | SW_INIT_STATE_EN_RUMBLE, | ||
| 38 | #ifdef SW_SET_MCU_CFG_EN | ||
| 39 | SW_INIT_STATE_SET_MCU_CFG, | ||
| 40 | #endif | ||
| 41 | SW_INIT_STATE_SET_LED, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static uint8_t calib_idx[][3] = { | ||
| 45 | {2, 1, 0}, | ||
| 46 | {1, 0, 2}, | ||
| 47 | }; | ||
| 48 | static struct bt_hid_sw_ctrl_calib calib[BT_MAX_DEV] = {0}; | ||
| 49 | |||
| 50 | 14 | static void bt_hid_sw_set_calib(struct bt_hid_sw_ctrl_calib *calib, uint8_t *data, uint8_t stick, uint8_t idx) { | |
| 51 | 14 | calib->sticks[stick].axes[0].val[calib_idx[idx][0]] = ((data[1] << 8) & 0xF00) | data[0]; | |
| 52 | 14 | calib->sticks[stick].axes[1].val[calib_idx[idx][0]] = (data[2] << 4) | (data[1] >> 4); | |
| 53 | 14 | calib->sticks[stick].axes[0].val[calib_idx[idx][1]] = ((data[4] << 8) & 0xF00) | data[3]; | |
| 54 | 14 | calib->sticks[stick].axes[1].val[calib_idx[idx][1]] = (data[5] << 4) | (data[4] >> 4); | |
| 55 | 14 | calib->sticks[stick].axes[0].val[calib_idx[idx][2]] = ((data[7] << 8) & 0xF00) | data[6]; | |
| 56 | 14 | calib->sticks[stick].axes[1].val[calib_idx[idx][2]] = (data[8] << 4) | (data[7] >> 4); | |
| 57 | 14 | } | |
| 58 | |||
| 59 | 10 | static void bt_hid_sw_print_calib(struct bt_hid_sw_ctrl_calib *calib) { | |
| 60 | 10 | TESTS_CMDS_LOG("\"calib_data\": {"); | |
| 61 | 10 | TESTS_CMDS_LOG("\"rel_min\": [%u, %u, %u, %u], ", calib->sticks[0].axes[0].rel_min, calib->sticks[0].axes[1].rel_min, | |
| 62 | calib->sticks[1].axes[0].rel_min, calib->sticks[1].axes[1].rel_min); | ||
| 63 | 10 | TESTS_CMDS_LOG("\"rel_max\": [%u, %u, %u, %u], ", calib->sticks[0].axes[0].rel_max, calib->sticks[0].axes[1].rel_max, | |
| 64 | calib->sticks[1].axes[0].rel_max, calib->sticks[1].axes[1].rel_max); | ||
| 65 | 10 | TESTS_CMDS_LOG("\"neutral\": [%u, %u, %u, %u], ", calib->sticks[0].axes[0].neutral, calib->sticks[0].axes[1].neutral, | |
| 66 | calib->sticks[1].axes[0].neutral, calib->sticks[1].axes[1].neutral); | ||
| 67 | 10 | TESTS_CMDS_LOG("\"deadzone\": [%u, %u, %u, %u]},\n", calib->sticks[0].deadzone, calib->sticks[0].deadzone, | |
| 68 | calib->sticks[1].deadzone, calib->sticks[1].deadzone); | ||
| 69 | 10 | printf("rel_min LX %03X RX %03X\n", calib->sticks[0].axes[0].rel_min, calib->sticks[1].axes[0].rel_min); | |
| 70 | 10 | printf("neutral LX %03X RX %03X\n", calib->sticks[0].axes[0].neutral, calib->sticks[1].axes[0].neutral); | |
| 71 | 10 | printf("rel_max LX %03X RX %03X\n", calib->sticks[0].axes[0].rel_max, calib->sticks[1].axes[0].rel_max); | |
| 72 | 10 | printf("rel_min LY %03X RY %03X\n", calib->sticks[0].axes[1].rel_min, calib->sticks[1].axes[1].rel_min); | |
| 73 | 10 | printf("neutral LY %03X RY %03X\n", calib->sticks[0].axes[1].neutral, calib->sticks[1].axes[1].neutral); | |
| 74 | 10 | printf("rel_max LY %03X RY %03X\n", calib->sticks[0].axes[1].rel_max, calib->sticks[1].axes[1].rel_max); | |
| 75 | 10 | printf(" LD %03X RD %03X\n", calib->sticks[0].deadzone, calib->sticks[1].deadzone); | |
| 76 | 10 | bt_mon_log(true, "rel_min LX %03X RX %03X\n", calib->sticks[0].axes[0].rel_min, calib->sticks[1].axes[0].rel_min); | |
| 77 | 10 | bt_mon_log(true, "neutral LX %03X RX %03X\n", calib->sticks[0].axes[0].neutral, calib->sticks[1].axes[0].neutral); | |
| 78 | 10 | bt_mon_log(true, "rel_max LX %03X RX %03X\n", calib->sticks[0].axes[0].rel_max, calib->sticks[1].axes[0].rel_max); | |
| 79 | 10 | bt_mon_log(true, "rel_min LY %03X RY %03X\n", calib->sticks[0].axes[1].rel_min, calib->sticks[1].axes[1].rel_min); | |
| 80 | 10 | bt_mon_log(true, "neutral LY %03X RY %03X\n", calib->sticks[0].axes[1].neutral, calib->sticks[1].axes[1].neutral); | |
| 81 | 10 | bt_mon_log(true, "rel_max LY %03X RY %03X\n", calib->sticks[0].axes[1].rel_max, calib->sticks[1].axes[1].rel_max); | |
| 82 | 10 | bt_mon_log(true, " LD %03X RD %03X\n", calib->sticks[0].deadzone, calib->sticks[1].deadzone); | |
| 83 | 10 | } | |
| 84 | |||
| 85 | 113 | void bt_hid_cmd_sw_set_conf(struct bt_dev *device, void *report) { | |
| 86 | 113 | struct bt_hidp_sw_conf *sw_conf = (struct bt_hidp_sw_conf *)bt_hci_pkt_tmp.hidp_data; | |
| 87 | 113 | uint8_t protocol = BT_HIDP_SW_SET_CONF; | |
| 88 | 113 | uint16_t len = sizeof(struct bt_hidp_sw_conf); | |
| 89 | |||
| 90 | 113 | memcpy((void *)sw_conf, report, sizeof(*sw_conf)); | |
| 91 | 113 | sw_conf->tid = device->tid++; | |
| 92 | 113 | sw_conf->tid &= 0xF; | |
| 93 | |||
| 94 | |||
| 95 | /* 8bitdo wont rumble w/ set_conf... */ | ||
| 96 |
2/2✓ Branch 0 (3→4) taken 11 times.
✓ Branch 1 (3→5) taken 102 times.
|
113 | if (((uint8_t *)report)[127] == FB_TYPE_RUMBLE) { |
| 97 | 11 | protocol = BT_HIDP_SW_SET_RUMBLE; | |
| 98 | 11 | len = sizeof(struct bt_hidp_sw_rumble); | |
| 99 | } | ||
| 100 | |||
| 101 | 113 | bt_hid_cmd(device->acl_handle, device->intr_chan.dcid, BT_HIDP_DATA_OUT, protocol, len); | |
| 102 | 113 | } | |
| 103 | |||
| 104 | 42 | void bt_hid_sw_get_calib(int32_t dev_id, struct bt_hid_sw_ctrl_calib **cal) { | |
| 105 | 42 | struct bt_dev *device = NULL; | |
| 106 | 42 | bt_host_get_dev_from_id(dev_id, &device); | |
| 107 | |||
| 108 |
3/4✓ Branch 0 (3→4) taken 42 times.
✗ Branch 1 (3→7) not taken.
✓ Branch 2 (5→6) taken 10 times.
✓ Branch 3 (5→7) taken 32 times.
|
42 | if (device && atomic_test_bit(&device->flags, BT_DEV_CALIB_SET)) { |
| 109 | 10 | *cal = &calib[dev_id]; | |
| 110 | } | ||
| 111 | 42 | } | |
| 112 | |||
| 113 | 72 | static void bt_hid_sw_exec_next_state(struct bt_dev *device) { | |
| 114 |
2/4✓ Branch 0 (2→3) taken 48 times.
✓ Branch 1 (2→5) taken 24 times.
✗ Branch 2 (2→7) not taken.
✗ Branch 3 (2→9) not taken.
|
72 | switch(device->hid_state) { |
| 115 | 48 | case SW_INIT_STATE_READ_INFO: | |
| 116 | { | ||
| 117 | 48 | struct bt_hidp_sw_conf sw_conf = { | |
| 118 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 119 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 120 | .subcmd = BT_HIDP_SW_SUBCMD_READ_INFO, | ||
| 121 | }; | ||
| 122 | 48 | device->tid = 0; | |
| 123 | 48 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 124 | 48 | break; | |
| 125 | } | ||
| 126 | #ifdef SW_DISABLE_SHIP_EN | ||
| 127 | case SW_INIT_STATE_DISABLE_SHIP: | ||
| 128 | { | ||
| 129 | struct bt_hidp_sw_conf sw_conf = { | ||
| 130 | .subcmd = BT_HIDP_SW_SUBCMD_DISABLE_SHIP, | ||
| 131 | }; | ||
| 132 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | #endif | ||
| 136 | 24 | case SW_INIT_STATE_READ_CALIB: | |
| 137 | { | ||
| 138 | 24 | struct bt_hidp_sw_conf sw_conf = { | |
| 139 | .subcmd = BT_HIDP_SW_SUBCMD_READ_SPI, | ||
| 140 | .addr = 0x603D, | ||
| 141 | .len = 18, | ||
| 142 | }; | ||
| 143 | 24 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 144 | 24 | break; | |
| 145 | } | ||
| 146 | #ifdef SW_SET_NATIVE_EN | ||
| 147 | case SW_INIT_STATE_SET_NATIVE: | ||
| 148 | { | ||
| 149 | struct bt_hidp_sw_conf sw_conf = { | ||
| 150 | .subcmd = BT_HIDP_SW_SUBCMD_SET_REP_MODE, | ||
| 151 | .subcmd_data[0] = BT_HIDP_SW_STATUS_NATIVE, | ||
| 152 | }; | ||
| 153 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | #endif | ||
| 157 | #ifdef SW_TRIGGER_TIME_EN | ||
| 158 | case SW_INIT_STATE_TRIGGER_TIME: | ||
| 159 | { | ||
| 160 | struct bt_hidp_sw_conf sw_conf = { | ||
| 161 | .subcmd = BT_HIDP_SW_SUBCMD_TRIGGER_TIME, | ||
| 162 | }; | ||
| 163 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | #endif | ||
| 167 | #ifdef SW_ENABLE_IMU_EN | ||
| 168 | case SW_INIT_STATE_ENABLE_IMU: | ||
| 169 | { | ||
| 170 | struct bt_hidp_sw_conf sw_conf = { | ||
| 171 | .subcmd = BT_HIDP_SW_SUBCMD_ENABLE_IMU, | ||
| 172 | .subcmd_data[0] = 0x01, | ||
| 173 | }; | ||
| 174 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | ||
| 175 | break; | ||
| 176 | } | ||
| 177 | #endif | ||
| 178 | ✗ | case SW_INIT_STATE_EN_RUMBLE: | |
| 179 | { | ||
| 180 | ✗ | struct bt_hidp_sw_conf sw_conf = { | |
| 181 | .subcmd = BT_HIDP_SW_SUBCMD_EN_RUMBLE, | ||
| 182 | .subcmd_data[0] = 0x01, | ||
| 183 | }; | ||
| 184 | ✗ | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 185 | ✗ | break; | |
| 186 | } | ||
| 187 | #ifdef SW_SET_MCU_CFG_EN | ||
| 188 | case SW_INIT_STATE_SET_MCU_CFG: | ||
| 189 | { | ||
| 190 | struct bt_hidp_sw_conf sw_conf = { | ||
| 191 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 192 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 193 | .subcmd = BT_HIDP_SW_SUBCMD_SET_MCU_CFG, | ||
| 194 | .subcmd_data[0] = 0x21, | ||
| 195 | }; | ||
| 196 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | #endif | ||
| 200 | ✗ | case SW_INIT_STATE_SET_LED: | |
| 201 | default: | ||
| 202 | { | ||
| 203 | ✗ | struct bt_hidp_sw_conf sw_conf = { | |
| 204 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 205 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 206 | .subcmd = BT_HIDP_SW_SUBCMD_SET_LED, | ||
| 207 | ✗ | .subcmd_data[0] = bt_hid_led_dev_id_map[device->ids.out_idx], | |
| 208 | }; | ||
| 209 | ✗ | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 210 | ✗ | break; | |
| 211 | } | ||
| 212 | } | ||
| 213 | 72 | } | |
| 214 | |||
| 215 | 62 | static void bt_hid_sw_init_callback(void *arg) { | |
| 216 | 62 | struct bt_dev *device = (struct bt_dev *)arg; | |
| 217 | |||
| 218 | 62 | printf("# %s\n", __FUNCTION__); | |
| 219 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→8) taken 62 times.
|
62 | if (device->hid_retry_cnt++ > SW_INIT_STATE_RETRY_MAX) { |
| 220 | ✗ | if (device->hid_state == SW_INIT_STATE_SET_LED) { | |
| 221 | ✗ | esp_timer_delete(device->timer_hdl); | |
| 222 | ✗ | device->timer_hdl = NULL; | |
| 223 | ✗ | return; | |
| 224 | } | ||
| 225 | ✗ | device->hid_state++; | |
| 226 | ✗ | device->hid_retry_cnt = 0; | |
| 227 | } | ||
| 228 | 62 | bt_hid_sw_exec_next_state(device); | |
| 229 | |||
| 230 | 62 | esp_timer_start_once(device->timer_hdl, 100000); | |
| 231 | |||
| 232 | 62 | atomic_set_bit(&device->flags, BT_DEV_HID_INIT_DONE); | |
| 233 | } | ||
| 234 | |||
| 235 | 42 | void bt_hid_sw_init(struct bt_dev *device) { | |
| 236 | #ifndef CONFIG_BLUERETRO_TEST_FALLBACK_REPORT | ||
| 237 | 42 | struct bt_data *bt_data = &bt_adapter.data[device->ids.id]; | |
| 238 | 42 | struct bt_hidp_sw_conf *set_conf = (struct bt_hidp_sw_conf *)bt_data->base.output; | |
| 239 | |||
| 240 | /* Init output data for Rumble/LED feedback */ | ||
| 241 | 42 | set_conf->l_lra.val = BT_HIDP_SW_LRA_IDLE; | |
| 242 | 42 | set_conf->r_lra.val = BT_HIDP_SW_LRA_IDLE; | |
| 243 | 42 | set_conf->subcmd = BT_HIDP_SW_SUBCMD_SET_LED; | |
| 244 | 42 | set_conf->subcmd_data[0] = bt_hid_led_dev_id_map[bt_data->base.pids->out_idx]; | |
| 245 | |||
| 246 | 42 | const esp_timer_create_args_t sw_timer_args = { | |
| 247 | .callback = &bt_hid_sw_init_callback, | ||
| 248 | .arg = (void *)device, | ||
| 249 | .name = "sw_init_timer" | ||
| 250 | }; | ||
| 251 | 42 | struct bt_hid_sw_ctrl_calib *dev_calib = &calib[device->ids.id]; | |
| 252 | 42 | printf("# %s\n", __FUNCTION__); | |
| 253 | |||
| 254 | 42 | memset((uint8_t *)dev_calib, 0, sizeof(*dev_calib)); | |
| 255 | |||
| 256 | 42 | esp_timer_create(&sw_timer_args, (esp_timer_handle_t *)&device->timer_hdl); | |
| 257 | 42 | esp_timer_start_once(device->timer_hdl, 300000); | |
| 258 | #endif | ||
| 259 | 42 | } | |
| 260 | |||
| 261 | 784 | void bt_hid_sw_hdlr(struct bt_dev *device, struct bt_hci_pkt *bt_hci_acl_pkt, uint32_t len) { | |
| 262 | 784 | uint32_t hidp_data_len = len - (BT_HCI_H4_HDR_SIZE + BT_HCI_ACL_HDR_SIZE | |
| 263 | + sizeof(struct bt_l2cap_hdr) + sizeof(struct bt_hidp_hdr)); | ||
| 264 | |||
| 265 |
1/2✓ Branch 0 (2→3) taken 784 times.
✗ Branch 1 (2→79) not taken.
|
784 | switch (bt_hci_acl_pkt->sig_hdr.code) { |
| 266 | 784 | case BT_HIDP_DATA_IN: | |
| 267 |
3/4✓ Branch 0 (3→4) taken 40 times.
✓ Branch 1 (3→69) taken 463 times.
✓ Branch 2 (3→74) taken 281 times.
✗ Branch 3 (3→79) not taken.
|
784 | switch (bt_hci_acl_pkt->hidp_hdr.protocol) { |
| 268 | 40 | case BT_HIDP_SW_SUBCMD_ACK: | |
| 269 | { | ||
| 270 | 40 | struct bt_hidp_sw_subcmd_ack *ack = (struct bt_hidp_sw_subcmd_ack *)bt_hci_acl_pkt->hidp_data; | |
| 271 |
1/10✗ Branch 0 (4→5) not taken.
✗ Branch 1 (4→9) not taken.
✗ Branch 2 (4→13) not taken.
✗ Branch 3 (4→17) not taken.
✓ Branch 4 (4→21) taken 40 times.
✗ Branch 5 (4→55) not taken.
✗ Branch 6 (4→59) not taken.
✗ Branch 7 (4→63) not taken.
✗ Branch 8 (4→67) not taken.
✗ Branch 9 (4→79) not taken.
|
40 | switch(ack->subcmd) { |
| 272 | ✗ | case BT_HIDP_SW_SUBCMD_READ_INFO: | |
| 273 | { | ||
| 274 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 275 | ✗ | printf("# BT_HIDP_SW_SUBCMD_READ_INFO\n"); | |
| 276 | ✗ | device->hid_state++; | |
| 277 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 278 | ✗ | break; | |
| 279 | } | ||
| 280 | ✗ | case BT_HIDP_SW_SUBCMD_SET_REP_MODE: | |
| 281 | { | ||
| 282 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 283 | ✗ | printf("# BT_HIDP_SW_SUBCMD_SET_REP_MODE\n"); | |
| 284 | ✗ | device->hid_state++; | |
| 285 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 286 | ✗ | break; | |
| 287 | } | ||
| 288 | ✗ | case BT_HIDP_SW_SUBCMD_TRIGGER_TIME: | |
| 289 | { | ||
| 290 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 291 | ✗ | printf("# BT_HIDP_SW_SUBCMD_TRIGGER_TIME\n"); | |
| 292 | ✗ | device->hid_state++; | |
| 293 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 294 | ✗ | break; | |
| 295 | } | ||
| 296 | ✗ | case BT_HIDP_SW_SUBCMD_DISABLE_SHIP: | |
| 297 | { | ||
| 298 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 299 | ✗ | printf("# BT_HIDP_SW_SUBCMD_DISABLE_SHIP\n"); | |
| 300 | ✗ | device->hid_state++; | |
| 301 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 302 | ✗ | break; | |
| 303 | } | ||
| 304 | 40 | case BT_HIDP_SW_SUBCMD_READ_SPI: | |
| 305 | { | ||
| 306 | 40 | esp_timer_restart(device->timer_hdl, 100000); | |
| 307 | 40 | printf("# BT_HIDP_SW_SUBCMD_READ_SPI 0x%04X\n", ack->addr); | |
| 308 |
4/5✓ Branch 0 (23→24) taken 10 times.
✓ Branch 1 (23→35) taken 10 times.
✓ Branch 2 (23→38) taken 10 times.
✓ Branch 3 (23→41) taken 10 times.
✗ Branch 4 (23→79) not taken.
|
40 | switch (ack->addr) { |
| 309 | 10 | case 0x603D: | |
| 310 | { | ||
| 311 | 10 | struct bt_hid_sw_ctrl_calib *dev_calib = &calib[device->ids.id]; | |
| 312 | 10 | uint8_t *data = ack->data; | |
| 313 | 10 | uint8_t idx = 0; | |
| 314 | |||
| 315 | 10 | data_dump(ack->data, ack->len); | |
| 316 | |||
| 317 |
2/2✓ Branch 0 (25→26) taken 1 times.
✓ Branch 1 (25→27) taken 9 times.
|
10 | if (device->ids.subtype == BT_SW_RIGHT_JOYCON) { |
| 318 | 1 | data += 9; | |
| 319 | 1 | idx++; | |
| 320 | } | ||
| 321 |
2/2✓ Branch 0 (32→28) taken 14 times.
✓ Branch 1 (32→33) taken 4 times.
|
18 | for (uint32_t i = 0; i < 2; i++, idx++) { |
| 322 |
2/2✓ Branch 0 (28→29) taken 8 times.
✓ Branch 1 (28→30) taken 6 times.
|
14 | if (data[0] != 0xFF) { |
| 323 | 8 | bt_hid_sw_set_calib(dev_calib, data, i, idx); | |
| 324 | } | ||
| 325 |
2/2✓ Branch 0 (30→31) taken 8 times.
✓ Branch 1 (30→33) taken 6 times.
|
14 | if (device->ids.subtype == BT_SUBTYPE_DEFAULT) { |
| 326 | 8 | data += 9; | |
| 327 | } | ||
| 328 | else { | ||
| 329 | break; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | 10 | struct bt_hidp_sw_conf sw_conf = { | |
| 334 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 335 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 336 | .subcmd = BT_HIDP_SW_SUBCMD_READ_SPI, | ||
| 337 | .addr = 0x6086, | ||
| 338 | .len = 18, | ||
| 339 | }; | ||
| 340 | 10 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 341 | 10 | break; | |
| 342 | } | ||
| 343 | 10 | case 0x6086: | |
| 344 | { | ||
| 345 | 10 | struct bt_hid_sw_ctrl_calib *dev_calib = &calib[device->ids.id]; | |
| 346 | 10 | uint8_t *data = ack->data; | |
| 347 | 10 | data_dump(ack->data, ack->len); | |
| 348 | |||
| 349 | 10 | dev_calib->sticks[0].deadzone = ((data[4] << 8) & 0xF00) | data[3]; | |
| 350 | |||
| 351 | 10 | struct bt_hidp_sw_conf sw_conf = { | |
| 352 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 353 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 354 | .subcmd = BT_HIDP_SW_SUBCMD_READ_SPI, | ||
| 355 | .addr = 0x6098, | ||
| 356 | .len = 18, | ||
| 357 | }; | ||
| 358 | 10 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 359 | 10 | break; | |
| 360 | } | ||
| 361 | 10 | case 0x6098: | |
| 362 | { | ||
| 363 | 10 | struct bt_hid_sw_ctrl_calib *dev_calib = &calib[device->ids.id]; | |
| 364 | 10 | uint8_t *data = ack->data; | |
| 365 | 10 | data_dump(ack->data, ack->len); | |
| 366 | |||
| 367 | 10 | dev_calib->sticks[1].deadzone = ((data[4] << 8) & 0xF00) | data[3]; | |
| 368 | |||
| 369 | 10 | struct bt_hidp_sw_conf sw_conf = { | |
| 370 | .l_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 371 | .r_lra.val = BT_HIDP_SW_LRA_IDLE, | ||
| 372 | .subcmd = BT_HIDP_SW_SUBCMD_READ_SPI, | ||
| 373 | .addr = 0x8010, | ||
| 374 | .len = 22, | ||
| 375 | }; | ||
| 376 | 10 | bt_hid_cmd_sw_set_conf(device, (void *)&sw_conf); | |
| 377 | 10 | break; | |
| 378 | } | ||
| 379 | 10 | case 0x8010: | |
| 380 | { | ||
| 381 | 10 | struct bt_hid_sw_ctrl_calib *dev_calib = &calib[device->ids.id]; | |
| 382 | 10 | uint8_t *data = ack->data; | |
| 383 | 10 | uint8_t idx = 0; | |
| 384 | |||
| 385 | 10 | data_dump(ack->data, ack->len); | |
| 386 | |||
| 387 |
2/2✓ Branch 0 (42→43) taken 1 times.
✓ Branch 1 (42→44) taken 9 times.
|
10 | if (device->ids.subtype == BT_SW_RIGHT_JOYCON) { |
| 388 | 1 | data += 11; | |
| 389 | 1 | idx++; | |
| 390 | } | ||
| 391 |
2/2✓ Branch 0 (49→45) taken 14 times.
✓ Branch 1 (49→50) taken 4 times.
|
18 | for (uint32_t i = 0; i < 2; i++, idx++) { |
| 392 |
2/2✓ Branch 0 (45→46) taken 6 times.
✓ Branch 1 (45→47) taken 8 times.
|
14 | if (data[0] != 0xFF) { |
| 393 | 6 | bt_hid_sw_set_calib(dev_calib, data + 2, i, idx); | |
| 394 | } | ||
| 395 |
2/2✓ Branch 0 (47→48) taken 8 times.
✓ Branch 1 (47→50) taken 6 times.
|
14 | if (device->ids.subtype == BT_SUBTYPE_DEFAULT) { |
| 396 | 8 | data += 11; | |
| 397 | } | ||
| 398 | else { | ||
| 399 | break; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | 10 | bt_hid_sw_print_calib(dev_calib); | |
| 404 | 10 | atomic_set_bit(&device->flags, BT_DEV_CALIB_SET); | |
| 405 | /* Force reinit once calib available */ | ||
| 406 | 10 | bt_type_update(device->ids.id, BT_SW, device->ids.subtype); | |
| 407 | 10 | device->hid_state++; | |
| 408 | 10 | bt_hid_sw_exec_next_state(device); | |
| 409 | 10 | break; | |
| 410 | } | ||
| 411 | } | ||
| 412 | break; | ||
| 413 | } | ||
| 414 | ✗ | case BT_HIDP_SW_SUBCMD_SET_MCU_CFG: | |
| 415 | { | ||
| 416 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 417 | ✗ | printf("# BT_HIDP_SW_SUBCMD_SET_MCU_CFG\n"); | |
| 418 | ✗ | device->hid_state++; | |
| 419 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 420 | ✗ | break; | |
| 421 | } | ||
| 422 | ✗ | case BT_HIDP_SW_SUBCMD_ENABLE_IMU: | |
| 423 | { | ||
| 424 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 425 | ✗ | printf("# BT_HIDP_SW_SUBCMD_ENABLE_IMU\n"); | |
| 426 | ✗ | device->hid_state++; | |
| 427 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 428 | ✗ | break; | |
| 429 | } | ||
| 430 | ✗ | case BT_HIDP_SW_SUBCMD_EN_RUMBLE: | |
| 431 | { | ||
| 432 | ✗ | esp_timer_restart(device->timer_hdl, 100000); | |
| 433 | ✗ | printf("# BT_HIDP_SW_SUBCMD_EN_RUMBLE\n"); | |
| 434 | ✗ | device->hid_state++; | |
| 435 | ✗ | bt_hid_sw_exec_next_state(device); | |
| 436 | ✗ | break; | |
| 437 | } | ||
| 438 | ✗ | case BT_HIDP_SW_SUBCMD_SET_LED: | |
| 439 | { | ||
| 440 | ✗ | esp_timer_delete(device->timer_hdl); | |
| 441 | ✗ | device->timer_hdl = NULL; | |
| 442 | ✗ | break; | |
| 443 | } | ||
| 444 | } | ||
| 445 | break; | ||
| 446 | } | ||
| 447 | 463 | case BT_HIDP_SW_STATUS: | |
| 448 | { | ||
| 449 |
2/2✓ Branch 0 (69→70) taken 21 times.
✓ Branch 1 (69→72) taken 442 times.
|
463 | if (device->ids.report_type != BT_HIDP_SW_STATUS) { |
| 450 | 21 | bt_type_update(device->ids.id, BT_SW, device->ids.subtype); | |
| 451 | 21 | device->ids.report_type = BT_HIDP_SW_STATUS; | |
| 452 | 21 | printf("# %s: Report type change to %02lX\n", __FUNCTION__, device->ids.report_type); | |
| 453 | } | ||
| 454 | 463 | bt_host_bridge(device, bt_hci_acl_pkt->hidp_hdr.protocol, bt_hci_acl_pkt->hidp_data, hidp_data_len); | |
| 455 | 463 | break; | |
| 456 | } | ||
| 457 | 281 | case BT_HIDP_SW_STATUS_NATIVE: | |
| 458 | { | ||
| 459 |
2/2✓ Branch 0 (74→75) taken 21 times.
✓ Branch 1 (74→77) taken 260 times.
|
281 | if (device->ids.report_type != BT_HIDP_SW_STATUS_NATIVE) { |
| 460 | 21 | bt_type_update(device->ids.id, BT_SW, device->ids.subtype); | |
| 461 | 21 | device->ids.report_type = BT_HIDP_SW_STATUS_NATIVE; | |
| 462 | 21 | printf("# %s: Report type change to %02lX\n", __FUNCTION__, device->ids.report_type); | |
| 463 | } | ||
| 464 | 281 | bt_host_bridge(device, bt_hci_acl_pkt->hidp_hdr.protocol, bt_hci_acl_pkt->hidp_data, hidp_data_len); | |
| 465 | 281 | break; | |
| 466 | } | ||
| 467 | } | ||
| 468 | break; | ||
| 469 | } | ||
| 470 | 784 | } | |
| 471 |