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> | |
22 | ||
23 | #if defined(KEYBOARD_SHARED_EP) && defined(RAW_ENABLE) | |
24 | #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." | |
25 | #endif | |
26 | ||
27 | #ifndef RAW_EPSIZE | |
28 | #define RAW_EPSIZE 32 | |
29 | #endif | |
30 | ||
31 | 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. | |
32 | ||
33 | static const uint8_t magic[] = UTIL_COMM_MAGIC; | |
34 | ||
35 | void raw_hid_receive(uint8_t *data, uint8_t length) { | |
36 | if (0 != memcmp(data, magic, sizeof(magic))) { | |
37 | return; | |
38 | } | |
39 | uint8_t response[RAW_EPSIZE]; | |
40 | memcpy(response, magic, sizeof(magic)); | |
41 | response[2] = UTIL_COMM_RESPONSE_ERROR; | |
42 | switch (data[2]) | |
43 | { | |
44 | case UTIL_COMM_GET_VERSION: | |
45 | response[2] = UTIL_COMM_RESPONSE_OK; | |
46 | response[3] = UTIL_COMM_VERSION; | |
47 | break; | |
48 | case UTIL_COMM_DISABLE_KEYBOARD: | |
49 | response[2] = UTIL_COMM_RESPONSE_OK; | |
50 | response[3] = (uint8_t) keyboard_scan_enabled; | |
51 | keyboard_scan_enabled = 0; | |
52 | break; | |
53 | case UTIL_COMM_ENABLE_KEYBOARD: | |
54 | response[2] = UTIL_COMM_RESPONSE_OK; | |
55 | response[3] = (uint8_t) keyboard_scan_enabled; | |
56 | keyboard_scan_enabled = 1; | |
57 | break; | |
58 | case UTIL_COMM_ENTER_BOOTLOADER: | |
59 | keyboard_scan_enabled = 0; | |
60 | wait_ms(10); | |
61 | bootloader_jump(); | |
62 | // we should not be reaching the following: | |
63 | wait_ms(10); | |
64 | response[2] = UTIL_COMM_RESPONSE_OK; | |
65 | break; | |
66 | case UTIL_COMM_GET_KEYSTATE: | |
67 | response[2] = UTIL_COMM_RESPONSE_OK; | |
68 | #if 1 | |
69 | 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. | |
70 | #else | |
71 | { | |
72 | matrix_row_t current_matrix[MATRIX_ROWS]; | |
73 | matrix_scan_raw(current_matrix); | |
74 | memcpy(&response[3], current_matrix, sizeof(current_matrix)); | |
75 | } | |
76 | #endif | |
77 | break; | |
78 | case UTIL_COMM_GET_THRESHOLDS: | |
79 | response[2] = UTIL_COMM_RESPONSE_OK; | |
80 | #if CAPSENSE_CAL_ENABLED | |
81 | response[3] = CAPSENSE_CAL_BINS; | |
82 | { | |
83 | const uint8_t cal_bin = data[3]; | |
84 | response[4] = cal_thresholds[cal_bin] & 0xff; | |
85 | response[5] = (cal_thresholds[cal_bin] >> 8) & 0xff; | |
86 | memcpy(&response[6], assigned_to_threshold[cal_bin], sizeof(assigned_to_threshold[cal_bin])); | |
87 | } | |
88 | #else | |
89 | response[3] = 0; | |
90 | response[4] = CAPSENSE_HARDCODED_THRESHOLD; | |
91 | #endif | |
92 | break; | |
93 | case UTIL_COMM_GET_KEYBOARD_FILENAME: | |
94 | { | |
95 | response[2] = UTIL_COMM_GET_KEYBOARD_FILENAME; | |
96 | const char *substring = KEYBOARD_FILENAME + data[3]; | |
97 | size_t substring_length = strlen(substring) + 1; | |
98 | if (substring_length > RAW_EPSIZE - 3) substring_length = RAW_EPSIZE - 3; | |
99 | memcpy(&response[3], substring, substring_length); | |
100 | break; | |
101 | } | |
102 | default: | |
103 | break; | |
104 | } | |
105 | raw_hid_send(response, sizeof(response)); | |
106 | } | |
107 |