Commit | Line | Data |
---|---|---|
38e6feca PA |
1 | /* Copyright 2020 Purdea Andrei |
2 | * | |
3 | * This program is free software: you can redistribute it and/or modify | |
4 | * it under the terms of the GNU General Public License as published by | |
5 | * the Free Software Foundation, either version 2 of the License, or | |
6 | * (at your option) any later version. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | */ | |
16 | ||
17 | #include "quantum.h" | |
18 | #include "raw_hid.h" | |
19 | #include "util_comm.h" | |
20 | #include "matrix_manipulate.h" | |
21 | #include <string.h> | |
d48eeb39 | 22 | #include <tmk_core/common/eeprom.h> |
38e6feca PA |
23 | |
24 | #if defined(KEYBOARD_SHARED_EP) && defined(RAW_ENABLE) | |
25 | #error "Enabling the KEYBOARD_SHARED_EP will make the util be unable to communicate with the firmware, because due to hidapi limiations, the util can't figure out which interface to talk to, so it hardcodes interface zero." | |
26 | #endif | |
27 | ||
28 | #ifndef RAW_EPSIZE | |
29 | #define RAW_EPSIZE 32 | |
30 | #endif | |
31 | ||
3134f10c PA |
32 | #define min(x, y) (((x) < (y))?(x):(y)) |
33 | ||
38e6feca PA |
34 | extern const char *KEYBOARD_FILENAME; // This must be defined in keyboard_name.c to equal the filename. This is sent back to the PC-side software for it to determine which keyboard we are using. |
35 | ||
36 | static const uint8_t magic[] = UTIL_COMM_MAGIC; | |
37 | ||
38 | void raw_hid_receive(uint8_t *data, uint8_t length) { | |
39 | if (0 != memcmp(data, magic, sizeof(magic))) { | |
40 | return; | |
41 | } | |
42 | uint8_t response[RAW_EPSIZE]; | |
43 | memcpy(response, magic, sizeof(magic)); | |
44 | response[2] = UTIL_COMM_RESPONSE_ERROR; | |
45 | switch (data[2]) | |
46 | { | |
47 | case UTIL_COMM_GET_VERSION: | |
48 | response[2] = UTIL_COMM_RESPONSE_OK; | |
ec75ada7 PA |
49 | response[3] = UTIL_COMM_VERSION_MAJOR; |
50 | response[4] = UTIL_COMM_VERSION_MID; | |
51 | response[5] = (UTIL_COMM_VERSION_MINOR >> 8) & 0xff; | |
52 | response[6] = (UTIL_COMM_VERSION_MINOR >> 0) & 0xff; | |
38e6feca PA |
53 | break; |
54 | case UTIL_COMM_DISABLE_KEYBOARD: | |
55 | response[2] = UTIL_COMM_RESPONSE_OK; | |
56 | response[3] = (uint8_t) keyboard_scan_enabled; | |
57 | keyboard_scan_enabled = 0; | |
58 | break; | |
59 | case UTIL_COMM_ENABLE_KEYBOARD: | |
60 | response[2] = UTIL_COMM_RESPONSE_OK; | |
61 | response[3] = (uint8_t) keyboard_scan_enabled; | |
62 | keyboard_scan_enabled = 1; | |
63 | break; | |
64 | case UTIL_COMM_ENTER_BOOTLOADER: | |
65 | keyboard_scan_enabled = 0; | |
66 | wait_ms(10); | |
67 | bootloader_jump(); | |
68 | // we should not be reaching the following: | |
69 | wait_ms(10); | |
70 | response[2] = UTIL_COMM_RESPONSE_OK; | |
71 | break; | |
72 | case UTIL_COMM_GET_KEYSTATE: | |
73 | response[2] = UTIL_COMM_RESPONSE_OK; | |
3134f10c PA |
74 | { |
75 | matrix_row_t current_matrix[MATRIX_ROWS]; | |
76 | matrix_scan_raw(current_matrix); | |
77 | char *current_matrix_ptr = (char *)current_matrix; | |
78 | int offset = 0; | |
79 | if (sizeof(current_matrix) > 32-3) | |
38e6feca | 80 | { |
3134f10c PA |
81 | offset = data[3]; |
82 | current_matrix_ptr += offset; | |
38e6feca | 83 | } |
3134f10c PA |
84 | memcpy(&response[3], current_matrix_ptr, min(32-3, sizeof(current_matrix)-offset)); |
85 | } | |
38e6feca PA |
86 | break; |
87 | case UTIL_COMM_GET_THRESHOLDS: | |
88 | response[2] = UTIL_COMM_RESPONSE_OK; | |
89 | #if CAPSENSE_CAL_ENABLED | |
90 | response[3] = CAPSENSE_CAL_BINS; | |
91 | { | |
92 | const uint8_t cal_bin = data[3]; | |
93 | response[4] = cal_thresholds[cal_bin] & 0xff; | |
94 | response[5] = (cal_thresholds[cal_bin] >> 8) & 0xff; | |
3134f10c PA |
95 | char *assigned_to_threshold_ptr = (char *)assigned_to_threshold[cal_bin]; |
96 | int offset = 0; | |
97 | if (sizeof(assigned_to_threshold[cal_bin]) > 32-6) | |
98 | { | |
99 | offset = data[4]; | |
100 | assigned_to_threshold_ptr += offset; | |
101 | } | |
102 | memcpy(&response[6], assigned_to_threshold_ptr, min(32-6, sizeof(assigned_to_threshold[cal_bin]) - offset)); | |
38e6feca PA |
103 | } |
104 | #else | |
105 | response[3] = 0; | |
f3c5c8cf PA |
106 | response[4] = (CAPSENSE_HARDCODED_THRESHOLD) & 0xff; |
107 | response[5] = ((CAPSENSE_HARDCODED_THRESHOLD) >> 8) & 0xff; | |
38e6feca PA |
108 | #endif |
109 | break; | |
110 | case UTIL_COMM_GET_KEYBOARD_FILENAME: | |
111 | { | |
f3c5c8cf | 112 | response[2] = UTIL_COMM_RESPONSE_OK; |
9db10068 PA |
113 | if (data[3] >= strlen(KEYBOARD_FILENAME) + 1) |
114 | { | |
115 | response[3] = 0; | |
116 | } else { | |
117 | const char *substring = KEYBOARD_FILENAME + data[3]; | |
118 | size_t substring_length = strlen(substring) + 1; | |
119 | if (substring_length > RAW_EPSIZE - 3) substring_length = RAW_EPSIZE - 3; | |
120 | memcpy(&response[3], substring, substring_length); | |
121 | } | |
38e6feca PA |
122 | break; |
123 | } | |
d48eeb39 PA |
124 | case UTIL_COMM_ERASE_EEPROM: |
125 | { | |
126 | response[2] = UTIL_COMM_RESPONSE_OK; | |
127 | uint16_t addr; | |
128 | for (addr=0; addr<E2END; addr += 1) | |
129 | { | |
130 | eeprom_update_byte((uint8_t*)addr, 0xff); | |
131 | } | |
a171da13 PA |
132 | break; |
133 | } | |
134 | case UTIL_COMM_GET_SIGNAL_VALUE: | |
135 | { | |
136 | response[2] = UTIL_COMM_RESPONSE_OK; | |
137 | uint8_t col = data[3]; | |
138 | uint8_t row = data[4]; | |
139 | uint8_t count = data[5]; | |
140 | int i; | |
141 | for (i=0;i<count;i++) | |
142 | { | |
0ee7bdb5 | 143 | uint16_t value = measure_middle_keymap_coords(col, row, CAPSENSE_HARDCODED_SAMPLE_TIME, 8); |
a171da13 PA |
144 | response[3+i*2] = value & 0xff; |
145 | response[3+i*2+1] = (value >> 8) & 0xff; | |
146 | col += 1; | |
147 | if (col >= MATRIX_COLS) { | |
148 | col -= MATRIX_COLS; | |
149 | row += 1; | |
150 | } | |
151 | if (row >= MATRIX_ROWS) | |
152 | { | |
153 | break; | |
154 | } | |
155 | } | |
156 | break; | |
157 | } | |
158 | case UTIL_COMM_GET_KEYBOARD_DETAILS: | |
159 | { | |
160 | response[2] = UTIL_COMM_RESPONSE_OK; | |
161 | response[3] = MATRIX_COLS; | |
162 | response[4] = MATRIX_ROWS; | |
163 | #if defined(CONTROLLER_IS_XWHATSIT_BEAMSPRING_REV_4) | |
164 | response[5] = 1; | |
165 | #elif defined(CONTROLLER_IS_XWHATSIT_MODEL_F_OR_WCASS_MODEL_F) | |
166 | response[5] = 2; | |
14466d90 | 167 | #elif defined(CONTROLLER_IS_THROUGH_HOLE_BEAMSPRING) |
8e2b95b6 | 168 | response[5] = 3; |
14466d90 | 169 | #elif defined(CONTROLLER_IS_THROUGH_HOLE_MODEL_F) |
8e2b95b6 | 170 | response[5] = 4; |
a171da13 PA |
171 | #else |
172 | response[5] = 0; | |
173 | #endif | |
174 | response[6] = CAPSENSE_KEYBOARD_SETTLE_TIME_US; | |
175 | response[7] = CAPSENSE_DAC_SETTLE_TIME_US; | |
176 | response[8] = CAPSENSE_HARDCODED_SAMPLE_TIME; | |
177 | response[9] = CAPSENSE_CAL_ENABLED; | |
fd28099f PA |
178 | response[10] = CAPSENSE_DAC_MAX & 0xFF; |
179 | response[11] = (CAPSENSE_DAC_MAX >> 8) & 0xFF; | |
a171da13 | 180 | break; |
d48eeb39 | 181 | } |
773b7610 PA |
182 | case UTIL_COMM_SHIFT_DATA: |
183 | { | |
184 | response[2] = UTIL_COMM_RESPONSE_OK; | |
185 | uint32_t shdata = (((uint32_t)(data[3])) << 0) | | |
186 | (((uint32_t)(data[4])) << 8) | | |
187 | (((uint32_t)(data[5])) << 16) | | |
188 | (((uint32_t)(data[6])) << 24); | |
189 | shift_data(shdata); | |
fd28099f PA |
190 | break; |
191 | } | |
192 | case UTIL_COMM_SET_DAC_VALUE: | |
193 | { | |
194 | response[2] = UTIL_COMM_RESPONSE_OK; | |
195 | uint16_t value = data[3] | (((uint16_t)data[4]) << 8); | |
196 | dac_write_threshold(value); | |
197 | break; | |
198 | } | |
199 | case UTIL_COMM_GET_ROW_STATE: | |
200 | { | |
201 | response[2] = UTIL_COMM_RESPONSE_OK; | |
202 | response[3] = test_single(255, 0, NULL); | |
203 | break; | |
773b7610 | 204 | } |
38e6feca PA |
205 | default: |
206 | break; | |
207 | } | |
208 | raw_hid_send(response, sizeof(response)); | |
209 | } |