GCC Code Coverage Report


Directory: main/
File: adapter/wired/cdi.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 206 0.0%
Functions: 0 8 0.0%
Branches: 0 104 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 <string.h>
7 #include "zephyr/types.h"
8 #include "tools/util.h"
9 #include "adapter/config.h"
10 #include "adapter/kb_monitor.h"
11 #include "tests/cmds.h"
12 #include "bluetooth/mon.h"
13 #include "cdi.h"
14
15 #define CDI_KB_SHIFT 0x01
16 #define CDI_KB_CAPS 0x02
17 #define CDI_KB_ALT 0x04
18 #define CDI_KB_CTRL 0x08
19
20 enum {
21 CDI_2 = 4,
22 CDI_1,
23 };
24
25 static DRAM_ATTR const uint8_t cdi_axes_idx[ADAPTER_MAX_AXES] =
26 {
27 /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */
28 0, 1, 0, 1, 0, 1
29 };
30
31 static DRAM_ATTR const struct ctrl_meta cdi_axes_meta[ADAPTER_MAX_AXES] =
32 {
33 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
34 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128, .polarity = 1},
35 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
36 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128, .polarity = 1},
37 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
38 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
39 };
40
41 struct cdi_map {
42 uint8_t buttons;
43 uint8_t align[5];
44 uint8_t relative[2];
45 int32_t raw_axes[2];
46 } __packed;
47
48 static const uint32_t cdi_mask[4] = {0x0005000F, 0x00000000, 0x00000000, BR_COMBO_MASK};
49 static const uint32_t cdi_desc[4] = {0x0000000F, 0x00000000, 0x00000000, 0x00000000};
50 static DRAM_ATTR const uint32_t cdi_btns_mask[32] = {
51 0, 0, 0, 0,
52 0, 0, 0, 0,
53 0, 0, 0, 0,
54 0, 0, 0, 0,
55 BIT(CDI_1), 0, BIT(CDI_2), 0,
56 0, 0, 0, 0,
57 0, 0, 0, 0,
58 0, 0, 0, 0,
59 };
60
61 static const uint32_t cdi_mouse_mask[4] = {0x190000F0, 0x00000000, 0x00000000, BR_COMBO_MASK};
62 static const uint32_t cdi_mouse_desc[4] = {0x000000F0, 0x00000000, 0x00000000, 0x00000000};
63 static const uint32_t cdi_mouse_btns_mask[32] = {
64 0, 0, 0, 0,
65 0, 0, 0, 0,
66 0, 0, 0, 0,
67 0, 0, 0, 0,
68 0, 0, 0, 0,
69 0, 0, 0, 0,
70 BIT(CDI_2), 0, 0, 0,
71 BIT(CDI_1), 0, 0, 0,
72 };
73
74 static const uint32_t cdi_kb_mask[4] = {0xE6FF0F0F, 0xFFFFFFFF, 0xFFFFFFFF, 0x0007FFFF | BR_COMBO_MASK};
75 static const uint32_t cdi_kb_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
76
77 /* Flash bite the bullet here, their is no dominant pattern between the special */
78 /* keys and the normal code set. So using 6 lookup table for CD-i to keep code readable */
79 static const uint8_t cdi_kb_code_normal[KBM_MAX] = {
80 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
81 0x61, 0x64, 0x73, 0x77, 0x00, 0x00, 0x00, 0x00,
82 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
83 0x08, 0x0C, 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00,
84 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
85 0x71, 0x72, 0x65, 0x66, 0x1B, 0x0D, 0x1C, 0x60,
86 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
87 0x00, 0x7A, 0x00, 0x00, 0x00, 0x78, 0x00, 0x20,
88
89 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
90 0x62, 0x63, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
91 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
92 0x6D, 0x6E, 0x6F, 0x70, 0x74, 0x75, 0x76, 0x79,
93 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
94 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
95 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
96 0x39, 0x30, 0x7F, 0x09, 0x2D, 0x3D, 0x5B, 0x5D,
97
98 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
99 0x5C, 0x3B, 0x27, 0x00, 0x2C, 0x2E, 0x2F, 0x00,
100 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
101 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
102 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
103 0x80, 0x81, 0x82, 0x83, 0x40, 0x42, 0x43, 0x56,
104 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
105 0x1E, 0x58, 0x06, 0x55, 0x59, 0x00, 0x2F, 0x2A,
106
107 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
108 0x2D, 0x2B, 0x0D, 0x31, 0x32, 0x33, 0x34, 0x35,
109 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
110 0x36, 0x37, 0x38, 0x39, 0x30, 0x2E, 0x00, 0x00,
111 /* KB_RSHIFT, KB_RALT, KB_RWIN */
112 0x00, 0x00, 0x1D,
113 };
114 static const uint8_t cdi_kb_code_shift[KBM_MAX] = {
115 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
116 0x41, 0x44, 0x53, 0x57, 0x00, 0x00, 0x00, 0x00,
117 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
118 0x11, 0x14, 0x12, 0x13, 0x00, 0x00, 0x00, 0x00,
119 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
120 0x51, 0x52, 0x45, 0x46, 0x1B, 0x0D, 0x1C, 0x7E,
121 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
122 0x00, 0x5A, 0x00, 0x00, 0x00, 0x58, 0x00, 0x20,
123
124 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
125 0x42, 0x43, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
126 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
127 0x4D, 0x4E, 0x4F, 0x50, 0x54, 0x55, 0x56, 0x59,
128 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
129 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A,
130 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
131 0x28, 0x29, 0x0F, 0x19, 0x5F, 0x2B, 0x7B, 0x7D,
132
133 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
134 0x7C, 0x3A, 0x22, 0x00, 0x3C, 0x3E, 0x3F, 0x00,
135 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
136 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
137 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
138 0x88, 0x89, 0x8A, 0x8B, 0x40, 0x42, 0x43, 0x56,
139 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
140 0x1E, 0x58, 0x57, 0x55, 0x59, 0x00, 0x2F, 0x2A,
141
142 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
143 0x2D, 0x2B, 0x0D, 0x31, 0x32, 0x33, 0x34, 0x35,
144 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
145 0x36, 0x37, 0x38, 0x39, 0x30, 0x2E, 0x00, 0x00,
146 /* KB_RSHIFT, KB_RALT, KB_RWIN */
147 0x00, 0x00, 0x1D,
148 };
149 static const uint8_t cdi_kb_code_alt[KBM_MAX] = {
150 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
151 0xE1, 0xE4, 0xF3, 0xF7, 0x00, 0x00, 0x00, 0x00,
152 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
153 0x15, 0x18, 0x16, 0x17, 0x00, 0x00, 0x00, 0x00,
154 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
155 0xF1, 0xF2, 0xE5, 0xE6, 0x1B, 0x0D, 0x1C, 0xE0,
156 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
157 0x00, 0xFA, 0x00, 0x00, 0x00, 0xF8, 0x00, 0xA0,
158
159 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
160 0xE2, 0xE3, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC,
161 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
162 0xED, 0xEE, 0xEF, 0xF0, 0xF4, 0xF5, 0xF6, 0xF9,
163 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
164 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
165 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
166 0xB9, 0xB0, 0x0F, 0x19, 0xAD, 0xBD, 0xDB, 0xDD,
167
168 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
169 0xDC, 0xBB, 0xA7, 0x00, 0xAC, 0xAE, 0xAF, 0x00,
170 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
171 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
172 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
173 0x90, 0x91, 0x92, 0x93, 0xC0, 0xC2, 0xC3, 0xD6,
174 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
175 0x1E, 0xD8, 0xD7, 0xD5, 0xD9, 0x00, 0xAF, 0xAA,
176
177 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
178 0xAD, 0xAB, 0x0D, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
179 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
180 0xB6, 0xB7, 0xB8, 0xB9, 0xB0, 0xAE, 0x00, 0x00,
181 /* KB_RSHIFT, KB_RALT, KB_RWIN */
182 0x00, 0x00, 0x1D,
183 };
184 static const uint8_t cdi_kb_code_ctrl[KBM_MAX] = {
185 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
186 0x01, 0x04, 0x13, 0x17, 0x00, 0x00, 0x00, 0x00,
187 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
188 0x02, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
189 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
190 0x11, 0x12, 0x05, 0x06, 0x1B, 0x0D, 0x1C, 0x60,
191 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
192 0x00, 0x1A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20,
193
194 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
195 0x02, 0x03, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
196 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
197 0x0D, 0x0E, 0x0F, 0x10, 0x14, 0x15, 0x16, 0x19,
198 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
199 0x31, 0x0, 0x33, 0x34, 0x35, 0x1E, 0x37, 0x38,
200 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
201 0x39, 0x30, 0x1F, 0x19, 0x1F, 0x3D, 0x5B, 0x5D,
202
203 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
204 0x5C, 0x3B, 0x27, 0x00, 0x2C, 0x2E, 0x2F, 0x00,
205 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
206 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
207 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
208 0x98, 0x99, 0x9A, 0x9B, 0x41, 0x42, 0x44, 0x56,
209 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
210 0x1E, 0x58, 0x57, 0x55, 0x59, 0x00, 0x2F, 0x2A,
211
212 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
213 0x2D, 0x2B, 0x0D, 0x31, 0x32, 0x33, 0x34, 0x35,
214 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
215 0x36, 0x37, 0x38, 0x39, 0x30, 0x2E, 0x00, 0x00,
216 /* KB_RSHIFT, KB_RALT, KB_RWIN */
217 0x00, 0x00, 0x1D,
218 };
219 static const uint8_t cdi_kb_code_ctrl_alt[KBM_MAX] = {
220 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
221 0x81, 0x84, 0x93, 0x97, 0x00, 0x00, 0x00, 0x00,
222 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
223 0x15, 0x18, 0x16, 0x17, 0x00, 0x00, 0x00, 0x00,
224 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
225 0x91, 0x92, 0x85, 0x86, 0x1B, 0x0D, 0x1C, 0xE0,
226 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
227 0x00, 0x9A, 0x00, 0x00, 0x00, 0x98, 0x00, 0xA0,
228
229 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
230 0x82, 0x83, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C,
231 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
232 0x8D, 0x8E, 0x8F, 0x90, 0x94, 0x95, 0x96, 0x99,
233 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
234 0xB1, 0x80, 0xB3, 0xB4, 0xB5, 0x9E, 0xB7, 0xB8,
235 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
236 0xB9, 0xB0, 0x0F, 0x19, 0x9F, 0xBD, 0xDB, 0xDD,
237
238 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
239 0xDC, 0xBB, 0xA7, 0x00, 0xAC, 0xAE, 0xAF, 0x00,
240 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
241 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
242 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
243 0x90, 0x91, 0x92, 0x93, 0xC1, 0xC2, 0xC4, 0xD6,
244 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
245 0x1E, 0xD8, 0xD7, 0xD5, 0xD9, 0x00, 0xAF, 0xAA,
246
247 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
248 0xAD, 0xAB, 0x0D, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
249 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
250 0xB6, 0xB7, 0xB8, 0xB9, 0xB0, 0xAE, 0x00, 0x00,
251 /* KB_RSHIFT, KB_RALT, KB_RWIN */
252 0x00, 0x00, 0x1D,
253 };
254 static const uint8_t cdi_kb_code_shift_alt[KBM_MAX] = {
255 /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */
256 0xC1, 0xC4, 0xD3, 0xD7, 0x00, 0x00, 0x00, 0x00,
257 /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */
258 0x15, 0x18, 0x16, 0x17, 0x00, 0x00, 0x00, 0x00,
259 /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */
260 0xD1, 0xD2, 0xC5, 0xC6, 0x1B, 0x0D, 0x1C, 0xFE,
261 /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */
262 0x00, 0xDA, 0x00, 0x00, 0x00, 0xD8, 0x00, 0xA0,
263
264 /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */
265 0xC2, 0xC3, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC,
266 /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */
267 0xCD, 0xCE, 0xCF, 0xD0, 0xD4, 0xD5, 0xD6, 0xD9,
268 /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */
269 0xA1, 0xC0, 0xA3, 0xA4, 0xA5, 0xDE, 0xA6, 0xAA,
270 /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */
271 0xA8, 0xA9, 0x0F, 0x19, 0xDF, 0xAB, 0xFB, 0xFD,
272
273 /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */
274 0xFC, 0xBA, 0xA2, 0x00, 0xBC, 0xBE, 0xBF, 0x00,
275 /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */
276 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
277 /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */
278 0x90, 0x91, 0x92, 0x93, 0xC1, 0xC2, 0xC3, 0xD6,
279 /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */
280 0x1E, 0xD8, 0xD7, 0xD5, 0xD9, 0x00, 0xAF, 0xAA,
281
282 /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */
283 0xAD, 0xAB, 0x0D, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
284 /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */
285 0xB6, 0xB7, 0xB8, 0xB9, 0xB0, 0xAE, 0x00, 0x00,
286 /* KB_RSHIFT, KB_RALT, KB_RWIN */
287 0x00, 0x00, 0x1D,
288 };
289
290 void IRAM_ATTR cdi_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
291 switch (dev_mode) {
292 case DEV_KB:
293 /* Use acc cfg to choose KB type */
294 switch (config.out_cfg[wired_data->index].acc_mode) {
295 case ACC_RUMBLE:
296 wired_data->output[0] = 0x40;
297 wired_data->output[1] = 0x10;
298 wired_data->output[2] = 0x00;
299 wired_data->output[3] = 0x00;
300 break;
301 default:
302 wired_data->output[0] = 0x80;
303 wired_data->output[1] = 0x00;
304 break;
305 }
306 break;
307 default:
308 {
309 struct cdi_map *map = (struct cdi_map *)wired_data->output;
310
311 wired_data->output[0] = 0x40;
312 wired_data->output[1] = 0x00;
313 wired_data->output[2] = 0x00;
314 for (uint32_t i = 0; i < 2; i++) {
315 map->raw_axes[i] = 0;
316 map->relative[i] = 1;
317 }
318 memset(wired_data->output_mask, 0xFF, sizeof(struct cdi_map));
319 break;
320 }
321 }
322 }
323
324 void cdi_meta_init(struct wired_ctrl *ctrl_data) {
325 memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*WIRED_MAX_DEV);
326
327 for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
328 for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
329 switch (config.out_cfg[i].dev_mode) {
330 case DEV_KB:
331 ctrl_data[i].mask = cdi_kb_mask;
332 ctrl_data[i].desc = cdi_kb_desc;
333 goto exit_axes_loop;
334 case DEV_MOUSE:
335 ctrl_data[i].mask = cdi_mouse_mask;
336 ctrl_data[i].desc = cdi_mouse_desc;
337 ctrl_data[i].axes[j].meta = &cdi_axes_meta[j];
338 break;
339 default:
340 ctrl_data[i].mask = cdi_mask;
341 ctrl_data[i].desc = cdi_desc;
342 ctrl_data[i].axes[j].meta = &cdi_axes_meta[j];
343 break;
344 }
345 }
346 exit_axes_loop:
347 ;
348 }
349 }
350
351 void cdi_ctrl_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
352 struct cdi_map map_tmp;
353 int32_t *raw_axes = (int32_t *)(wired_data->output + 8);
354
355 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
356
357 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
358 if (ctrl_data->map_mask[0] & BIT(i)) {
359 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
360 map_tmp.buttons |= cdi_btns_mask[i];
361 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
362 }
363 else {
364 map_tmp.buttons &= ~cdi_btns_mask[i];
365 wired_data->cnt_mask[i] = 0;
366 }
367 }
368 }
369
370 for (uint32_t i = 0; i < 2; i++) {
371 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & cdi_desc[0])) {
372 map_tmp.relative[cdi_axes_idx[i]] = 0;
373 raw_axes[cdi_axes_idx[i]] = ctrl_data->axes[i].value;
374 }
375 wired_data->cnt_mask[axis_to_btn_id(i)] = ctrl_data->axes[i].cnt_mask;
376 }
377
378 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
379
380 TESTS_CMDS_LOG("\"wired_output\": {\"axes\": [%ld, %ld], \"btns\": %d},\n",
381 raw_axes[cdi_axes_idx[0]], raw_axes[cdi_axes_idx[1]], map_tmp.buttons);
382 BT_MON_LOG("\"wired_output\": {\"axes\": [%08lX, %08lX], \"btns\": %02X},\n",
383 raw_axes[cdi_axes_idx[0]], raw_axes[cdi_axes_idx[1]], map_tmp.buttons);
384 }
385
386 static void cdi_mouse_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
387 struct cdi_map map_tmp;
388 int32_t *raw_axes = (int32_t *)(wired_data->output + 8);
389
390 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
391
392 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
393 if (ctrl_data->map_mask[0] & BIT(i)) {
394 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
395 map_tmp.buttons |= cdi_mouse_btns_mask[i];
396 }
397 else {
398 map_tmp.buttons &= ~cdi_mouse_btns_mask[i];
399 }
400 }
401 }
402
403 for (uint32_t i = 2; i < 4; i++) {
404 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & cdi_mouse_desc[0])) {
405 if (ctrl_data->axes[i].relative) {
406 map_tmp.relative[cdi_axes_idx[i]] = 1;
407 atomic_add(&raw_axes[cdi_axes_idx[i]], ctrl_data->axes[i].value);
408 }
409 else {
410 map_tmp.relative[cdi_axes_idx[i]] = 0;
411 raw_axes[cdi_axes_idx[i]] = ctrl_data->axes[i].value;
412 }
413 }
414 }
415
416 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
417 }
418
419 static void cdi_kb_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
420 if (!atomic_test_bit(&wired_data->flags, WIRED_KBMON_INIT)) {
421 kbmon_init(ctrl_data->index, cdi_kb_id_to_scancode);
422 kbmon_set_typematic(ctrl_data->index, 1, 500000, 90000);
423 atomic_set_bit(&wired_data->flags, WIRED_KBMON_INIT);
424 }
425 kbmon_update(ctrl_data->index, ctrl_data);
426 }
427
428 void cdi_kb_id_to_scancode(uint32_t dev_id, uint8_t type, uint8_t id) {
429 if (id < KBM_MAX) {
430 uint8_t kb_buf[3] = {0};
431 uint8_t scancode, change = 0;
432 uint8_t *special = &wired_adapter.data[dev_id].output[4];
433 uint8_t char_set = 0x00;
434
435 /* Update status of special keys */
436 if (type == KBMON_TYPE_MAKE) {
437 switch (id) {
438 case KB_LSHIFT:
439 case KB_RSHIFT:
440 *special |= CDI_KB_SHIFT;
441 change = 1;
442 break;
443 case KB_CAPSLOCK:
444 *special ^= CDI_KB_CAPS;
445 change = 1;
446 break;
447 case KB_LALT:
448 case KB_RALT:
449 *special |= CDI_KB_ALT;
450 change = 1;
451 break;
452 case KB_LCTRL:
453 case KB_RCTRL:
454 *special |= CDI_KB_CTRL;
455 change = 1;
456 break;
457 }
458 }
459 else {
460 switch (id) {
461 case KB_LSHIFT:
462 case KB_RSHIFT:
463 *special &= ~CDI_KB_SHIFT;
464 change = 1;
465 break;
466 case KB_LALT:
467 case KB_RALT:
468 *special &= ~CDI_KB_ALT;
469 change = 1;
470 break;
471 case KB_LCTRL:
472 case KB_RCTRL:
473 *special &= ~CDI_KB_CTRL;
474 change = 1;
475 break;
476 }
477 }
478
479 /* Get keycode base on status of special keys */
480 switch (*special & ~CDI_KB_CAPS) {
481 case CDI_KB_SHIFT:
482 scancode = cdi_kb_code_shift[id];
483 if ((*special & CDI_KB_CAPS) && ((scancode >= 0x41 && scancode <= 0x5A) || (scancode >= 0x61 && scancode <= 0x7A))) {
484 scancode = cdi_kb_code_normal[id];
485 }
486 break;
487 case CDI_KB_ALT:
488 scancode = cdi_kb_code_alt[id];
489 break;
490 case CDI_KB_CTRL:
491 scancode = cdi_kb_code_ctrl[id];
492 break;
493 case CDI_KB_CTRL | CDI_KB_ALT:
494 scancode = cdi_kb_code_ctrl_alt[id];
495 break;
496 case CDI_KB_SHIFT | CDI_KB_ALT:
497 scancode = cdi_kb_code_shift_alt[id];
498 break;
499 default:
500 scancode = cdi_kb_code_normal[id];
501 if ((*special & CDI_KB_CAPS) && ((scancode >= 0x41 && scancode <= 0x5A) || (scancode >= 0x61 && scancode <= 0x7A))) {
502 scancode = cdi_kb_code_shift[id];
503 }
504 break;
505 }
506
507 /* Extended keys */
508 if ((id >= KB_F9 && id <= KB_INSERT) || (id >= KB_PAGEUP && id <= KB_PAGEDOWN) || (id >= KB_KP_DIV && id <= KB_KP_ENTER)) {
509 if (config.out_cfg[dev_id].acc_mode == ACC_MEM) { // If type 'Z' KB
510 char_set = 0x01;
511 }
512 else {
513 return;
514 }
515 }
516
517 if (scancode) {
518 switch (type) {
519 case KBMON_TYPE_MAKE:
520 kb_buf[0] = *special;
521 kb_buf[1] = char_set;
522 kb_buf[2] = scancode;
523 break;
524 case KBMON_TYPE_BREAK:
525 kb_buf[0] = *special;
526 kb_buf[1] = 0x01;
527 kb_buf[2] = 0x00;
528 if (config.out_cfg[dev_id].acc_mode == ACC_RUMBLE) { // If type 'T' KB
529 if (id >= KB_F1 && id <= KB_F8) {
530 kb_buf[2] = scancode;
531 }
532 }
533 break;
534 }
535 change = 1;
536 }
537 else if (change) {
538 /* Update special keys only */
539 kb_buf[0] = *special;
540 kb_buf[1] = 0x01;
541 kb_buf[2] = 0x00;
542 }
543
544 if (change) {
545 kbmon_set_code(dev_id, kb_buf, 3);
546 }
547 }
548 }
549
550 void cdi_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
551 switch (dev_mode) {
552 case DEV_KB:
553 cdi_kb_from_generic(ctrl_data, wired_data);
554 break;
555 case DEV_MOUSE:
556 cdi_mouse_from_generic(ctrl_data, wired_data);
557 break;
558 default:
559 cdi_ctrl_from_generic(ctrl_data, wired_data);
560 break;
561 }
562 }
563
564 void IRAM_ATTR cdi_gen_turbo_mask(struct wired_data *wired_data) {
565 struct cdi_map *map_mask = (struct cdi_map *)wired_data->output_mask;
566
567 memset(map_mask, 0xFF, sizeof(*map_mask));
568
569 for (uint32_t i = 0; i < ARRAY_SIZE(cdi_btns_mask); i++) {
570 uint8_t mask = wired_data->cnt_mask[i] >> 1;
571
572 if (cdi_btns_mask[i] && mask) {
573 if (wired_data->cnt_mask[i] & 1) {
574 if (!(mask & wired_data->frame_cnt)) {
575 map_mask->buttons &= ~cdi_btns_mask[i];
576 }
577 }
578 else {
579 if (!((mask & wired_data->frame_cnt) == mask)) {
580 map_mask->buttons &= ~cdi_btns_mask[i];
581 }
582 }
583 }
584 }
585
586 for (uint32_t i = 0; i < 2; i++) {
587 uint8_t btn_id = axis_to_btn_id(i);
588 uint8_t mask = wired_data->cnt_mask[btn_id] >> 1;
589 if (mask) {
590 if (wired_data->cnt_mask[btn_id] & 1) {
591 if (!(mask & wired_data->frame_cnt)) {
592 map_mask->raw_axes[cdi_axes_idx[i]] = cdi_axes_meta[i].neutral;
593 }
594 }
595 else {
596 if (!((mask & wired_data->frame_cnt) == mask)) {
597 map_mask->raw_axes[cdi_axes_idx[i]] = cdi_axes_meta[i].neutral;
598 }
599 }
600 }
601 }
602 }
603