mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-07-17 21:22:05 +00:00
Merge b491088d6f
into 86badb394e
This commit is contained in:
commit
b47ea8f7ea
5
keyboards/momokai/tap_trio_pro/Scratchpad.md
Normal file
5
keyboards/momokai/tap_trio_pro/Scratchpad.md
Normal 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
|
40
keyboards/momokai/tap_trio_pro/analogkeys.h
Normal file
40
keyboards/momokai/tap_trio_pro/analogkeys.h
Normal 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];
|
16
keyboards/momokai/tap_trio_pro/config.h
Normal file
16
keyboards/momokai/tap_trio_pro/config.h
Normal 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
|
||||
|
13
keyboards/momokai/tap_trio_pro/driver.c
Normal file
13
keyboards/momokai/tap_trio_pro/driver.c
Normal 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;
|
||||
}
|
8
keyboards/momokai/tap_trio_pro/halconf.h
Normal file
8
keyboards/momokai/tap_trio_pro/halconf.h
Normal 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>
|
106
keyboards/momokai/tap_trio_pro/keyboard.json
Normal file
106
keyboards/momokai/tap_trio_pro/keyboard.json
Normal 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}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
18
keyboards/momokai/tap_trio_pro/keymaps/default/keymap.c
Normal file
18
keyboards/momokai/tap_trio_pro/keymaps/default/keymap.c
Normal 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
|
44
keyboards/momokai/tap_trio_pro/lut.c
Normal file
44
keyboards/momokai/tap_trio_pro/lut.c
Normal 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);
|
||||
}
|
||||
}
|
17
keyboards/momokai/tap_trio_pro/lut.h
Normal file
17
keyboards/momokai/tap_trio_pro/lut.h
Normal 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);
|
122
keyboards/momokai/tap_trio_pro/matrix.c
Normal file
122
keyboards/momokai/tap_trio_pro/matrix.c
Normal 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(¤t_matrix[current_row], current_col, key);
|
||||
break;
|
||||
case continuous_dynamic_actuation:
|
||||
matrix_read_cols_continuous_dynamic_actuation(¤t_matrix[current_row], current_col, key);
|
||||
break;
|
||||
case static_actuation:
|
||||
matrix_read_cols_static_actuation(¤t_matrix[current_row], current_col, key);
|
||||
break;
|
||||
case flashing:
|
||||
default:
|
||||
bootloader_jump();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return memcmp(previous_matrix, current_matrix, sizeof(previous_matrix)) != 0;
|
||||
}
|
||||
|
||||
|
8
keyboards/momokai/tap_trio_pro/mcuconf.h
Normal file
8
keyboards/momokai/tap_trio_pro/mcuconf.h
Normal 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
|
27
keyboards/momokai/tap_trio_pro/readme.md
Normal file
27
keyboards/momokai/tap_trio_pro/readme.md
Normal file
@ -0,0 +1,27 @@
|
||||
# momokai/tap_trio_pro
|
||||
|
||||

|
||||
|
||||
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
|
6
keyboards/momokai/tap_trio_pro/rules.mk
Normal file
6
keyboards/momokai/tap_trio_pro/rules.mk
Normal file
@ -0,0 +1,6 @@
|
||||
QUANTUM_LIB_SRC += analog.c
|
||||
SRC += matrix.c lut.c scanfunctions.c
|
||||
|
||||
CUSTOM_MATRIX = lite
|
||||
|
||||
OPT = 3
|
123
keyboards/momokai/tap_trio_pro/scanfunctions.c
Normal file
123
keyboards/momokai/tap_trio_pro/scanfunctions.c
Normal 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;
|
||||
}
|
||||
}
|
21
keyboards/momokai/tap_trio_pro/scanfunctions.h
Normal file
21
keyboards/momokai/tap_trio_pro/scanfunctions.h
Normal 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);
|
206
keyboards/momokai/tap_trio_pro/tap_trio_pro.c
Normal file
206
keyboards/momokai/tap_trio_pro/tap_trio_pro.c
Normal 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
|
||||
|
||||
|
||||
|
9
keyboards/momokai/tap_trio_pro/tap_trio_pro.h
Normal file
9
keyboards/momokai/tap_trio_pro/tap_trio_pro.h
Normal 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
|
Loading…
Reference in New Issue
Block a user