brand_new_model_f: fixing typo in product descriptor string
[jackhill/qmk/firmware.git] / keyboards / xwhatsit / util_comm.c
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>
22 #include <tmk_core/common/eeprom.h>
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
32 #define min(x, y) (((x) < (y))?(x):(y))
33
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;
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;
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;
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)
80 {
81 offset = data[3];
82 current_matrix_ptr += offset;
83 }
84 memcpy(&response[3], current_matrix_ptr, min(32-3, sizeof(current_matrix)-offset));
85 }
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;
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));
103 }
104 #else
105 response[3] = 0;
106 response[4] = (CAPSENSE_HARDCODED_THRESHOLD) & 0xff;
107 response[5] = ((CAPSENSE_HARDCODED_THRESHOLD) >> 8) & 0xff;
108 #endif
109 break;
110 case UTIL_COMM_GET_KEYBOARD_FILENAME:
111 {
112 response[2] = UTIL_COMM_RESPONSE_OK;
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 }
122 break;
123 }
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 }
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 {
143 uint16_t value = measure_middle_keymap_coords(col, row, CAPSENSE_HARDCODED_SAMPLE_TIME, 8);
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;
167 #elif defined(CONTROLLER_IS_THROUGH_HOLE_BEAMSPRING)
168 response[5] = 3;
169 #elif defined(CONTROLLER_IS_THROUGH_HOLE_MODEL_F)
170 response[5] = 4;
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;
178 response[10] = CAPSENSE_DAC_MAX & 0xFF;
179 response[11] = (CAPSENSE_DAC_MAX >> 8) & 0xFF;
180 break;
181 }
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);
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;
204 }
205 default:
206 break;
207 }
208 raw_hid_send(response, sizeof(response));
209 }