This commit is contained in:
peepeetee 2025-07-16 17:38:43 -04:00 committed by GitHub
commit b47ea8f7ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 789 additions and 0 deletions

View File

@ -0,0 +1,5 @@
as of 126dc933b203435abb76081603b8fa7978f4181d the SMD keys no longer work
at the start, all keys are outputted in order --> initialization or infinite loop
analogReadPin limits our options, I would like to change hybrid_key_t to include weather it is a hall effect key

View File

@ -0,0 +1,40 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
2024 peepeetee (@peepeetee)
2024 minisbett (@minisbett)
2025 Jenna Fligor (@Ex-32)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <stdint.h>
#include <stdbool.h>
enum analog_key_modes {
dynamic_actuation = 0,
continuous_dynamic_actuation = 1,
static_actuation = 2,
flashing = 3,
};
/* global struct to save keypress logic params */
typedef struct {
uint8_t mode;
uint8_t actuation_point;
uint8_t press_sensitivity;
uint8_t release_sensitivity;
uint8_t press_hysteresis;
uint8_t release_hysteresis;
} analog_config; /* 6 bytes */
//size defined in config.h
_Static_assert(sizeof(analog_config) == EECONFIG_KB_DATA_SIZE, "Size mismatch");
extern analog_config g_config;
typedef struct {
/* For individual analog key data */
uint16_t value;
uint16_t extremum;
int16_t offset;
bool is_analog;
bool continuous_dynamic_actuation;
} hybrid_key_t;
extern hybrid_key_t keys[MATRIX_ROWS][MATRIX_COLS];

View File

@ -0,0 +1,16 @@
// Copyright 2023 peepeetee (@peepeetee) RephlexZero (@RephlexZero)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define DYNAMIC_KEYMAP_LAYER_COUNT 1
#define EECONFIG_KB_DATA_SIZE 6
#define DEBUG_ENABLE
// #define DEBUG_MATRIX_SCAN_RATE
#define ADC_RESOLUTION 12
#define ADC_RESOLUTION_MAX 4096 //1 << 12
#define CALIBRATION_RANGE 255

View File

@ -0,0 +1,13 @@
/* Copyright 2024 Jenna Fligor (@Ex-32)
SPDX-License-Identifier: GPL-2.0-or-later */
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include "lut.h"
int main() {
__builtin_trap();
return 0;
}

View File

@ -0,0 +1,8 @@
/* Copyright 2023 peepeetee (@peepeetee)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#undef HAL_USE_ADC
#define HAL_USE_ADC TRUE
#include_next <halconf.h>

View File

@ -0,0 +1,106 @@
{
"manufacturer": "momokai",
"keyboard_name": "tap_trio_pro",
"maintainer": "peepeetee",
"bootloader": "rp2040",
"bootmagic": {
"matrix": [1, 0]
},
"debounce": 0,
"features": {
"bootmagic": true,
"console": true,
"debug": true,
"deferred_exec": true,
"extrakey": true,
"mousekey": true,
"nkro": true,
"oled": true,
"rgb_matrix": true
},
"matrix_pins": {
"direct": [
["GP28", "GP27", "GP26"],
["GP10", "GP9", "GP8"]
]
},
"processor": "RP2040",
"rgb_matrix": {
"animations": {
"alphas_mods": true,
"band_pinwheel_sat": true,
"band_pinwheel_val": true,
"band_sat": true,
"band_spiral_sat": true,
"band_spiral_val": true,
"band_val": true,
"breathing": true,
"cycle_all": true,
"cycle_left_right": true,
"cycle_out_in": true,
"cycle_out_in_dual": true,
"cycle_pinwheel": true,
"cycle_spiral": true,
"cycle_up_down": true,
"digital_rain": true,
"dual_beacon": true,
"gradient_left_right": true,
"gradient_up_down": true,
"hue_breathing": true,
"hue_pendulum": true,
"hue_wave": true,
"jellybean_raindrops": true,
"multisplash": true,
"pixel_flow": true,
"pixel_fractal": true,
"pixel_rain": true,
"rainbow_beacon": true,
"rainbow_moving_chevron": true,
"rainbow_pinwheels": true,
"raindrops": true,
"solid_color": true,
"solid_multisplash": true,
"solid_reactive": true,
"solid_reactive_cross": true,
"solid_reactive_multicross": true,
"solid_reactive_multinexus": true,
"solid_reactive_multiwide": true,
"solid_reactive_nexus": true,
"solid_reactive_simple": true,
"solid_reactive_wide": true,
"solid_splash": true,
"splash": true,
"typing_heatmap": true
},
"driver": "ws2812",
"layout": [
{"matrix": [1, 0], "x": 0, "y": 0, "flags": 4},
{"matrix": [1, 1], "x": 0, "y": 32, "flags": 4},
{"matrix": [1, 2], "x": 0, "y": 64, "flags": 4}
],
"led_count": 3,
"sleep": true
},
"url": "https://momokai.com/",
"usb": {
"device_version": "1.0.0",
"pid": "0x0016",
"vid": "0x69F9"
},
"ws2812": {
"driver": "vendor",
"pin": "GP29"
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [1, 0], "x": 0.5, "y": 1.25, "w": 0.5, "h": 0.5},
{"matrix": [1, 1], "x": 1, "y": 1.25, "w": 0.5, "h": 0.5},
{"matrix": [1, 2], "x": 1.5, "y": 1.25, "w": 0.5, "h": 0.5}
]
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright 2023 peepeetee
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(
KC_Z, KC_X, KC_C,
KC_GRV, KC_ESC, KC_F2
)
};
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }
};
#endif

View File

@ -0,0 +1,44 @@
/* Copyright 202 RephlexZero (@RephlexZero) 2024 peepeetee (@peepeetee) 2024 Jenna Fligor (@Ex-32)
SPDX-License-Identifier: GPL-2.0-or-later */
#include <math.h>
#include <stdint.h>
#include "scanfunctions.h"
#include "util.h"
// /* Equation parameters for the sensor-magnet linearity mapping */
//https://www.desmos.com/calculator/qtbbjbsyvi
// These are values when there were 400 steps
// const double lut_a = -366.805673399;
// const double lut_b = 0.00617870508512;
// const double lut_c = -1.49468890703;
// const double lut_d = 2094.38794157;
//Values for 256 steps
const double lut_a = -0.203212;
const double lut_b = 0.00955995;
const double lut_c = 5.99691;
const double lut_d = 2122.25924;
uint16_t distance_to_adc(uint16_t distance) {
double intermediate = lut_a * exp(lut_b * distance + lut_c) + lut_d;
return (uint16_t) fmax(0, fmin(intermediate, 4095));
}
uint16_t adc_to_distance(uint16_t adc) {
double check = (adc - lut_d) / lut_a;
if (check <= 0) {
return 0;
}
double intermediate = (log(check) - lut_c) / lut_b;
return (uint16_t) fmax(0, fmin(intermediate, 255));
}
uint16_t lut[ADC_RESOLUTION_MAX] = {0};
void generate_lut(void) {
for (uint16_t i = 0; i < ADC_RESOLUTION_MAX; i++) {
lut[i] = adc_to_distance(i);
}
}

View File

@ -0,0 +1,17 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <stdint.h>
extern uint16_t lut[ADC_RESOLUTION_MAX];
const double lut_a;
const double lut_b;
const double lut_c;
const double lut_d;
uint16_t distance_to_adc(uint16_t distance);
uint16_t adc_to_distance(uint16_t adc);
void generate_lut(void);

View File

@ -0,0 +1,122 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
Copyright 2023 peepeetee
SPDX-License-Identifier: GPL-2.0-or-later */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "quantum.h"
#include "analog.h"
#include "lut.h"
#include "scanfunctions.h"
#include "quantum/matrix.h"
#ifndef MATRIX_INPUT_PRESSED_STATE
# define MATRIX_INPUT_PRESSED_STATE 0
#endif
// Pin and key matrix definitions
pin_t matrix_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
hybrid_key_t keys[MATRIX_ROWS][MATRIX_COLS] = {0};
static uint16_t pressedAdcValue = 0;
static uint16_t restAdcValue = 0;
/* Matrix state: 1 = on, 0 = off */
matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
matrix_row_t matrix[MATRIX_ROWS]; // debounced values
static inline uint8_t readMatrixPin(pin_t pin) {
if (pin != NO_PIN) {
return (gpio_read_pin(pin) == MATRIX_INPUT_PRESSED_STATE) ? 0 : 1;
} else {
return 1;
}
}
void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
// Start with a clear matrix row
matrix_row_t current_row_value = 0;
matrix_row_t row_shifter = MATRIX_ROW_SHIFTER;
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) {
pin_t pin = matrix_pins[current_row][col_index];
current_row_value |= readMatrixPin(pin) ? 0 : row_shifter;
}
// Update the matrix
current_matrix[current_row] = current_row_value;
}
// Setup only rows 1, leave row 0 untouched (for analog)
void matrix_init_pins(void) {
for (int row = 0; row < MATRIX_ROWS; row++) {
if (row != 0) {
for (int col = 0; col < MATRIX_COLS; col++) {
pin_t pin = matrix_pins[row][col];
if (pin != NO_PIN) {
setPinInputHigh(pin);
}
}
}
}
}
void matrix_init_custom(void) {
// Analog row setup (should ideally be done at compile time)
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
keys[0][i].is_analog = true;
// initialize_SMA_filter(&keys[1][i], SMA_FILTER_SAMPLE_EXPONENT);
}
// eeconfig_init_kb();
matrix_init_pins();
generate_lut();
pressedAdcValue = distance_to_adc(255);
restAdcValue = distance_to_adc(0);
wait_ms(100); // Let ADC reach steady state
get_sensor_offsets();
}
static matrix_row_t previous_matrix[MATRIX_ROWS];
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
memcpy(previous_matrix, current_matrix, sizeof(previous_matrix));
for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
if (current_row == 1) {
matrix_read_cols_on_row(current_matrix, current_row);
} else {
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
hybrid_key_t *key = &keys[current_row][current_col];
key->value = lut[analogReadPin(matrix_pins[current_row][current_col]) + key->offset];
switch (g_config.mode) {
case dynamic_actuation:
matrix_read_cols_dynamic_actuation(&current_matrix[current_row], current_col, key);
break;
case continuous_dynamic_actuation:
matrix_read_cols_continuous_dynamic_actuation(&current_matrix[current_row], current_col, key);
break;
case static_actuation:
matrix_read_cols_static_actuation(&current_matrix[current_row], current_col, key);
break;
case flashing:
default:
bootloader_jump();
break;
}
}
}
}
return memcmp(previous_matrix, current_matrix, sizeof(previous_matrix)) != 0;
}

View File

@ -0,0 +1,8 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include_next <mcuconf.h>
#undef RP_I2C_USE_I2C1
#define RP_I2C_USE_I2C1 TRUE

View File

@ -0,0 +1,27 @@
# momokai/tap_trio_pro
![momokai/tap_trio_pro](https://i.imgur.com/k6EqTA1.jpeg)
Tap trio pro, a 6 key macropad with 3 hall effect switches
* Keyboard Maintainer: [peepeetee](https://github.com/peepeetee)
* Hardware Supported: Tap trio pro
* Hardware Availability: https://momokai.com/
Make example for this keyboard (after setting up your build environment):
make momokai/tap_trio_pro:default
Flashing example for this keyboard:
make momokai/tap_trio_pro:default:flash
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 3 ways:
* **Bootmagic reset**: Hold down the key at (1,0) in the matrix (the left most micro switch) and plug in the keyboard
* **Physical reset button**: Hold down the BOOT1 button on the back of the PCB While plugging it in
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available

View File

@ -0,0 +1,6 @@
QUANTUM_LIB_SRC += analog.c
SRC += matrix.c lut.c scanfunctions.c
CUSTOM_MATRIX = lite
OPT = 3

View File

@ -0,0 +1,123 @@
/* Copyright 2023 RephlexZero (@RephlexZero) 2024 peepeetee (@peepeetee)
SPDX-License-Identifier: GPL-2.0-or-later */
#include "quantum.h"
#include "analog.h"
#include "scanfunctions.h"
extern pin_t matrix_pins[MATRIX_ROWS][MATRIX_COLS];
//detects sensor offsets when the key is not pressed
void get_sensor_offsets(void) {
uint16_t rest_adc_value = distance_to_adc(0);
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
for (uint8_t j = 0; j < MATRIX_COLS; j++) {
if (keys[i][j].is_analog) {
keys[i][j].offset = rest_adc_value - analogReadPin(matrix_pins[i][j]);
printf("Offset: %d\n", keys[i][j].offset);
}
}
}
}
void update_extremum(hybrid_key_t *key) {
if (key->is_analog){
key->extremum = key->value;
}
}
void register_key(matrix_row_t *current_row, uint8_t current_col) {
*current_row |= (1 << current_col);
}
void deregister_key(matrix_row_t *current_row, uint8_t current_col) {
*current_row &= ~(1 << current_col);
}
void matrix_read_cols_static_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key) {
if (*current_row & (1 << current_col)) {
if (key->value <= MAX(g_config.actuation_point - g_config.release_hysteresis, 0)) {
deregister_key(current_row, current_col);
}
} else {
if (key->value >= MIN(g_config.actuation_point + g_config.press_hysteresis, CALIBRATION_RANGE)) {
register_key(current_row, current_col);
}
}
}
/* Extremum is the highest or lowest value of the key reached
this functionality changes based on whether the key is pressed or not,
assuming your sensor value decreases when the key is pressed,
if the key is pressed, the extremum is the lowest value reached,
if the key is not pressed, the extremum is the highest value reached. */
void matrix_read_cols_dynamic_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key) {
if (key->value > g_config.actuation_point) {
/* In DA zone? */
if (*current_row & (1 << current_col)) {
/* Key is pressed
Is key still moving down? */
if (key->value > key->extremum) {
update_extremum(key);
} else if (key->value <= MAX(key->extremum - g_config.release_sensitivity, 0)) {
/* Has key moved up enough to be released? */
deregister_key(current_row, current_col);
update_extremum(key);
}
} else {
/* Key is not pressed
Is the key still moving up? */
if (key->value < key->extremum) {
update_extremum(key);
} else if (key->value >= MIN(key->extremum + g_config.press_sensitivity, CALIBRATION_RANGE)) {
/* Has key moved down enough to be pressed? */
register_key(current_row, current_col);
update_extremum(key);
}
}
} else {
/* Out of DA zone
Always deregister key */
deregister_key(current_row, current_col);
if (key->value > key->extremum) {
update_extremum(key);
}
}
}
void matrix_read_cols_continuous_dynamic_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key) {
if (key->continuous_dynamic_actuation) {
if (*current_row & (1 << current_col)) {
/* Key is pressed
Is key still moving down? */
if (key->value > key->extremum) {
update_extremum(key);
} else if (key->value <= MAX(key->extremum - g_config.release_sensitivity, 0)) {
/* Has key moved up enough to be released? */
deregister_key(current_row, current_col);
update_extremum(key);
}
} else {
/* Key is not pressed
Is the key still moving up? */
if (key->value < key->extremum) {
update_extremum(key);
} else if (key->value >= MIN(key->extremum + g_config.press_sensitivity, CALIBRATION_RANGE)) {
/* Has key moved down enough to be pressed? */
register_key(current_row, current_col);
update_extremum(key);
}
}
if (key->value == 0) {
deregister_key(current_row, current_col);
update_extremum(key);
key->continuous_dynamic_actuation = false;
}
} else if (key->value > g_config.actuation_point) {
register_key(current_row, current_col);
update_extremum(key);
key->continuous_dynamic_actuation = true;
}
}

View File

@ -0,0 +1,21 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "analogkeys.h"
#include <stdint.h>
#include "quantum.h"
#include "lut.h"
void update_extremum(hybrid_key_t *key);
void register_key(matrix_row_t *current_row, uint8_t current_col);
void deregister_key(matrix_row_t *current_row, uint8_t current_col);
void get_sensor_offsets(void);
void matrix_read_cols_dynamic_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key);
void matrix_read_cols_continuous_dynamic_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key);
void matrix_read_cols_static_actuation(matrix_row_t *current_row, uint8_t current_col, hybrid_key_t *key);

View File

@ -0,0 +1,206 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
2023 peepeetee (@peepeetee)
2025 Jenna Fligor (@Ex-32)
SPDX-License-Identifier: GPL-2.0-or-later */
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "tap_trio_pro.h"
#include "quantum.h"
#include "analog.h"
#include "eeprom.h"
#include "scanfunctions.h"
#include "print.h"
analog_config g_config = {
.mode = dynamic_actuation,
.actuation_point = 48,
.press_sensitivity = 32,
.release_sensitivity = 32,
.press_hysteresis = 0,
.release_hysteresis = 5
};
#ifdef BOOTMAGIC_ENABLE
extern pin_t matrix_pins[MATRIX_ROWS][MATRIX_COLS];
void bootmagic_lite(void) {
if (analogReadPin(matrix_pins[BOOTMAGIC_ROW][BOOTMAGIC_COLUMN]) < 1350) {
bootloader_jump();
}
}
#endif
#ifdef DEFERRED_EXEC_ENABLE
# ifdef DEBUG_ENABLE
deferred_token debug_token;
bool debug_print(void) {
// uint8_t hall_effect_rows = 1;
// char buffer[hall_effect_rows * MATRIX_COLS * 5 + MATRIX_ROWS * 2];
// buffer[0] = '\0';
// // for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
// uint8_t row = 1;
// for (uint8_t col = 0; col < MATRIX_COLS; col++) {
// hybrid_key_t *key = &keys[row][col];
// char temp[6];
// snprintf(temp, sizeof(temp), "%5u", key->value);
// strcat(buffer, temp);
// }
// strcat(buffer, "\n");
// // }
// uprintf("%s", buffer);
// int raw_analog_value[3];
// for (uint8_t col = 0; col < MATRIX_COLS; col++) {
// raw_analog_value[col] = analogReadPin(matrix_pins[0][col]);
// }
// printf("raw_analog_value = %d, %d, %d\n", raw_analog_value[0], raw_analog_value[1], raw_analog_value[2]);
return true;
}
uint32_t debug_print_callback(uint32_t trigger_time, void *cb_arg) {
debug_print();
return 25;
}
# endif
deferred_token idle_recalibrate_token;
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
extend_deferred_exec(idle_recalibrate_token, 300000);
return true;
}
uint32_t idle_recalibrate_callback(uint32_t trigger_time, void *cb_arg) {
get_sensor_offsets();
return 10000;
}
#endif
void values_load(void) {
eeconfig_read_kb_datablock(&g_config, 0, EECONFIG_KB_DATA_SIZE);
}
void values_save(void) {
eeconfig_update_kb_datablock(&g_config, 0, EECONFIG_KB_DATA_SIZE);
}
void eeconfig_init_kb() {
values_save();
}
void keyboard_post_init_kb(void) {
#ifdef DEFERRED_EXEC_ENABLE
# ifdef DEBUG_ENABLE
debug_token = defer_exec(1000, debug_print_callback, NULL);
# endif
idle_recalibrate_token = defer_exec(300000, idle_recalibrate_callback, NULL);
#endif
values_load();
}
#ifdef VIA_ENABLE
void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
/* data = [ command_id, channel_id, value_id, value_data ] */
uint8_t *command_id = &(data[0]);
uint8_t *channel_id = &(data[1]);
uint8_t *value_id_and_data = &(data[2]);
if (*channel_id == id_custom_channel) {
switch (*command_id) {
case id_custom_set_value: {
via_config_set_value(value_id_and_data);
break;
}
case id_custom_get_value: {
via_config_get_value(value_id_and_data);
break;
}
case id_custom_save: {
values_save();
break;
}
default: {
/* Unhandled message */
*command_id = id_unhandled;
break;
}
}
return;
}
/* Return the unhandled state */
*command_id = id_unhandled;
/* DO NOT call raw_hid_send(data,length) here, let caller do this */
}
enum via_dynamic_actuation {
id_mode = 1,
id_actuation_point = 2,
id_press_sensitivity = 3,
id_release_sensitivity = 4,
id_press_hysteresis = 5,
id_release_hysteresis = 6,
};
void via_config_set_value(uint8_t *data) {
/* data = [ value_id, value_data ] */
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_mode:
g_config.mode = *value_data;
break;
case id_actuation_point:
g_config.actuation_point = *value_data * 255 / 40;
break;
case id_press_sensitivity:
g_config.press_sensitivity = *value_data * 255 / 40;
break;
case id_release_sensitivity:
g_config.release_sensitivity = *value_data * 255 / 40;
break;
case id_press_hysteresis:
g_config.press_hysteresis = *value_data * 255 / 40;
break;
case id_release_hysteresis:
g_config.release_hysteresis = *value_data * 255 / 40;
break;
}
}
void via_config_get_value(uint8_t *data) {
uint8_t *value_id = &(data[0]);
uint8_t *value_data = &(data[1]);
switch (*value_id) {
case id_mode:
*value_data = g_config.mode;
break;
case id_actuation_point:
*value_data = g_config.actuation_point * 40 / 255;
break;
case id_press_sensitivity:
*value_data = g_config.press_sensitivity * 40 / 255;
break;
case id_release_sensitivity:
*value_data = g_config.release_sensitivity * 40 / 255;
break;
case id_press_hysteresis:
*value_data = g_config.press_hysteresis * 40 / 255;
break;
case id_release_hysteresis:
*value_data = g_config.release_hysteresis * 40 / 255;
break;
}
}
#endif

View File

@ -0,0 +1,9 @@
/* Copyright 2023 RephlexZero (@RephlexZero)
SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#ifdef VIA_ENABLE
void via_config_set_value(uint8_t *data);
void via_config_get_value(uint8_t *data);
#endif