xwhatsit util_comm: make get signal value reps smaller to increase refresh rate at...
[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
32extern 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.
33
34static const uint8_t magic[] = UTIL_COMM_MAGIC;
35
36void raw_hid_receive(uint8_t *data, uint8_t length) {
37 if (0 != memcmp(data, magic, sizeof(magic))) {
38 return;
39 }
40 uint8_t response[RAW_EPSIZE];
41 memcpy(response, magic, sizeof(magic));
42 response[2] = UTIL_COMM_RESPONSE_ERROR;
43 switch (data[2])
44 {
45 case UTIL_COMM_GET_VERSION:
46 response[2] = UTIL_COMM_RESPONSE_OK;
ec75ada7
PA
47 response[3] = UTIL_COMM_VERSION_MAJOR;
48 response[4] = UTIL_COMM_VERSION_MID;
49 response[5] = (UTIL_COMM_VERSION_MINOR >> 8) & 0xff;
50 response[6] = (UTIL_COMM_VERSION_MINOR >> 0) & 0xff;
38e6feca
PA
51 break;
52 case UTIL_COMM_DISABLE_KEYBOARD:
53 response[2] = UTIL_COMM_RESPONSE_OK;
54 response[3] = (uint8_t) keyboard_scan_enabled;
55 keyboard_scan_enabled = 0;
56 break;
57 case UTIL_COMM_ENABLE_KEYBOARD:
58 response[2] = UTIL_COMM_RESPONSE_OK;
59 response[3] = (uint8_t) keyboard_scan_enabled;
60 keyboard_scan_enabled = 1;
61 break;
62 case UTIL_COMM_ENTER_BOOTLOADER:
63 keyboard_scan_enabled = 0;
64 wait_ms(10);
65 bootloader_jump();
66 // we should not be reaching the following:
67 wait_ms(10);
68 response[2] = UTIL_COMM_RESPONSE_OK;
69 break;
70 case UTIL_COMM_GET_KEYSTATE:
71 response[2] = UTIL_COMM_RESPONSE_OK;
72 #if 1
73 matrix_scan_raw((matrix_row_t *)&response[3]); // AVR doesn't require not-byte values to be aligned, so this is correct, and it's an optimization.
74 #else
75 {
76 matrix_row_t current_matrix[MATRIX_ROWS];
77 matrix_scan_raw(current_matrix);
78 memcpy(&response[3], current_matrix, sizeof(current_matrix));
79 }
80 #endif
81 break;
82 case UTIL_COMM_GET_THRESHOLDS:
83 response[2] = UTIL_COMM_RESPONSE_OK;
84 #if CAPSENSE_CAL_ENABLED
85 response[3] = CAPSENSE_CAL_BINS;
86 {
87 const uint8_t cal_bin = data[3];
88 response[4] = cal_thresholds[cal_bin] & 0xff;
89 response[5] = (cal_thresholds[cal_bin] >> 8) & 0xff;
90 memcpy(&response[6], assigned_to_threshold[cal_bin], sizeof(assigned_to_threshold[cal_bin]));
91 }
92 #else
93 response[3] = 0;
f3c5c8cf
PA
94 response[4] = (CAPSENSE_HARDCODED_THRESHOLD) & 0xff;
95 response[5] = ((CAPSENSE_HARDCODED_THRESHOLD) >> 8) & 0xff;
38e6feca
PA
96 #endif
97 break;
98 case UTIL_COMM_GET_KEYBOARD_FILENAME:
99 {
f3c5c8cf 100 response[2] = UTIL_COMM_RESPONSE_OK;
9db10068
PA
101 if (data[3] >= strlen(KEYBOARD_FILENAME) + 1)
102 {
103 response[3] = 0;
104 } else {
105 const char *substring = KEYBOARD_FILENAME + data[3];
106 size_t substring_length = strlen(substring) + 1;
107 if (substring_length > RAW_EPSIZE - 3) substring_length = RAW_EPSIZE - 3;
108 memcpy(&response[3], substring, substring_length);
109 }
38e6feca
PA
110 break;
111 }
d48eeb39
PA
112 case UTIL_COMM_ERASE_EEPROM:
113 {
114 response[2] = UTIL_COMM_RESPONSE_OK;
115 uint16_t addr;
116 for (addr=0; addr<E2END; addr += 1)
117 {
118 eeprom_update_byte((uint8_t*)addr, 0xff);
119 }
a171da13
PA
120 break;
121 }
122 case UTIL_COMM_GET_SIGNAL_VALUE:
123 {
124 response[2] = UTIL_COMM_RESPONSE_OK;
125 uint8_t col = data[3];
126 uint8_t row = data[4];
127 uint8_t count = data[5];
128 int i;
129 for (i=0;i<count;i++)
130 {
0ee7bdb5 131 uint16_t value = measure_middle_keymap_coords(col, row, CAPSENSE_HARDCODED_SAMPLE_TIME, 8);
a171da13
PA
132 response[3+i*2] = value & 0xff;
133 response[3+i*2+1] = (value >> 8) & 0xff;
134 col += 1;
135 if (col >= MATRIX_COLS) {
136 col -= MATRIX_COLS;
137 row += 1;
138 }
139 if (row >= MATRIX_ROWS)
140 {
141 break;
142 }
143 }
144 break;
145 }
146 case UTIL_COMM_GET_KEYBOARD_DETAILS:
147 {
148 response[2] = UTIL_COMM_RESPONSE_OK;
149 response[3] = MATRIX_COLS;
150 response[4] = MATRIX_ROWS;
151 #if defined(CONTROLLER_IS_XWHATSIT_BEAMSPRING_REV_4)
152 response[5] = 1;
153 #elif defined(CONTROLLER_IS_XWHATSIT_MODEL_F_OR_WCASS_MODEL_F)
154 response[5] = 2;
155 #else
156 response[5] = 0;
157 #endif
158 response[6] = CAPSENSE_KEYBOARD_SETTLE_TIME_US;
159 response[7] = CAPSENSE_DAC_SETTLE_TIME_US;
160 response[8] = CAPSENSE_HARDCODED_SAMPLE_TIME;
161 response[9] = CAPSENSE_CAL_ENABLED;
162 break;
d48eeb39 163 }
38e6feca
PA
164 default:
165 break;
166 }
167 raw_hid_send(response, sizeof(response));
168}