GCC Code Coverage Report


Directory: main/
File: adapter/wired/npiso.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 177 0.0%
Functions: 0 10 0.0%
Branches: 0 97 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019-2025, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include "zephyr/types.h"
9 #include "tools/util.h"
10 #include "adapter/config.h"
11 #include "adapter/wired/wired.h"
12 #include "tests/cmds.h"
13 #include "bluetooth/mon.h"
14 #include "npiso.h"
15 #include "soc/gpio_struct.h"
16 #include "driver/gpio.h"
17
18 #define VTAP_PAL_PIN 16
19 #define VTAP_MODE_PIN 27
20
21 #define P2_D1_PIN 25
22 #define P2_D2_PIN 3
23 #define P2_D3_PIN 16
24 #define P2_D4_PIN 27
25
26 #define P2_D1_MASK (1U << P2_D1_PIN)
27 #define P2_D2_MASK (1U << P2_D2_PIN)
28 #define P2_D3_MASK (1U << P2_D3_PIN)
29 #define P2_D4_MASK (1U << P2_D4_PIN)
30
31 enum {
32 NPISO_LD_RIGHT = 0,
33 NPISO_LD_LEFT,
34 NPISO_LD_DOWN,
35 NPISO_LD_UP,
36 NPISO_START,
37 NPISO_SELECT,
38 NPISO_Y, NPISO_VB_RD_LEFT = NPISO_Y,
39 NPISO_B, NPISO_VB_RD_DOWN = NPISO_B,
40 NPISO_VB_A = 10,
41 NPISO_VB_B,
42 NPISO_R,
43 NPISO_L,
44 NPISO_X, NPISO_VB_RD_UP = NPISO_X,
45 NPISO_A, NPISO_VB_RD_RIGHT = NPISO_A,
46 };
47
48 static DRAM_ATTR const uint8_t npiso_mouse_axes_idx[ADAPTER_MAX_AXES] =
49 {
50 /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */
51 1, 0, 1, 0, 1, 0
52 };
53
54 static DRAM_ATTR const struct ctrl_meta npiso_mouse_axes_meta[ADAPTER_MAX_AXES] =
55 {
56 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80},
57 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80, .polarity = 1},
58 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80},
59 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80, .polarity = 1},
60 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80},
61 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 0x7F, .abs_min = 0x80},
62 };
63
64 static DRAM_ATTR const struct ctrl_meta npiso_trackball_axes_meta[ADAPTER_MAX_AXES] =
65 {
66 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8},
67 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8, .polarity = 1},
68 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8},
69 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8, .polarity = 1},
70 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8},
71 {.size_min = -8, .size_max = 7, .neutral = 0x00, .abs_max = 0x7, .abs_min = 0x8},
72 };
73
74 static DRAM_ATTR const struct ctrl_meta npiso_axes_meta[ADAPTER_MAX_AXES] =
75 {
76 {.size_min = -128, .size_max = 127, .neutral = 0, .abs_max = 127, .abs_min = 128},
77 {.size_min = -128, .size_max = 127, .neutral = 0, .abs_max = 127, .abs_min = 128},
78 {.size_min = -128, .size_max = 127, .neutral = 0, .abs_max = 127, .abs_min = 128},
79 {.size_min = -128, .size_max = 127, .neutral = 0, .abs_max = 127, .abs_min = 128},
80 {.size_min = 0, .size_max = 255, .neutral = 0, .abs_max = 255, .abs_min = 0x00},
81 {.size_min = 0, .size_max = 255, .neutral = 0, .abs_max = 255, .abs_min = 0x00},
82 };
83
84 struct npiso_map {
85 uint16_t buttons;
86 uint8_t axes[6];
87 } __packed;
88
89 struct npiso_mouse_map {
90 uint8_t id;
91 uint8_t buttons;
92 uint8_t relative[2];
93 int32_t raw_axes[2];
94 } __packed;
95
96 struct npiso_trackball_map {
97 uint8_t buttons;
98 uint8_t flags;
99 uint8_t relative[2];
100 int32_t raw_axes[2];
101 } __packed;
102
103 struct npiso_kb_map {
104 uint32_t scancodes[9][2];
105 } __packed;
106
107 struct npiso_kb_key_to_matrix {
108 uint8_t column_idx;
109 uint8_t row_nibble_idx;
110 uint32_t row_mask;
111 };
112 static const uint32_t npiso_mask[4] = {0x333F0FFF, 0x00000000, 0x00000000, BR_COMBO_MASK};
113 static const uint32_t npiso_desc[4] = {0x110000FF, 0x00000000, 0x00000000, 0x00000000};
114 static DRAM_ATTR const uint32_t npiso_btns_mask[32] = {
115 0, 0, 0, 0,
116 0, 0, 0, 0,
117 BIT(NPISO_LD_LEFT), BIT(NPISO_LD_RIGHT), BIT(NPISO_LD_DOWN), BIT(NPISO_LD_UP),
118 0, 0, 0, 0,
119 BIT(NPISO_Y), BIT(NPISO_A), BIT(NPISO_B), BIT(NPISO_X),
120 BIT(NPISO_START), BIT(NPISO_SELECT), 0, 0,
121 BIT(NPISO_L), BIT(NPISO_L), 0, 0,
122 BIT(NPISO_R), BIT(NPISO_R), 0, 0,
123 };
124
125 static const uint32_t npiso_vb_mask[4] = {0xBBF50FF0, 0x00000000, 0x00000000, BR_COMBO_MASK};
126 static const uint32_t npiso_vb_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
127 static DRAM_ATTR const uint32_t npiso_vb_btns_mask[32] = {
128 0, 0, 0, 0,
129 BIT(NPISO_VB_RD_LEFT), BIT(NPISO_VB_RD_RIGHT), BIT(NPISO_VB_RD_DOWN), BIT(NPISO_VB_RD_UP),
130 BIT(NPISO_LD_LEFT), BIT(NPISO_LD_RIGHT), BIT(NPISO_LD_DOWN), BIT(NPISO_LD_UP),
131 0, 0, 0, 0,
132 BIT(NPISO_VB_B), 0, BIT(NPISO_VB_A), 0,
133 BIT(NPISO_START), BIT(NPISO_SELECT), BIT(NPISO_START), BIT(NPISO_SELECT),
134 BIT(NPISO_L), BIT(NPISO_L), 0, 0,
135 BIT(NPISO_R), BIT(NPISO_R), 0, 0,
136 };
137
138 static const uint32_t npiso_mouse_mask[4] = {0x110000F0, 0x00000000, 0x00000000, BR_COMBO_MASK};
139 static const uint32_t npiso_mouse_desc[4] = {0x000000F0, 0x00000000, 0x00000000, 0x00000000};
140 static const uint32_t npiso_mouse_btns_mask[32] = {
141 0, 0, 0, 0,
142 0, 0, 0, 0,
143 0, 0, 0, 0,
144 0, 0, 0, 0,
145 0, 0, 0, 0,
146 0, 0, 0, 0,
147 BIT(NPISO_B), 0, 0, 0,
148 BIT(NPISO_Y), 0, 0, 0,
149 };
150
151 static const uint32_t npiso_trackball_mask[4] = {0x1907C0F0, 0x00000000, 0x00000000, BR_COMBO_MASK};
152 static const uint32_t npiso_trackball_desc[4] = {0x000000F0, 0x00000000, 0x00000000, 0x00000000};
153 static const uint32_t npiso_trackball_btns_mask[32] = {
154 0, 0, 0, 0,
155 0, 0, 0, 0,
156 0, 0, 0, 0,
157 0, 0, BIT(NPISO_LD_DOWN), BIT(NPISO_LD_UP),
158 BIT(NPISO_LD_LEFT), BIT(NPISO_LD_RIGHT), 0, 0,
159 0, 0, 0, 0,
160 BIT(NPISO_Y), 0, 0, BIT(NPISO_START),
161 BIT(NPISO_B), 0, 0, 0,
162 };
163
164 static const uint32_t npiso_kb_mask[4] = {0xE6FF0F0F, 0xFFFFFFFF, 0xFFFFFFFF, 0x0007FFFF | BR_COMBO_MASK};
165 static const uint32_t npiso_kb_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
166 static const struct npiso_kb_key_to_matrix npiso_kb_key_to_matrix[KBM_MAX] = {
167 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
168 {6, 0, P2_D4_MASK}, {5, 0, P2_D4_MASK}, {6, 0, P2_D3_MASK}, {6, 0, P2_D2_MASK}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
169 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
170 {8, 0, P2_D4_MASK}, {8, 0, P2_D3_MASK}, {8, 1, P2_D1_MASK}, {8, 0, P2_D2_MASK}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
171 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
172 {7, 0, P2_D3_MASK}, {5, 0, P2_D3_MASK}, {6, 1, P2_D3_MASK}, {5, 1, P2_D1_MASK}, {7, 0, P2_D2_MASK}, {0, 0, P2_D2_MASK}, {0, 0, 0}, {0, 1, P2_D3_MASK},
173 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
174 {0, 0, 0}, {6, 1, P2_D2_MASK}, {7, 0, P2_D4_MASK}, {0, 0, 0}, {0, 0, 0}, {6, 1, P2_D1_MASK}, {7, 1, P2_D1_MASK}, {8, 1, P2_D2_MASK},
175
176 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
177 {4, 1, P2_D1_MASK}, {5, 1, P2_D2_MASK}, {4, 0, P2_D3_MASK}, {4, 0, P2_D4_MASK}, {3, 0, P2_D2_MASK}, {3, 0, P2_D4_MASK}, {2, 0, P2_D4_MASK}, {2, 0, P2_D3_MASK},
178 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
179 {3, 1, P2_D1_MASK}, {3, 1, P2_D2_MASK}, {2, 0, P2_D2_MASK}, {2, 1, P2_D3_MASK}, {5, 0, P2_D2_MASK}, {3, 0, P2_D3_MASK}, {4, 1, P2_D2_MASK}, {4, 0, P2_D2_MASK},
180 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
181 {7, 1, P2_D3_MASK}, {7, 1, P2_D4_MASK}, {6, 1, P2_D4_MASK}, {5, 1, P2_D4_MASK}, {5, 1, P2_D3_MASK}, {4, 1, P2_D4_MASK}, {4, 1, P2_D3_MASK}, {3, 1, P2_D4_MASK},
182 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
183 {3, 1, P2_D3_MASK}, {2, 1, P2_D4_MASK}, {0, 1, P2_D4_MASK}, {0, 0, 0}, {1, 1, P2_D4_MASK}, {1, 1, P2_D3_MASK}, {0, 0, P2_D3_MASK}, {0, 0, P2_D4_MASK},
184
185 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
186 {1, 1, P2_D1_MASK}, {1, 0, P2_D3_MASK}, {1, 0, P2_D4_MASK}, {0, 1, P2_D3_MASK}, {2, 1, P2_D2_MASK}, {2, 1, P2_D1_MASK}, {1, 1, P2_D2_MASK}, {0, 1, P2_D1_MASK},
187 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
188 {7, 0, P2_D1_MASK}, {6, 0, P2_D1_MASK}, {5, 0, P2_D1_MASK}, {4, 0, P2_D1_MASK}, {3, 0, P2_D1_MASK}, {2, 0, P2_D1_MASK}, {1, 0, P2_D1_MASK}, {0, 0, P2_D1_MASK},
189 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
190 {0, 0, P2_D1_MASK | P2_D2_MASK | P2_D3_MASK | P2_D4_MASK}, {0, 1, P2_D1_MASK | P2_D2_MASK | P2_D3_MASK | P2_D4_MASK}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {8, 1, P2_D4_MASK},
191 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
192 {8, 0, P2_D1_MASK}, {0, 0, 0}, {8, 1, P2_D3_MASK}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
193
194 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
195 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
196 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
197 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {7, 1, P2_D2_MASK}, {0, 0, 0}, {0, 0, 0},
198 /* KB_RSHIFT, KB_RALT, KB_RWIN */
199 {0, 1, P2_D2_MASK}, {1, 0, P2_D2_MASK}, {0, 0, 0},
200 };
201
202 void IRAM_ATTR npiso_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
203 switch (dev_mode) {
204 case DEV_KB:
205 {
206 memset(wired_data->output, 0x00, sizeof(struct npiso_kb_map));
207 break;
208 }
209 case DEV_MOUSE:
210 {
211 if (wired_adapter.system_id == SNES) {
212 struct npiso_mouse_map *map = (struct npiso_mouse_map *)wired_data->output;
213
214 map->id = 0xFF;
215 map->buttons = 0xFE;
216 map->relative[0] = 1;
217 map->relative[1] = 1;
218 map->raw_axes[0] = 0;
219 map->raw_axes[1] = 0;
220 }
221 else {
222 struct npiso_trackball_map *map = (struct npiso_trackball_map *)wired_data->output;
223
224 map->buttons = 0xFF;
225 map->flags = 0x2F; // Fixed switch to L & Lo
226 map->relative[0] = 1;
227 map->relative[1] = 1;
228 map->raw_axes[0] = 0;
229 map->raw_axes[1] = 0;
230 }
231 break;
232 }
233 default:
234 {
235 struct npiso_map *map = (struct npiso_map *)wired_data->output;
236 struct npiso_map *map_mask = (struct npiso_map *)wired_data->output_mask;
237
238 if (wired_adapter.system_id == VBOY) {
239 map->buttons = 0xFDFF;
240 }
241 else {
242 map->buttons = 0xFFFF;
243 }
244 map_mask->buttons = 0x0000;
245 memset(map->axes, 0xFF, sizeof(map_mask->axes));
246 memset(map_mask->axes, 0x00, sizeof(map_mask->axes));
247 break;
248 }
249 }
250 }
251
252 void npiso_meta_init(struct wired_ctrl *ctrl_data) {
253 memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*WIRED_MAX_DEV);
254
255 for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
256 for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
257 switch (config.out_cfg[i].dev_mode) {
258 case DEV_KB:
259 ctrl_data[i].mask = npiso_kb_mask;
260 ctrl_data[i].desc = npiso_kb_desc;
261 break;
262 case DEV_MOUSE:
263 if (wired_adapter.system_id == SNES) {
264 ctrl_data[i].mask = npiso_mouse_mask;
265 ctrl_data[i].desc = npiso_mouse_desc;
266 ctrl_data[i].axes[j].meta = &npiso_mouse_axes_meta[j];
267 }
268 else {
269 ctrl_data[i].mask = npiso_trackball_mask;
270 ctrl_data[i].desc = npiso_trackball_desc;
271 ctrl_data[i].axes[j].meta = &npiso_trackball_axes_meta[j];
272 }
273 break;
274 default:
275 if (wired_adapter.system_id == VBOY) {
276 ctrl_data[i].mask = npiso_vb_mask;
277 ctrl_data[i].desc = npiso_vb_desc;
278 }
279 else {
280 ctrl_data[i].mask = npiso_mask;
281 ctrl_data[i].desc = npiso_desc;
282 ctrl_data[i].axes[j].meta = &npiso_axes_meta[j];
283 }
284 break;
285 }
286 }
287 }
288 }
289
290 static void npiso_vtap_gpio(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
291 /* Palette */
292 if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_LJ]) {
293 if (ctrl_data->btns[0].value & generic_btns_mask[PAD_LJ]) {
294 GPIO.out_w1tc = BIT(VTAP_PAL_PIN);
295 }
296 else {
297 GPIO.out_w1ts = BIT(VTAP_PAL_PIN);
298 }
299 }
300
301 /* Mode */
302 if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_RJ]) {
303 if (ctrl_data->btns[0].value & generic_btns_mask[PAD_RJ]) {
304 if (!atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2)) {
305 atomic_set_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2);
306 }
307 }
308 else {
309 if (atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2)) {
310 atomic_clear_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2);
311
312 if (GPIO.out & BIT(VTAP_MODE_PIN)) {
313 GPIO.out_w1tc = BIT(VTAP_MODE_PIN);
314 }
315 else {
316 GPIO.out_w1ts = BIT(VTAP_MODE_PIN);
317 }
318 }
319 }
320 }
321 }
322
323 static void npiso_ctrl_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
324 struct npiso_map map_tmp;
325 uint32_t map_mask = 0xFFFF;
326 const uint32_t *btns_mask = (wired_adapter.system_id == VBOY) ? npiso_vb_btns_mask : npiso_btns_mask;
327
328 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
329
330 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
331 if (ctrl_data->map_mask[0] & BIT(i)) {
332 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
333 map_tmp.buttons &= ~btns_mask[i];
334 map_mask &= ~btns_mask[i];
335 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
336 }
337 else if (map_mask & btns_mask[i]) {
338 map_tmp.buttons |= btns_mask[i];
339 wired_data->cnt_mask[i] = 0;
340 }
341 }
342 }
343
344 for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) {
345 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & ctrl_data->desc[0])) {
346 if (ctrl_data->axes[i].value > ctrl_data->axes[i].meta->size_max) {
347 map_tmp.axes[i] = ~ctrl_data->axes[i].meta->size_max;
348 }
349 else if (ctrl_data->axes[i].value < ctrl_data->axes[i].meta->size_min) {
350 map_tmp.axes[i] = ~ctrl_data->axes[i].meta->size_min;
351 }
352 else {
353 map_tmp.axes[i] = ~(uint8_t)(ctrl_data->axes[i].value);
354 }
355 }
356 wired_data->cnt_mask[axis_to_btn_id(i)] = ctrl_data->axes[i].cnt_mask;
357 }
358
359 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
360
361 TESTS_CMDS_LOG("\"wired_output\": {\"btns\": %d},\n", map_tmp.buttons);
362 BT_MON_LOG("\"wired_output\": {\"btns\": %04X},\n", map_tmp.buttons);
363 }
364
365 static void npiso_mouse_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
366 struct npiso_mouse_map map_tmp;
367 int32_t *raw_axes = (int32_t *)(wired_data->output + 4);
368
369 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
370
371 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
372 if (ctrl_data->map_mask[0] & BIT(i)) {
373 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
374 map_tmp.buttons &= ~npiso_mouse_btns_mask[i];
375 }
376 else {
377 map_tmp.buttons |= npiso_mouse_btns_mask[i];
378 }
379 }
380 }
381
382 for (uint32_t i = 2; i < 4; i++) {
383 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & npiso_mouse_desc[0])) {
384 if (ctrl_data->axes[i].relative) {
385 map_tmp.relative[npiso_mouse_axes_idx[i]] = 1;
386 atomic_add(&raw_axes[npiso_mouse_axes_idx[i]], ctrl_data->axes[i].value);
387 }
388 else {
389 map_tmp.relative[npiso_mouse_axes_idx[i]] = 0;
390 raw_axes[npiso_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
391 }
392 }
393 }
394
395 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
396 }
397
398 static void npiso_trackball_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
399 struct npiso_trackball_map map_tmp;
400 int32_t *raw_axes = (int32_t *)(wired_data->output + 4);
401
402 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
403
404 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
405 if (ctrl_data->map_mask[0] & BIT(i)) {
406 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
407 map_tmp.buttons &= ~npiso_trackball_btns_mask[i];
408 }
409 else {
410 map_tmp.buttons |= npiso_trackball_btns_mask[i];
411 }
412 }
413 }
414
415 for (uint32_t i = 2; i < 4; i++) {
416 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & npiso_trackball_desc[0])) {
417 if (ctrl_data->axes[i].relative) {
418 map_tmp.relative[npiso_mouse_axes_idx[i]] = 1;
419 atomic_add(&raw_axes[npiso_mouse_axes_idx[i]], ctrl_data->axes[i].value);
420 }
421 else {
422 map_tmp.relative[npiso_mouse_axes_idx[i]] = 0;
423 raw_axes[npiso_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
424 }
425 }
426 }
427
428 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
429 }
430
431 static void npiso_kb_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
432 struct npiso_kb_map map_tmp = {0};
433
434 for (uint32_t i = 0; i < KBM_MAX; i++) {
435 if (ctrl_data->map_mask[i / 32] & BIT(i & 0x1F)) {
436 if (ctrl_data->btns[i / 32].value & BIT(i & 0x1F)) {
437 uint8_t column = npiso_kb_key_to_matrix[i].column_idx;
438 uint8_t row = npiso_kb_key_to_matrix[i].row_nibble_idx;
439
440 map_tmp.scancodes[column][row] |= npiso_kb_key_to_matrix[i].row_mask;
441 }
442 }
443 }
444
445 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
446 }
447
448 void npiso_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
449 switch (dev_mode) {
450 case DEV_KB:
451 npiso_kb_from_generic(ctrl_data, wired_data);
452 break;
453 case DEV_MOUSE:
454 if (wired_adapter.system_id == SNES) {
455 npiso_mouse_from_generic(ctrl_data, wired_data);
456 }
457 else {
458 npiso_trackball_from_generic(ctrl_data, wired_data);
459 }
460 break;
461 default:
462 npiso_ctrl_from_generic(ctrl_data, wired_data);
463 if (wired_adapter.system_id == VBOY) {
464 npiso_vtap_gpio(ctrl_data, wired_data);
465 }
466 break;
467 }
468 }
469
470 void npiso_fb_to_generic(int32_t dev_mode, struct raw_fb *raw_fb_data, struct generic_fb *fb_data) {
471 fb_data->wired_id = raw_fb_data->header.wired_id;
472 fb_data->type = raw_fb_data->header.type;
473
474 /* This stop rumble when BR timeout trigger */
475 if (raw_fb_data->header.data_len == 0) {
476 fb_data->state = 0;
477 fb_data->lf_pwr = fb_data->hf_pwr = 0;
478 }
479 else {
480 switch (fb_data->type) {
481 case FB_TYPE_RUMBLE:
482 fb_data->state = (raw_fb_data->data[0] || raw_fb_data->data[1] ? 1 : 0);
483 fb_data->lf_pwr = raw_fb_data->data[1] * 17;
484 fb_data->hf_pwr = raw_fb_data->data[0] * 17;
485 break;
486 }
487 }
488 }
489
490 void IRAM_ATTR npiso_gen_turbo_mask(struct wired_data *wired_data) {
491 const uint32_t *btns_mask = (wired_adapter.system_id == VBOY) ? npiso_vb_btns_mask : npiso_btns_mask;
492 struct npiso_map *map_mask = (struct npiso_map *)wired_data->output_mask;
493
494 map_mask->buttons = 0x0000;
495
496 wired_gen_turbo_mask_btns16_neg(wired_data, &map_mask->buttons, btns_mask);
497 }
498