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