| 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 <string.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <freertos/FreeRTOS.h> | ||
| 10 | #include <xtensa/hal.h> | ||
| 11 | #include <esp_heap_caps.h> | ||
| 12 | #include <esp_timer.h> | ||
| 13 | #include <esp32/rom/ets_sys.h> | ||
| 14 | #include "sdkconfig.h" | ||
| 15 | #include "queue_bss.h" | ||
| 16 | #include "zephyr/types.h" | ||
| 17 | #include "tools/util.h" | ||
| 18 | #include "config.h" | ||
| 19 | #include "adapter.h" | ||
| 20 | #include "adapter_debug.h" | ||
| 21 | #include "wired/wired.h" | ||
| 22 | #include "wireless/wireless.h" | ||
| 23 | #include "macro.h" | ||
| 24 | #include "bluetooth/host.h" | ||
| 25 | #include "tests/cmds.h" | ||
| 26 | |||
| 27 | const uint32_t hat_to_ld_btns[16] = { | ||
| 28 | BIT(PAD_LD_UP), BIT(PAD_LD_UP) | BIT(PAD_LD_RIGHT), BIT(PAD_LD_RIGHT), BIT(PAD_LD_DOWN) | BIT(PAD_LD_RIGHT), | ||
| 29 | BIT(PAD_LD_DOWN), BIT(PAD_LD_DOWN) | BIT(PAD_LD_LEFT), BIT(PAD_LD_LEFT), BIT(PAD_LD_UP) | BIT(PAD_LD_LEFT), | ||
| 30 | }; | ||
| 31 | |||
| 32 | const uint32_t generic_btns_mask[32] = { | ||
| 33 | BIT(PAD_LX_LEFT), BIT(PAD_LX_RIGHT), BIT(PAD_LY_DOWN), BIT(PAD_LY_UP), | ||
| 34 | BIT(PAD_RX_LEFT), BIT(PAD_RX_RIGHT), BIT(PAD_RY_DOWN), BIT(PAD_RY_UP), | ||
| 35 | BIT(PAD_LD_LEFT), BIT(PAD_LD_RIGHT), BIT(PAD_LD_DOWN), BIT(PAD_LD_UP), | ||
| 36 | BIT(PAD_RD_LEFT), BIT(PAD_RD_RIGHT), BIT(PAD_RD_DOWN), BIT(PAD_RD_UP), | ||
| 37 | BIT(PAD_RB_LEFT), BIT(PAD_RB_RIGHT), BIT(PAD_RB_DOWN), BIT(PAD_RB_UP), | ||
| 38 | BIT(PAD_MM), BIT(PAD_MS), BIT(PAD_MT), BIT(PAD_MQ), | ||
| 39 | BIT(PAD_LM), BIT(PAD_LS), BIT(PAD_LT), BIT(PAD_LJ), | ||
| 40 | BIT(PAD_RM), BIT(PAD_RS), BIT(PAD_RT), BIT(PAD_RJ), | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct wireless_ctrl *ctrl_input; | ||
| 44 | struct wired_ctrl *ctrl_output; | ||
| 45 | struct generic_fb fb_input; | ||
| 46 | struct bt_adapter bt_adapter = {0}; | ||
| 47 | struct wired_adapter wired_adapter = {0}; | ||
| 48 | static uint32_t adapter_out_mask[WIRED_MAX_DEV] = {0}; | ||
| 49 | static bool rumble_mute = false; | ||
| 50 | |||
| 51 | 209746 | static uint32_t btn_id_to_btn_idx(uint8_t btn_id) { | |
| 52 |
2/2✓ Branch 0 (2→3) taken 122686 times.
✓ Branch 1 (2→6) taken 87060 times.
|
209746 | if (btn_id < 32) { |
| 53 | return 0; | ||
| 54 | } | ||
| 55 |
2/2✓ Branch 0 (3→4) taken 80126 times.
✓ Branch 1 (3→6) taken 42560 times.
|
122686 | else if (btn_id >= 32 && btn_id < 64) { |
| 56 | return 1; | ||
| 57 | } | ||
| 58 |
2/2✓ Branch 0 (4→5) taken 37566 times.
✓ Branch 1 (4→6) taken 42560 times.
|
80126 | else if (btn_id >= 64 && btn_id < 96) { |
| 59 | return 2; | ||
| 60 | } | ||
| 61 | else { | ||
| 62 | 37566 | return 3; | |
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | 8832 | static uint32_t adapter_map_from_axis(struct map_cfg * map_cfg) { | |
| 67 | 8832 | uint32_t out_mask = BIT(map_cfg->dst_id); | |
| 68 | 8832 | struct wired_ctrl *out = &ctrl_output[map_cfg->dst_id]; | |
| 69 | 8832 | uint8_t src = map_cfg->src_btn; | |
| 70 | 8832 | uint8_t dst = map_cfg->dst_btn; | |
| 71 | 8832 | uint32_t dst_mask = BIT(dst & 0x1F); | |
| 72 | 8832 | uint32_t dst_btn_idx = btn_id_to_btn_idx(dst); | |
| 73 | 8832 | uint32_t src_axis_idx = btn_id_to_axis(src); | |
| 74 | 8832 | uint32_t dst_axis_idx = btn_id_to_axis(dst); | |
| 75 | |||
| 76 |
1/2✓ Branch 0 (2→3) taken 8832 times.
✗ Branch 1 (2→26) not taken.
|
8832 | if (src_axis_idx == AXIS_NONE) { |
| 77 | return 0; | ||
| 78 | } | ||
| 79 | |||
| 80 | /* Check if mapping dst exist in output */ | ||
| 81 |
2/2✓ Branch 0 (3→4) taken 8776 times.
✓ Branch 1 (3→25) taken 56 times.
|
8832 | if (dst_mask & out->mask[dst_btn_idx]) { |
| 82 | 8776 | int32_t abs_src_value = abs(ctrl_input->axes[src_axis_idx].value); | |
| 83 | 8776 | int32_t src_sign = btn_sign(ctrl_input->axes[src_axis_idx].meta->polarity, src); | |
| 84 | 8776 | int32_t sign_check = src_sign * ctrl_input->axes[src_axis_idx].value; | |
| 85 | |||
| 86 | /* Check if the srv value sign match the src mapping sign */ | ||
| 87 |
2/2✓ Branch 0 (4→5) taken 7948 times.
✓ Branch 1 (4→24) taken 828 times.
|
8776 | if (sign_check >= 0) { |
| 88 | /* Get proper abs_max base on sign and update max if current value is over */ | ||
| 89 | 7948 | int32_t src_abs_max; | |
| 90 |
2/2✓ Branch 0 (5→6) taken 4882 times.
✓ Branch 1 (5→9) taken 3066 times.
|
7948 | if (src_sign > 0) { |
| 91 |
2/2✓ Branch 0 (6→7) taken 148 times.
✓ Branch 1 (6→8) taken 4734 times.
|
4882 | if (abs_src_value > ctrl_input->axes[src_axis_idx].meta->abs_max) { |
| 92 | 148 | ctrl_input->axes[src_axis_idx].meta->abs_max = abs_src_value; | |
| 93 | } | ||
| 94 | 4882 | src_abs_max = ctrl_input->axes[src_axis_idx].meta->abs_max; | |
| 95 | } | ||
| 96 | else { | ||
| 97 |
2/2✓ Branch 0 (9→10) taken 120 times.
✓ Branch 1 (9→11) taken 2946 times.
|
3066 | if (abs_src_value > ctrl_input->axes[src_axis_idx].meta->abs_min) { |
| 98 | 120 | ctrl_input->axes[src_axis_idx].meta->abs_min = abs_src_value; | |
| 99 | } | ||
| 100 | 3066 | src_abs_max = ctrl_input->axes[src_axis_idx].meta->abs_min; | |
| 101 | } | ||
| 102 | |||
| 103 | /* Check if dst is an axis */ | ||
| 104 |
2/2✓ Branch 0 (12→13) taken 6996 times.
✓ Branch 1 (12→22) taken 952 times.
|
7948 | if (dst_mask & out->desc[dst_btn_idx]) { |
| 105 | /* Keep track of source axis type */ | ||
| 106 | 6996 | out->axes[dst_axis_idx].relative = ctrl_input->axes[src_axis_idx].meta->relative; | |
| 107 | /* Dst is an axis */ | ||
| 108 | 6996 | int32_t deadzone = (int32_t)(((float)map_cfg->perc_deadzone / 10000) * src_abs_max) + ctrl_input->axes[src_axis_idx].meta->deadzone; | |
| 109 | /* Check if axis over deadzone */ | ||
| 110 |
2/2✓ Branch 0 (13→14) taken 831 times.
✓ Branch 1 (13→24) taken 6165 times.
|
6996 | if (abs_src_value > deadzone) { |
| 111 | 831 | int32_t value = abs_src_value - deadzone; | |
| 112 | 831 | int32_t dst_sign = btn_sign(out->axes[dst_axis_idx].meta->polarity, dst); | |
| 113 |
2/2✓ Branch 0 (14→15) taken 404 times.
✓ Branch 1 (14→16) taken 427 times.
|
831 | int32_t dst_abs_max = (dst_sign > 0) ? out->axes[dst_axis_idx].meta->abs_max : out->axes[dst_axis_idx].meta->abs_min; |
| 114 | 831 | float scale, fvalue; | |
| 115 |
1/2✓ Branch 0 (17→18) taken 831 times.
✗ Branch 1 (17→19) not taken.
|
831 | switch (map_cfg->algo & 0xF) { |
| 116 | 831 | case LINEAR: | |
| 117 | 831 | scale = ((float)dst_abs_max / (src_abs_max - deadzone)) * (((float)map_cfg->perc_max) / 100); | |
| 118 | 831 | break; | |
| 119 | ✗ | default: | |
| 120 | ✗ | scale = ((float)map_cfg->perc_max) / 100; | |
| 121 | ✗ | break; | |
| 122 | |||
| 123 | } | ||
| 124 | 831 | fvalue = dst_sign * value * scale; | |
| 125 | 831 | value = (int32_t)fvalue; | |
| 126 | |||
| 127 |
2/2✓ Branch 0 (20→21) taken 661 times.
✓ Branch 1 (20→24) taken 170 times.
|
831 | if (abs(value) > abs(out->axes[dst_axis_idx].value)) { |
| 128 | 661 | out->axes[dst_axis_idx].value = value; | |
| 129 | 661 | out->axes[dst_axis_idx].cnt_mask = map_cfg->turbo; | |
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | else { | ||
| 134 | /* Dst is a button */ | ||
| 135 | 952 | int32_t threshold = (int32_t)(((float)map_cfg->perc_threshold / 100) * src_abs_max); | |
| 136 | /* Check if axis over threshold */ | ||
| 137 |
2/2✓ Branch 0 (22→23) taken 56 times.
✓ Branch 1 (22→24) taken 896 times.
|
952 | if (abs_src_value >= threshold) { |
| 138 | 56 | out->btns[dst_btn_idx].value |= dst_mask; | |
| 139 | 56 | out->btns[dst_btn_idx].cnt_mask[dst & 0x1F] = map_cfg->turbo; | |
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | /* Flag this dst for update */ | ||
| 144 | 8776 | out->map_mask[dst_btn_idx] |= dst_mask; | |
| 145 | } | ||
| 146 | |||
| 147 | return out_mask; | ||
| 148 | } | ||
| 149 | |||
| 150 | 34664 | static uint32_t adapter_map_from_btn(struct map_cfg * map_cfg, uint32_t src_mask, uint32_t src_btn_idx) { | |
| 151 | 34664 | uint32_t out_mask = BIT(map_cfg->dst_id); | |
| 152 | 34664 | struct wired_ctrl *out = &ctrl_output[map_cfg->dst_id]; | |
| 153 | 34664 | uint8_t dst = map_cfg->dst_btn; | |
| 154 | 34664 | uint32_t dst_mask = BIT(dst & 0x1F); | |
| 155 | 34664 | uint32_t dst_btn_idx = btn_id_to_btn_idx(dst); | |
| 156 | |||
| 157 | /* Check if mapping dst exist in output */ | ||
| 158 |
2/2✓ Branch 0 (2→3) taken 29532 times.
✓ Branch 1 (2→13) taken 5132 times.
|
34664 | if (dst_mask & out->mask[dst_btn_idx]) { |
| 159 | /* Check if button pressed */ | ||
| 160 |
2/2✓ Branch 0 (3→4) taken 2024 times.
✓ Branch 1 (3→12) taken 27508 times.
|
29532 | if (ctrl_input->btns[src_btn_idx].value & src_mask) { |
| 161 | /* Check if dst is an axis */ | ||
| 162 |
2/2✓ Branch 0 (4→5) taken 162 times.
✓ Branch 1 (4→11) taken 1862 times.
|
2024 | if (dst_mask & out->desc[dst_btn_idx]) { |
| 163 | /* Dst is an axis */ | ||
| 164 | 162 | uint32_t axis_id = btn_id_to_axis(dst); | |
| 165 | |||
| 166 |
1/2✓ Branch 0 (5→6) taken 162 times.
✗ Branch 1 (5→14) not taken.
|
162 | if (axis_id == AXIS_NONE) { |
| 167 | return 0; | ||
| 168 | } | ||
| 169 | else { | ||
| 170 | 162 | int32_t dst_sign = btn_sign(out->axes[axis_id].meta->polarity, dst); | |
| 171 |
2/2✓ Branch 0 (6→7) taken 134 times.
✓ Branch 1 (6→8) taken 28 times.
|
162 | int32_t dst_abs_max = (dst_sign > 0) ? out->axes[axis_id].meta->abs_max : out->axes[axis_id].meta->abs_min; |
| 172 | 162 | float fvalue = dst_sign * dst_abs_max * (((float)map_cfg->perc_max) / 100); | |
| 173 | 162 | int32_t value = (int32_t)fvalue; | |
| 174 | |||
| 175 |
2/2✓ Branch 0 (9→10) taken 154 times.
✓ Branch 1 (9→12) taken 8 times.
|
162 | if (abs(value) > abs(out->axes[axis_id].value)) { |
| 176 | 154 | out->axes[axis_id].value = value; | |
| 177 | 154 | out->axes[axis_id].cnt_mask = map_cfg->turbo; | |
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | else { | ||
| 182 | /* Dst is a button */ | ||
| 183 | 1862 | out->btns[dst_btn_idx].value |= dst_mask; | |
| 184 | 1862 | out->btns[dst_btn_idx].cnt_mask[dst & 0x1F] = map_cfg->turbo; | |
| 185 | } | ||
| 186 | } | ||
| 187 | /* Flag this dst for update */ | ||
| 188 | 29532 | out->map_mask[dst_btn_idx] |= dst_mask; | |
| 189 | } | ||
| 190 | |||
| 191 | return out_mask; | ||
| 192 | } | ||
| 193 | |||
| 194 | 1330 | static uint32_t adapter_mapping(struct in_cfg * in_cfg) { | |
| 195 | 1330 | uint32_t out_mask = 0; | |
| 196 | |||
| 197 |
2/2✓ Branch 0 (10→3) taken 166250 times.
✓ Branch 1 (10→11) taken 1330 times.
|
167580 | for (uint32_t i = 0; i < in_cfg->map_size; i++) { |
| 198 | 166250 | uint8_t src = in_cfg->map_cfg[i].src_btn; | |
| 199 | 166250 | uint32_t src_mask = BIT(src & 0x1F); | |
| 200 | 166250 | uint32_t src_btn_idx = btn_id_to_btn_idx(src); | |
| 201 | |||
| 202 | /* Check if mapping src exist in input */ | ||
| 203 |
2/2✓ Branch 0 (3→4) taken 43496 times.
✓ Branch 1 (3→9) taken 122754 times.
|
166250 | if (src_mask & ctrl_input->mask[src_btn_idx]) { |
| 204 | /* Check if src is an axis */ | ||
| 205 |
2/2✓ Branch 0 (4→5) taken 8832 times.
✓ Branch 1 (4→7) taken 34664 times.
|
43496 | if (src_mask & ctrl_input->desc[src_btn_idx]) { |
| 206 | /* Src is an axis */ | ||
| 207 | 8832 | out_mask |= adapter_map_from_axis(&in_cfg->map_cfg[i]); | |
| 208 | } | ||
| 209 | else { | ||
| 210 | /* Src is a button */ | ||
| 211 | 34664 | out_mask |= adapter_map_from_btn(&in_cfg->map_cfg[i], src_mask, src_btn_idx); | |
| 212 | } | ||
| 213 | } | ||
| 214 | } | ||
| 215 | 1330 | return out_mask; | |
| 216 | } | ||
| 217 | |||
| 218 | 27 | static void adapter_fb_stop_cb(void* arg) { | |
| 219 | 27 | struct raw_fb fb_data = {0}; | |
| 220 | |||
| 221 | 27 | fb_data.header.wired_id = (uint8_t)(uintptr_t)arg; | |
| 222 | 27 | fb_data.header.type = FB_TYPE_RUMBLE; | |
| 223 | 27 | fb_data.header.data_len = 0; | |
| 224 | |||
| 225 | 27 | adapter_fb_stop_timer_stop((uint8_t)(uintptr_t)arg); | |
| 226 | |||
| 227 | /* Unmute system rumble */ | ||
| 228 | 27 | rumble_mute = false; | |
| 229 | |||
| 230 | /* Send 0 byte data, system that require callback stop shall look for that */ | ||
| 231 | 27 | adapter_q_fb(&fb_data); | |
| 232 | 27 | } | |
| 233 | |||
| 234 | ✗ | uint32_t adapter_get_out_mask(uint8_t dev_id) { | |
| 235 | ✗ | return adapter_out_mask[dev_id]; | |
| 236 | } | ||
| 237 | |||
| 238 | 17826 | int32_t btn_id_to_axis(uint8_t btn_id) { | |
| 239 |
7/17✓ Branch 0 (2→3) taken 4020 times.
✓ Branch 1 (2→4) taken 2936 times.
✓ Branch 2 (2→5) taken 2936 times.
✓ Branch 3 (2→6) taken 1482 times.
✓ Branch 4 (2→7) taken 1480 times.
✗ Branch 5 (2→8) not taken.
✗ Branch 6 (2→9) not taken.
✗ Branch 7 (2→10) not taken.
✗ Branch 8 (2→11) not taken.
✗ Branch 9 (2→12) not taken.
✗ Branch 10 (2→13) not taken.
✗ Branch 11 (2→14) not taken.
✗ Branch 12 (2→15) not taken.
✗ Branch 13 (2→16) not taken.
✗ Branch 14 (2→17) not taken.
✓ Branch 15 (2→18) taken 952 times.
✓ Branch 16 (2→19) taken 4020 times.
|
17826 | switch (btn_id) { |
| 240 | case PAD_LX_LEFT: | ||
| 241 | case PAD_LX_RIGHT: | ||
| 242 | case MOUSE_WX_LEFT: | ||
| 243 | case MOUSE_WX_RIGHT: | ||
| 244 | return AXIS_LX; | ||
| 245 | 4020 | case PAD_LY_DOWN: | |
| 246 | case PAD_LY_UP: | ||
| 247 | case MOUSE_WY_DOWN: | ||
| 248 | case MOUSE_WY_UP: | ||
| 249 | 4020 | return AXIS_LY; | |
| 250 | 2936 | case PAD_RX_LEFT: | |
| 251 | case PAD_RX_RIGHT: | ||
| 252 | //case MOUSE_X_LEFT: | ||
| 253 | //case MOUSE_X_RIGHT: | ||
| 254 | 2936 | return AXIS_RX; | |
| 255 | 2936 | case PAD_RY_DOWN: | |
| 256 | case PAD_RY_UP: | ||
| 257 | //case MOUSE_Y_DOWN: | ||
| 258 | //case MOUSE_Y_UP: | ||
| 259 | 2936 | return AXIS_RY; | |
| 260 | 1482 | case PAD_LM: | |
| 261 | 1482 | return TRIG_L; | |
| 262 | 1480 | case PAD_RM: | |
| 263 | 1480 | return TRIG_R; | |
| 264 | ✗ | case PAD_LS: | |
| 265 | ✗ | return TRIG_LS; | |
| 266 | ✗ | case PAD_RS: | |
| 267 | ✗ | return TRIG_RS; | |
| 268 | ✗ | case PAD_LD_LEFT: | |
| 269 | ✗ | return DPAD_LEFT; | |
| 270 | ✗ | case PAD_LD_RIGHT: | |
| 271 | ✗ | return DPAD_RIGHT; | |
| 272 | ✗ | case PAD_LD_DOWN: | |
| 273 | ✗ | return DPAD_DOWN; | |
| 274 | ✗ | case PAD_LD_UP: | |
| 275 | ✗ | return DPAD_UP; | |
| 276 | ✗ | case PAD_RB_LEFT: | |
| 277 | ✗ | return BTN_LEFT; | |
| 278 | ✗ | case PAD_RB_RIGHT: | |
| 279 | ✗ | return BTN_RIGHT; | |
| 280 | ✗ | case PAD_RB_DOWN: | |
| 281 | ✗ | return BTN_DOWN; | |
| 282 | ✗ | case PAD_RB_UP: | |
| 283 | ✗ | return BTN_UP; | |
| 284 | } | ||
| 285 | 952 | return AXIS_NONE; | |
| 286 | } | ||
| 287 | |||
| 288 | ✗ | uint8_t btn_is_axis(uint8_t dst_id, uint8_t dst_btn) { | |
| 289 | ✗ | struct wired_ctrl *out = &ctrl_output[dst_id]; | |
| 290 | ✗ | uint32_t dst_mask = BIT(dst_btn & 0x1F); | |
| 291 | ✗ | uint32_t dst_btn_idx = btn_id_to_btn_idx(dst_btn); | |
| 292 | ✗ | if (dst_mask & out->desc[dst_btn_idx]) { | |
| 293 | ✗ | return 1; | |
| 294 | } | ||
| 295 | return 0; | ||
| 296 | } | ||
| 297 | |||
| 298 | 7864 | uint32_t axis_to_btn_mask(uint8_t axis) { | |
| 299 |
6/17✓ Branch 0 (2→3) taken 1330 times.
✓ Branch 1 (2→4) taken 1294 times.
✓ Branch 2 (2→5) taken 1294 times.
✓ Branch 3 (2→6) taken 1308 times.
✓ Branch 4 (2→7) taken 1308 times.
✗ Branch 5 (2→8) not taken.
✗ Branch 6 (2→9) not taken.
✗ Branch 7 (2→10) not taken.
✗ Branch 8 (2→11) not taken.
✗ Branch 9 (2→12) not taken.
✗ Branch 10 (2→13) not taken.
✗ Branch 11 (2→14) not taken.
✗ Branch 12 (2→15) not taken.
✗ Branch 13 (2→16) not taken.
✗ Branch 14 (2→17) not taken.
✗ Branch 15 (2→18) not taken.
✓ Branch 16 (2→19) taken 1330 times.
|
7864 | switch (axis) { |
| 300 | case AXIS_LX: | ||
| 301 | return BIT(PAD_LX_LEFT) | BIT(PAD_LX_RIGHT) | BIT(MOUSE_WX_LEFT) | BIT(MOUSE_WX_RIGHT); | ||
| 302 | 1330 | case AXIS_LY: | |
| 303 | 1330 | return BIT(PAD_LY_DOWN) | BIT(PAD_LY_UP) | BIT(MOUSE_WY_DOWN) | BIT(MOUSE_WY_UP); | |
| 304 | 1294 | case AXIS_RX: | |
| 305 | 1294 | return BIT(PAD_RX_LEFT) | BIT(PAD_RX_RIGHT); /* BIT(MOUSE_X_LEFT) | BIT(MOUSE_X_RIGHT) */ | |
| 306 | 1294 | case AXIS_RY: | |
| 307 | 1294 | return BIT(PAD_RY_DOWN) | BIT(PAD_RY_UP); /* BIT(MOUSE_Y_DOWN) | BIT(MOUSE_Y_UP) */ | |
| 308 | 1308 | case TRIG_L: | |
| 309 | 1308 | return BIT(PAD_LM); | |
| 310 | 1308 | case TRIG_R: | |
| 311 | 1308 | return BIT(PAD_RM); | |
| 312 | ✗ | case TRIG_LS: | |
| 313 | ✗ | return BIT(PAD_LS); | |
| 314 | ✗ | case TRIG_RS: | |
| 315 | ✗ | return BIT(PAD_RS); | |
| 316 | ✗ | case DPAD_LEFT: | |
| 317 | ✗ | return BIT(PAD_LD_LEFT); | |
| 318 | ✗ | case DPAD_RIGHT: | |
| 319 | ✗ | return BIT(PAD_LD_RIGHT); | |
| 320 | ✗ | case DPAD_DOWN: | |
| 321 | ✗ | return BIT(PAD_LD_DOWN); | |
| 322 | ✗ | case DPAD_UP: | |
| 323 | ✗ | return BIT(PAD_LD_UP); | |
| 324 | ✗ | case BTN_LEFT: | |
| 325 | ✗ | return BIT(PAD_RB_LEFT); | |
| 326 | ✗ | case BTN_RIGHT: | |
| 327 | ✗ | return BIT(PAD_RB_RIGHT); | |
| 328 | ✗ | case BTN_DOWN: | |
| 329 | ✗ | return BIT(PAD_RB_DOWN); | |
| 330 | ✗ | case BTN_UP: | |
| 331 | ✗ | return BIT(PAD_RB_UP); | |
| 332 | } | ||
| 333 | ✗ | return 0x00000000; | |
| 334 | } | ||
| 335 | |||
| 336 | 7864 | uint32_t IRAM_ATTR axis_to_btn_id(uint8_t axis) { | |
| 337 |
6/16✓ Branch 0 (2→3) taken 1330 times.
✓ Branch 1 (2→4) taken 1294 times.
✓ Branch 2 (2→5) taken 1294 times.
✓ Branch 3 (2→6) taken 1308 times.
✓ Branch 4 (2→7) taken 1308 times.
✗ Branch 5 (2→8) not taken.
✗ Branch 6 (2→9) not taken.
✗ Branch 7 (2→10) not taken.
✗ Branch 8 (2→11) not taken.
✗ Branch 9 (2→12) not taken.
✗ Branch 10 (2→13) not taken.
✗ Branch 11 (2→14) not taken.
✗ Branch 12 (2→15) not taken.
✗ Branch 13 (2→16) not taken.
✗ Branch 14 (2→17) not taken.
✓ Branch 15 (2→18) taken 1330 times.
|
7864 | switch (axis) { |
| 338 | case AXIS_LX: | ||
| 339 | return PAD_LX_LEFT; | ||
| 340 | 1330 | case AXIS_LY: | |
| 341 | 1330 | return PAD_LY_DOWN; | |
| 342 | 1294 | case AXIS_RX: | |
| 343 | 1294 | return PAD_RX_LEFT; | |
| 344 | 1294 | case AXIS_RY: | |
| 345 | 1294 | return PAD_RY_DOWN; | |
| 346 | 1308 | case TRIG_L: | |
| 347 | 1308 | return PAD_LM; | |
| 348 | 1308 | case TRIG_R: | |
| 349 | 1308 | return PAD_RM; | |
| 350 | ✗ | case TRIG_LS: | |
| 351 | ✗ | return PAD_LS; | |
| 352 | ✗ | case TRIG_RS: | |
| 353 | ✗ | return PAD_RS; | |
| 354 | ✗ | case DPAD_LEFT: | |
| 355 | ✗ | return PAD_LD_LEFT; | |
| 356 | ✗ | case DPAD_RIGHT: | |
| 357 | ✗ | return PAD_LD_RIGHT; | |
| 358 | ✗ | case DPAD_DOWN: | |
| 359 | ✗ | return PAD_LD_DOWN; | |
| 360 | ✗ | case DPAD_UP: | |
| 361 | ✗ | return PAD_LD_UP; | |
| 362 | ✗ | case BTN_LEFT: | |
| 363 | ✗ | return PAD_RB_LEFT; | |
| 364 | ✗ | case BTN_RIGHT: | |
| 365 | ✗ | return PAD_RB_RIGHT; | |
| 366 | ✗ | case BTN_DOWN: | |
| 367 | ✗ | return PAD_RB_DOWN; | |
| 368 | ✗ | case BTN_UP: | |
| 369 | ✗ | return PAD_RB_UP; | |
| 370 | } | ||
| 371 | return 0; | ||
| 372 | } | ||
| 373 | |||
| 374 | 9769 | int8_t btn_sign(uint32_t polarity, uint8_t btn_id) { | |
| 375 |
2/3✓ Branch 0 (2→3) taken 5878 times.
✗ Branch 1 (2→4) not taken.
✓ Branch 2 (2→5) taken 3891 times.
|
9769 | switch (btn_id) { |
| 376 | 5878 | case PAD_LX_RIGHT: | |
| 377 | case PAD_LY_UP: | ||
| 378 | case PAD_RX_RIGHT: | ||
| 379 | case PAD_RY_UP: | ||
| 380 | case PAD_LM: | ||
| 381 | case PAD_RM: | ||
| 382 | case MOUSE_WX_RIGHT: | ||
| 383 | case MOUSE_WY_UP: | ||
| 384 | //case MOUSE_X_RIGHT: | ||
| 385 | //case MOUSE_Y_UP: | ||
| 386 | case PAD_LS: | ||
| 387 | case PAD_RS: | ||
| 388 | case PAD_LD_LEFT: | ||
| 389 | case PAD_LD_RIGHT: | ||
| 390 | case PAD_LD_DOWN: | ||
| 391 | case PAD_LD_UP: | ||
| 392 | case PAD_RB_LEFT: | ||
| 393 | case PAD_RB_RIGHT: | ||
| 394 | case PAD_RB_DOWN: | ||
| 395 | case PAD_RB_UP: | ||
| 396 |
2/2✓ Branch 0 (3→4) taken 4970 times.
✓ Branch 1 (3→6) taken 908 times.
|
5878 | return polarity ? -1 : 1; |
| 397 | 3891 | case PAD_LX_LEFT: | |
| 398 | case PAD_LY_DOWN: | ||
| 399 | case PAD_RY_DOWN: | ||
| 400 | case PAD_RX_LEFT: | ||
| 401 | case MOUSE_WX_LEFT: | ||
| 402 | case MOUSE_WY_DOWN: | ||
| 403 | //case MOUSE_X_LEFT: | ||
| 404 | //case MOUSE_Y_DOWN: | ||
| 405 |
2/2✓ Branch 0 (5→4) taken 908 times.
✓ Branch 1 (5→6) taken 2983 times.
|
3891 | return polarity ? 1 : -1; |
| 406 | } | ||
| 407 | return 1; | ||
| 408 | } | ||
| 409 | |||
| 410 | 192 | void IRAM_ATTR adapter_init_buffer(uint8_t wired_id) { | |
| 411 |
1/2✓ Branch 0 (2→3) taken 192 times.
✗ Branch 1 (2→4) not taken.
|
192 | if (wired_adapter.system_id != WIRED_AUTO) { |
| 412 | 192 | wired_adapter.data[wired_id].index = wired_id; | |
| 413 | 192 | wired_init_buffer(config.out_cfg[wired_id].dev_mode, &wired_adapter.data[wired_id]); | |
| 414 | } | ||
| 415 | 192 | } | |
| 416 | |||
| 417 | 1330 | void adapter_bridge(struct bt_data *bt_data) { | |
| 418 | 1330 | uint32_t out_mask = 0; | |
| 419 | |||
| 420 |
1/2✓ Branch 0 (2→3) taken 1330 times.
✗ Branch 1 (2→19) not taken.
|
1330 | if (bt_data->base.pids->type != BT_NONE) { |
| 421 |
1/2✓ Branch 0 (4→5) taken 1330 times.
✗ Branch 1 (4→19) not taken.
|
1330 | if (wireless_to_generic(bt_data, ctrl_input)) { |
| 422 | /* Unsupported report */ | ||
| 423 | return; | ||
| 424 | } | ||
| 425 | |||
| 426 | #ifdef CONFIG_BLUERETRO_ADAPTER_INPUT_DBG | ||
| 427 | 1330 | TESTS_CMDS_LOG("\"generic_input\": {"); | |
| 428 | 1330 | adapter_debug_wireless_print(ctrl_input); | |
| 429 | #endif | ||
| 430 |
1/2✓ Branch 0 (7→8) taken 1330 times.
✗ Branch 1 (7→19) not taken.
|
1330 | if (wired_adapter.system_id != WIRED_AUTO) { |
| 431 |
1/2✓ Branch 0 (9→10) taken 1330 times.
✗ Branch 1 (9→19) not taken.
|
1330 | if (wired_meta_init(ctrl_output)) { |
| 432 | /* Unsupported system */ | ||
| 433 | return; | ||
| 434 | } | ||
| 435 | |||
| 436 | 2660 | adapter_out_mask[bt_data->base.pids->out_idx] = | |
| 437 | 1330 | out_mask = adapter_mapping(&config.in_cfg[bt_data->base.pids->out_idx]); | |
| 438 | |||
| 439 | #ifdef CONFIG_BLUERETRO_ADAPTER_INPUT_MAP_DBG | ||
| 440 | 1330 | TESTS_CMDS_LOG("\"mapped_input\": {"); | |
| 441 | 1330 | adapter_debug_wired_print(&ctrl_output[bt_data->base.pids->out_idx]); | |
| 442 | #endif | ||
| 443 | 1330 | ctrl_output[bt_data->base.pids->out_idx].index = bt_data->base.pids->out_idx; | |
| 444 | 1330 | sys_macro_hdl(&ctrl_output[bt_data->base.pids->out_idx], &bt_data->base.flags[PAD]); | |
| 445 |
2/2✓ Branch 0 (18→15) taken 1330 times.
✓ Branch 1 (18→19) taken 1330 times.
|
2660 | for (uint32_t i = 0; out_mask; i++, out_mask >>= 1) { |
| 446 |
1/2✓ Branch 0 (15→16) taken 1330 times.
✗ Branch 1 (15→17) not taken.
|
1330 | if (out_mask & 0x1) { |
| 447 | 1330 | ctrl_output[i].index = i; | |
| 448 | 1330 | wired_from_generic(config.out_cfg[i].dev_mode, &ctrl_output[i], &wired_adapter.data[i]); | |
| 449 | } | ||
| 450 | } | ||
| 451 | } | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 455 | 27 | void adapter_fb_stop_timer_start(uint8_t dev_id, uint64_t dur_us) { | |
| 456 |
1/2✓ Branch 0 (2→3) taken 27 times.
✗ Branch 1 (2→6) not taken.
|
27 | if (wired_adapter.data[dev_id].fb_timer_hdl == NULL) { |
| 457 | 27 | const esp_timer_create_args_t fb_timer_args = { | |
| 458 | .callback = &adapter_fb_stop_cb, | ||
| 459 | 27 | .arg = (void*)(uintptr_t)dev_id, | |
| 460 | .name = "fb_timer" | ||
| 461 | }; | ||
| 462 | 27 | esp_timer_create(&fb_timer_args, (esp_timer_handle_t *)&wired_adapter.data[dev_id].fb_timer_hdl); | |
| 463 | 27 | esp_timer_start_once(wired_adapter.data[dev_id].fb_timer_hdl, dur_us); | |
| 464 | } | ||
| 465 | 27 | } | |
| 466 | |||
| 467 | 27 | void adapter_fb_stop_timer_stop(uint8_t dev_id) { | |
| 468 |
1/2✓ Branch 0 (2→3) taken 27 times.
✗ Branch 1 (2→5) not taken.
|
27 | if (wired_adapter.data[dev_id].fb_timer_hdl) { |
| 469 | 27 | esp_timer_delete(wired_adapter.data[dev_id].fb_timer_hdl); | |
| 470 | 27 | wired_adapter.data[dev_id].fb_timer_hdl = NULL; | |
| 471 | } | ||
| 472 | 27 | } | |
| 473 | |||
| 474 | ✗ | bool adapter_bridge_fb(struct raw_fb *fb_data, struct bt_data *bt_data) { | |
| 475 | ✗ | bool ret = false; | |
| 476 | |||
| 477 | ✗ | if (wired_adapter.system_id != WIRED_AUTO && bt_data && bt_data->base.pids) { | |
| 478 | ✗ | wired_fb_to_generic(config.out_cfg[bt_data->base.pids->id].dev_mode, fb_data, &fb_input); | |
| 479 | |||
| 480 | ✗ | if (bt_data->base.pids->type != BT_NONE) { | |
| 481 | ✗ | ret = wireless_fb_from_generic(&fb_input, bt_data); | |
| 482 | } | ||
| 483 | } | ||
| 484 | ✗ | return ret; | |
| 485 | } | ||
| 486 | |||
| 487 | 28 | void IRAM_ATTR adapter_q_fb(struct raw_fb *fb_data) { | |
| 488 | /* Best efford only on fb */ | ||
| 489 |
1/2✓ Branch 0 (2→3) taken 28 times.
✗ Branch 1 (2→4) not taken.
|
28 | if (!rumble_mute) { |
| 490 | 28 | queue_bss_enqueue(wired_adapter.input_q_hdl, (uint8_t *)fb_data, sizeof(*fb_data)); | |
| 491 | } | ||
| 492 | 28 | } | |
| 493 | |||
| 494 | 82 | void adapter_toggle_fb(uint32_t wired_id, uint32_t duration_us, uint8_t lf_pwr, uint8_t hf_pwr) { | |
| 495 | 82 | struct bt_dev *device = NULL; | |
| 496 | 82 | struct bt_data *bt_data = NULL; | |
| 497 | |||
| 498 | 82 | bt_host_get_active_dev_from_out_idx(wired_id, &device); | |
| 499 |
4/4✓ Branch 0 (3→4) taken 50 times.
✓ Branch 1 (3→9) taken 32 times.
✓ Branch 2 (4→5) taken 27 times.
✓ Branch 3 (4→9) taken 23 times.
|
82 | if (!rumble_mute && device) { |
| 500 | 27 | bt_data = &bt_adapter.data[device->ids.id]; | |
| 501 | 27 | if (bt_data) { | |
| 502 | 27 | struct generic_fb fb_data = {0}; | |
| 503 | |||
| 504 | 27 | fb_data.wired_id = wired_id; | |
| 505 | 27 | fb_data.type = FB_TYPE_RUMBLE; | |
| 506 | 27 | fb_data.state = 1; | |
| 507 | 27 | fb_data.hf_pwr = hf_pwr; | |
| 508 | 27 | fb_data.lf_pwr = lf_pwr; | |
| 509 | 27 | rumble_mute = true; | |
| 510 | 27 | adapter_fb_stop_timer_start(wired_id, duration_us); | |
| 511 | 27 | wireless_fb_from_generic(&fb_data, bt_data); | |
| 512 | 27 | bt_hid_feedback(device, bt_data->base.output); | |
| 513 | } | ||
| 514 | } | ||
| 515 | 82 | } | |
| 516 | |||
| 517 | 1 | void adapter_init(void) { | |
| 518 | 1 | wired_adapter.system_id = WIRED_AUTO; | |
| 519 | |||
| 520 | /* Save regular DRAM by allocating big sruct w/ only 32bits access in IRAM */ | ||
| 521 | 1 | ctrl_input = heap_caps_aligned_alloc(32, sizeof(struct wireless_ctrl), MALLOC_CAP_32BIT); | |
| 522 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 1 times.
|
1 | if (ctrl_input == NULL) { |
| 523 | ✗ | printf("# %s ctrl_input alloc fail\n", __FUNCTION__); | |
| 524 | } | ||
| 525 | 1 | ctrl_output = heap_caps_aligned_alloc(32, sizeof(struct wired_ctrl) * WIRED_MAX_DEV, MALLOC_CAP_32BIT); | |
| 526 |
1/2✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→8) taken 1 times.
|
1 | if (ctrl_output == NULL) { |
| 527 | ✗ | printf("# %s ctrl_output alloc fail\n", __FUNCTION__); | |
| 528 | } | ||
| 529 |
2/2✓ Branch 0 (13→9) taken 7 times.
✓ Branch 1 (13→14) taken 1 times.
|
8 | for (uint32_t i = 0; i < BT_MAX_DEV; i++) { |
| 530 | 7 | bt_adapter.data[i].raw_src_mappings = heap_caps_aligned_alloc(32, sizeof(struct raw_src_mapping) * REPORT_MAX, MALLOC_CAP_32BIT); | |
| 531 |
1/2✗ Branch 0 (10→11) not taken.
✓ Branch 1 (10→12) taken 7 times.
|
7 | if (bt_adapter.data[i].raw_src_mappings == NULL) { |
| 532 | ✗ | printf("# %s bt_adapter.data[%ld].raw_src_mappings alloc fail\n", __FUNCTION__, i); | |
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | 1 | wired_adapter.input_q_hdl = queue_bss_init(16, sizeof(struct raw_fb)); | |
| 537 |
1/2✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 1 times.
|
1 | if (wired_adapter.input_q_hdl == NULL) { |
| 538 | ✗ | ets_printf("# %s: Failed to create fb queue\n", __FUNCTION__); | |
| 539 | } | ||
| 540 | 1 | } | |
| 541 | |||
| 542 | ✗ | void adapter_meta_init(void) { | |
| 543 | ✗ | if (wired_adapter.system_id != WIRED_AUTO) { | |
| 544 | ✗ | wired_meta_init(ctrl_output); | |
| 545 | } | ||
| 546 | ✗ | } | |
| 547 |