Update cheapino firmware

* Extract keymap definitions to follow the external userspace model. A
  default keymap should probably be added again as an example.
* Move configuration to keyboard.json.
* Enable LTO.
* Move encoder button handling to the keymap for full qmk feature
  support (layers, mod-tap).
* Inject encoder turn events into the qmk encoder pipeline, with the
  same motivation as above.
* Rename files to avoid clashing with qmk-internal files (encoder.h).
* Faster matrix store/compare primitives.
This commit is contained in:
schuay
2025-07-30 18:07:15 +02:00
parent 0c363cd93a
commit 92af2e26a4
12 changed files with 122 additions and 174 deletions
+8 -41
View File
@@ -1,5 +1,4 @@
#include "wait.h"
#include "quantum.h"
#include QMK_KEYBOARD_H
// This is to keep state between callbacks, when it is 0 the
// initial RGB flash is finished
@@ -27,49 +26,17 @@ uint32_t flash_led(uint32_t next_trigger_time, void *cb_arg) {
}
}
void keyboard_post_init_user(void) {
//debug_enable=true;
//debug_matrix=true;
//debug_keyboard=true;
//debug_mouse=true;
void keyboard_post_init_kb(void) {
// debug_enable=true;
// debug_matrix=true;
// debug_keyboard=true;
// debug_mouse=true;
// Store user selected rgb hsv:
_hue = rgblight_get_hue();
_hue = rgblight_get_hue();
_saturation = rgblight_get_sat();
_value = rgblight_get_val();
_value = rgblight_get_val();
// Flash a little on start
defer_exec(50, flash_led, NULL);
}
// Make the builtin RGB led show different colors per layer:
// This seemed like a good idea but turned out pretty annoying,
// to me at least... Uncomment the lines below to enable
/*
uint8_t get_hue(uint8_t layer) {
switch (layer) {
case 6:
return 169;
case 5:
return 43;
case 4:
return 85;
case 3:
return 120;
case 2:
return 180;
case 1:
return 220;
default:
return 0;
}
}
layer_state_t layer_state_set_user(layer_state_t state) {
uint8_t sat = rgblight_get_sat();
uint8_t val = rgblight_get_val();
uint8_t hue = get_hue(get_highest_layer(state));
rgblight_sethsv(hue, sat, val);
return state;
}
*/
+2 -37
View File
@@ -3,41 +3,6 @@
#pragma once
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD
#define WS2812_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the WS2812 implementation uses the PIO0 peripheral
//#define WS2812_TRST_US 80
// Force the usage of PIO1 peripheral, by default the WS2812 implementation uses the PIO0 peripheral.
#define WS2812_PIO_USE_PIO1
#define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_RGB
#define RGB_MATRIX_DEFAULT_VAL 32
// Pick good defaults for enabling homerow modifiers
#define TAPPING_TERM 230
#define WS2812_DI_PIN GP16 // The pin connected to the data pin of the LEDs
#define RGBLIGHT_LED_COUNT 1 // The number of LEDs connected
#define MAX_DEFERRED_EXECUTORS 32
// #define DEBUG_MATRIX_SCAN_RATE
#define RGBLIGHT_DEFAULT_HUE 128 // Sets the default hue value, if none has been set
#define RGBLIGHT_DEFAULT_SAT 128 // Sets the default saturation value, if none has been set
#define RGBLIGHT_DEFAULT_VAL 32 // Sets the default brightness value, if none has been set
-63
View File
@@ -1,63 +0,0 @@
#include "matrix.h"
#include "quantum.h"
#define COL_SHIFTER ((uint16_t)1)
#define ENC_ROW 3
#define ENC_A_COL 2
#define ENC_B_COL 4
#define ENC_BUTTON_COL 0
static bool colABPressed = false;
static bool encoderPressed = false;
void clicked(void) {
tap_code(KC_MPLY);
}
void turned(bool clockwise) {
if (IS_LAYER_ON(6)) {
tap_code(clockwise ? KC_VOLU : KC_VOLD);
} else if (IS_LAYER_ON(3)) {
tap_code16(clockwise ? LCTL(KC_TAB) : LCTL(LSFT(KC_TAB)));
} else if (IS_LAYER_ON(5)) {
tap_code16(clockwise ? LGUI(KC_Y) : LGUI(KC_Z));
} else {
tap_code16(clockwise ? KC_PGDN : KC_PGUP);
}
}
void fix_encoder_action(matrix_row_t current_matrix[]) {
matrix_row_t encoder_row = current_matrix[ENC_ROW];
if (encoder_row & (COL_SHIFTER << ENC_BUTTON_COL)) {
encoderPressed = true;
} else {
// Only trigger click on release
if (encoderPressed) {
encoderPressed = false;
clicked();
}
}
// Check which way the encoder is turned:
bool colA = encoder_row & (COL_SHIFTER << ENC_A_COL);
bool colB = encoder_row & (COL_SHIFTER << ENC_B_COL);
if (colA && colB) {
colABPressed = true;
} else if (colA) {
if (colABPressed) {
// A+B followed by A means clockwise
colABPressed = false;
turned(true);
}
} else if (colB) {
if (colABPressed) {
// A+B followed by B means counter-clockwise
colABPressed = false;
turned(false);
}
}
current_matrix[ENC_ROW] = 0;
}
-5
View File
@@ -1,5 +0,0 @@
//
// Created by Thomas Haukland on 25/03/2023.
//
void fix_encoder_action(matrix_row_t current_matrix[]);
-8
View File
@@ -1,8 +0,0 @@
#pragma once
#define HAL_USE_PWM TRUE
#define HAL_USE_PAL TRUE
#define HAL_USE_I2C TRUE
#include_next <halconf.h>
@@ -4,16 +4,51 @@
"maintainer": "tompi",
"bootloader": "rp2040",
"diode_direction": "ROW2COL",
"ws2812": {
"driver": "vendor",
"pin": "GP16"
},
"build": {
"lto": true
},
"features": {
"bootmagic": true,
"caps_word": true,
"command": false,
"console": false,
"deferred_exec": true,
"extrakey": true,
"mousekey": true,
"nkro": false
"nkro": false,
"rgblight": true
},
"tapping": {
"term": 230
},
"caps_word": {
"both_shifts_turns_on": true
},
"encoder": {
"_comment0": "These are unused but have to be defined. The encoder is",
"_comment1": "actually handled by matrix intersections; see encoder.c",
"rotary": [
{
"pin_a": "GP9",
"pin_b": "GP10"
}
]
},
"rgblight": {
"led_count": 1,
"default": {
"hue": 128,
"sat": 128,
"val": 64
}
},
"community_layouts": ["split_3x5_3"],
"matrix_pins": {
"custom": true,
"custom_lite": true,
"cols": [
"GP6",
"GP6",
@@ -29,7 +64,16 @@
"GP26",
"GP26"
],
"rows": ["GP3", "GP1", "GP2", "GP0", "GP27", "GP28", "GP29", "GP8"]
"rows": [
"GP3",
"GP1",
"GP2",
"GP0",
"GP27",
"GP28",
"GP29",
"GP8"
]
},
"processor": "RP2040",
"url": "",
@@ -47,6 +91,8 @@
{ "matrix": [4, 7], "x": 3, "y": 0.125 },
{ "matrix": [4, 6], "x": 4, "y": 0.25 },
{ "matrix": [3, 0], "x": 6, "y": 0.25 },
{ "matrix": [0, 0], "x": 7, "y": 0.25 },
{ "matrix": [0, 1], "x": 8, "y": 0.125 },
{ "matrix": [0, 2], "x": 9, "y": 0 },
+50
View File
@@ -0,0 +1,50 @@
#include "matrix-encoder.h"
#include "matrix.h"
#include "quantum.h"
void encoder_driver_task(void) {
// This is intentionally left empty to disable the default encoder driver.
// We inject events manually below.
}
// There aren't enough pins on the RJ45 for dedicated encoder pins. Use matrix
// intersections instead.
void fix_encoder_action(matrix_row_t current_matrix[]) {
static const int ENC_ROW = 3;
static const int ENC_A_COL = 2;
static const int ENC_B_COL = 4;
// The button column is unused here and handled through the keymap instead.
// static const int ENC_BUTTON_COL = 0;
static const matrix_row_t ENC_A_BIT = (1 << ENC_A_COL);
static const matrix_row_t ENC_B_BIT = (1 << ENC_B_COL);
// State machine tracking.
static bool colABPressed = false;
// Check which way the encoder is turned:
matrix_row_t encoder_row = current_matrix[ENC_ROW];
bool colA = encoder_row & ENC_A_BIT;
bool colB = encoder_row & ENC_B_BIT;
extern bool encoder_queue_event(uint8_t, bool);
if (colA && colB) {
colABPressed = true;
} else if (colA) {
if (colABPressed) {
// A+B followed by A means clockwise
colABPressed = false;
encoder_queue_event(0, true);
}
} else if (colB) {
if (colABPressed) {
// A+B followed by B means counter-clockwise
colABPressed = false;
encoder_queue_event(0, false);
}
}
// Clear A+B bits, and leave the button bits intact; it will be picked up
// by normal matrix/keymap processing.
static const matrix_row_t ROW_MASK = ~(ENC_A_BIT | ENC_B_BIT);
current_matrix[ENC_ROW] = encoder_row & ROW_MASK;
}
+6
View File
@@ -0,0 +1,6 @@
//
// Created by Thomas Haukland on 25/03/2023.
//
#include "quantum.h"
void fix_encoder_action(matrix_row_t current_matrix[]);
+4 -9
View File
@@ -25,8 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config.h"
#include "quantum.h"
#include "debounce.h"
#include "encoder.h"
#include "ghosting.h"
#include "matrix-encoder.h"
#include "matrix-ghosting.h"
#include "print.h"
// How long the scanning code waits for changed io to settle.
@@ -120,16 +120,11 @@ void matrix_init_custom(void) {
}
void store_old_matrix(matrix_row_t current_matrix[]) {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
previous_matrix[i] = current_matrix[i];
}
memcpy(previous_matrix, current_matrix, MATRIX_ROWS * sizeof(matrix_row_t));
}
bool has_matrix_changed(matrix_row_t current_matrix[]) {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
if (previous_matrix[i] != current_matrix[i]) return true;
}
return false;
return memcmp(previous_matrix, current_matrix, MATRIX_ROWS * sizeof(matrix_row_t)) != 0;
}
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+3 -8
View File
@@ -1,8 +1,3 @@
CAPS_WORD_ENABLE = yes
CUSTOM_MATRIX = lite
WS2812_DRIVER = vendor
RGBLIGHT_ENABLE = yes
DEFERRED_EXEC_ENABLE = yes
SRC += encoder.c
SRC += ghosting.c
SRC += matrix.c
SRC += matrix-encoder.c
SRC += matrix-ghosting.c
SRC += matrix.c