1 /* Copyright 2020 Purdea Andrei
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.
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.
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/>.
19 #include "util_comm.h"
20 #include "matrix_manipulate.h"
22 #include <tmk_core/common/eeprom.h>
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."
32 #define min(x, y) (((x) < (y))?(x):(y))
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.
36 static const uint8_t magic
[] = UTIL_COMM_MAGIC
;
38 void raw_hid_receive(uint8_t *data
, uint8_t length
) {
39 if (0 != memcmp(data
, magic
, sizeof(magic
))) {
42 uint8_t response
[RAW_EPSIZE
];
43 memcpy(response
, magic
, sizeof(magic
));
44 response
[2] = UTIL_COMM_RESPONSE_ERROR
;
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;
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;
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;
64 case UTIL_COMM_ENTER_BOOTLOADER
:
65 keyboard_scan_enabled
= 0;
68 // we should not be reaching the following:
70 response
[2] = UTIL_COMM_RESPONSE_OK
;
72 case UTIL_COMM_GET_KEYSTATE
:
73 response
[2] = UTIL_COMM_RESPONSE_OK
;
75 matrix_row_t current_matrix
[MATRIX_ROWS
];
76 matrix_scan_raw(current_matrix
);
77 char *current_matrix_ptr
= (char *)current_matrix
;
79 if (sizeof(current_matrix
) > 32-3)
82 current_matrix_ptr
+= offset
;
84 memcpy(&response
[3], current_matrix_ptr
, min(32-3, sizeof(current_matrix
)-offset
));
87 case UTIL_COMM_GET_THRESHOLDS
:
88 response
[2] = UTIL_COMM_RESPONSE_OK
;
89 #if CAPSENSE_CAL_ENABLED
90 response
[3] = CAPSENSE_CAL_BINS
;
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
];
97 if (sizeof(assigned_to_threshold
[cal_bin
]) > 32-6)
100 assigned_to_threshold_ptr
+= offset
;
102 memcpy(&response
[6], assigned_to_threshold_ptr
, min(32-6, sizeof(assigned_to_threshold
[cal_bin
]) - offset
));
106 response
[4] = (CAPSENSE_HARDCODED_THRESHOLD
) & 0xff;
107 response
[5] = ((CAPSENSE_HARDCODED_THRESHOLD
) >> 8) & 0xff;
110 case UTIL_COMM_GET_KEYBOARD_FILENAME
:
112 response
[2] = UTIL_COMM_RESPONSE_OK
;
113 if (data
[3] >= strlen(KEYBOARD_FILENAME
) + 1)
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
);
124 case UTIL_COMM_ERASE_EEPROM
:
126 response
[2] = UTIL_COMM_RESPONSE_OK
;
128 for (addr
=0; addr
<E2END
; addr
+= 1)
130 eeprom_update_byte((uint8_t*)addr
, 0xff);
134 case UTIL_COMM_GET_SIGNAL_VALUE
:
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];
141 for (i
=0;i
<count
;i
++)
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;
147 if (col
>= MATRIX_COLS
) {
151 if (row
>= MATRIX_ROWS
)
158 case UTIL_COMM_GET_KEYBOARD_DETAILS
:
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)
165 #elif defined(CONTROLLER_IS_XWHATSIT_MODEL_F_OR_WCASS_MODEL_F)
167 #elif defined(CONTROLLER_IS_THROUGH_HOLE_BEAMSPRING)
169 #elif defined(CONTROLLER_IS_THROUGH_HOLE_MODEL_F)
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;
182 case UTIL_COMM_SHIFT_DATA
:
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);
192 case UTIL_COMM_SET_DAC_VALUE
:
194 response
[2] = UTIL_COMM_RESPONSE_OK
;
195 uint16_t value
= data
[3] | (((uint16_t)data
[4]) << 8);
196 dac_write_threshold(value
);
199 case UTIL_COMM_GET_ROW_STATE
:
201 response
[2] = UTIL_COMM_RESPONSE_OK
;
202 response
[3] = test_single(255, 0, NULL
);
208 raw_hid_send(response
, sizeof(response
));