util: added another note to monitor window
[jackhill/qmk/firmware.git] / keyboards / xwhatsit / util_comm.c
CommitLineData
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
34extern 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
36static const uint8_t magic[] = UTIL_COMM_MAGIC;
37
38void 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}