keyboards/xwhatsit/ibm/f107: added missing key
[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>
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
31extern 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
33static const uint8_t magic[] = UTIL_COMM_MAGIC;
34
35void 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