From 91a9f9e49263dbb04a0c54a2664d5115623009aa Mon Sep 17 00:00:00 2001 From: nullptr Date: Sat, 3 Jan 2026 20:45:29 +0100 Subject: [PATCH 01/21] Fix RGB Matrix Typing Heatmap overflow (#25915) --- quantum/rgb_matrix/animations/typing_heatmap_anim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/rgb_matrix/animations/typing_heatmap_anim.h b/quantum/rgb_matrix/animations/typing_heatmap_anim.h index 060673889184..77d79cf1af9e 100644 --- a/quantum/rgb_matrix/animations/typing_heatmap_anim.h +++ b/quantum/rgb_matrix/animations/typing_heatmap_anim.h @@ -32,7 +32,7 @@ void process_rgb_matrix_typing_heatmap(uint8_t row, uint8_t col) { if (i_row == row && i_col == col) { g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP); } else { -# define LED_DISTANCE(led_a, led_b) sqrt16(((int16_t)(led_a.x - led_b.x) * (int16_t)(led_a.x - led_b.x)) + ((int16_t)(led_a.y - led_b.y) * (int16_t)(led_a.y - led_b.y))) +# define LED_DISTANCE(led_a, led_b) sqrt16(((int32_t)(led_a.x - led_b.x) * (int32_t)(led_a.x - led_b.x)) + ((int32_t)(led_a.y - led_b.y) * (int32_t)(led_a.y - led_b.y))) uint8_t distance = LED_DISTANCE(g_led_config.point[g_led_config.matrix_co[row][col]], g_led_config.point[g_led_config.matrix_co[i_row][i_col]]); # undef LED_DISTANCE if (distance <= RGB_MATRIX_TYPING_HEATMAP_SPREAD) { From 8c035c2116c0ff2617a6aba996c3b6a9c977e19e Mon Sep 17 00:00:00 2001 From: Ed Flanagan Date: Sat, 3 Jan 2026 14:18:41 -0600 Subject: [PATCH 02/21] Fix small typo in WS2812 driver doc (#25928) `ws812` -> `ws2812` --- docs/drivers/ws2812.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drivers/ws2812.md b/docs/drivers/ws2812.md index 0c26ec624807..1d701138970b 100644 --- a/docs/drivers/ws2812.md +++ b/docs/drivers/ws2812.md @@ -292,7 +292,7 @@ Set the color of a single LED. This function does not immediately update the LED --- -### `void ws812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all} +### `void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all} Set the color of all LEDs. From 31948625020db943f2a5272a43876983c404d814 Mon Sep 17 00:00:00 2001 From: Pascal Getreuer <50221757+getreuer@users.noreply.github.com> Date: Sat, 3 Jan 2026 15:00:50 -0800 Subject: [PATCH 03/21] docs/tap_hold.md fixes: Note that Chordal Hold supports multiple same-side mods and fix heading for Speculative Hold. (#25924) * Note Chordal Hold supports multiple same-side mods. * Fix "Speculative Hold" heading from H3 -> H2. --- docs/tap_hold.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/tap_hold.md b/docs/tap_hold.md index 2aa628c5354c..3e88a7a5c238 100644 --- a/docs/tap_hold.md +++ b/docs/tap_hold.md @@ -604,6 +604,20 @@ Or if the two keys are on opposite hands and the `PERMISSIVE_HOLD` option is enabled, this will produce `C` with `SFT_T(KC_A)` settled as held when that `KC_C` is released. +As an exception to the opposite hands rule, Chordal Hold supports combining +multiple same-side modifiers within the tapping term. This is useful for +multi-mod hotkeys like Ctrl + Shift + V. For instance with Chordal Hold together +with either Permissive Hold or Hold On Other Key Press, the following input +results in Ctrl + Shift + V being sent, supposing `J` and `K` are on the right +hand side and `V` is on the left hand side: + +- `SFT_T(KC_J)` Down +- `CTL_T(KC_K)` Down +- `KC_V` Down +- `KC_V` Up +- `SFT_T(KC_J)` Up +- `CTL_T(KC_K)` Up + ### Chordal Hold Handedness Determining whether keys are on the same or opposite hands involves defining the @@ -779,7 +793,7 @@ Do not use `MOD_xxx` constants like `MOD_LSFT` or `MOD_RALT`, since they're 5-bi [Auto Shift](features/auto_shift) has its own version of `retro tapping` called `retro shift`. It is extremely similar to `retro tapping`, but holding the key past `AUTO_SHIFT_TIMEOUT` results in the value it sends being shifted. Other configurations also affect it differently; see [here](features/auto_shift#retro-shift) for more information. -### Speculative Hold +## Speculative Hold Speculative Hold makes mod-tap keys more responsive by applying the modifier instantly on keydown, before the tap-hold decision is made. This is especially useful for actions like Shift+Click with a mouse, which can feel laggy with standard mod-taps. @@ -820,4 +834,4 @@ Well, it's simple really: customization. But specifically, it depends on how you ## Why are there no `*_kb` or `*_user` functions?! -Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum- or keyboard-level function. Only user-level functions are useful here, so there is no need to mark them as such. \ No newline at end of file +Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum- or keyboard-level function. Only user-level functions are useful here, so there is no need to mark them as such. From 1e683923e1e42dda42911ebbaa191776aec3a626 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 7 Jan 2026 10:24:16 +0000 Subject: [PATCH 04/21] Handle broken symlinks in `qmk doctor` udev checks (#25934) Handle broken symlinks in 'qmk doctor' udev checks --- lib/python/qmk/cli/doctor/linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/qmk/cli/doctor/linux.py b/lib/python/qmk/cli/doctor/linux.py index f0850d4e6488..c99cc6baeaad 100644 --- a/lib/python/qmk/cli/doctor/linux.py +++ b/lib/python/qmk/cli/doctor/linux.py @@ -87,7 +87,7 @@ def check_udev_rules(): line = line.strip() if not line.startswith("#") and len(line): current_rules.add(line) - except PermissionError: + except (PermissionError, FileNotFoundError): cli.log.debug("Failed to read: %s", rule_file) # Check if the desired rules are among the currently present rules From 3d591a2000044d859115b8f6bf8e0c6af60acb74 Mon Sep 17 00:00:00 2001 From: Stefan Gluszek Date: Wed, 7 Jan 2026 22:08:05 +0100 Subject: [PATCH 05/21] Update fatotesa keyboard config. (#25811) --- keyboards/fatotesa/keyboard.json | 8 +++--- keyboards/fatotesa/keymaps/default/keymap.c | 30 +++++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/keyboards/fatotesa/keyboard.json b/keyboards/fatotesa/keyboard.json index 3013e8b812ac..f300daa8ce6a 100644 --- a/keyboards/fatotesa/keyboard.json +++ b/keyboards/fatotesa/keyboard.json @@ -32,9 +32,9 @@ "rows": ["B6", "E6", "D4", "D7", "B4", "B5"] } }, - "bootmagic": { - "matrix": [4, 1] - } + }, + "bootmagic": { + "matrix": [4, 1] }, "matrix_pins": { "cols": ["F5", "F6", "F7", "B1", "B3", "B2", "B6", null], @@ -43,7 +43,7 @@ "usb": { "device_version": "1.0.0", "pid": "0x0000", - "vid": "0xFEED" + "vid": "0x5347" }, "layouts": { "LAYOUT": { diff --git a/keyboards/fatotesa/keymaps/default/keymap.c b/keyboards/fatotesa/keymaps/default/keymap.c index 1f6aa8048897..a9fadb4142de 100644 --- a/keyboards/fatotesa/keymaps/default/keymap.c +++ b/keyboards/fatotesa/keymaps/default/keymap.c @@ -13,18 +13,20 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT( - KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_END, KC_INSERT, KC_DELETE, KC_KB_MUTE, - KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BACKSPACE, - LT(1, KC_TAB), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LEFT_BRACKET, KC_RIGHT_BRACKET, KC_ENTER, - KC_LEFT_CTRL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SEMICOLON, KC_QUOTE, KC_BACKSLASH, - KC_LEFT_SHIFT, KC_LEFT_ANGLE_BRACKET, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_SLASH, KC_RIGHT_SHIFT, - CW_TOGG, KC_LWIN, KC_LEFT_ALT, KC_BACKSPACE, KC_LEFT_ALT, KC_SPACE, KC_RIGHT_ALT, KC_RIGHT_CTRL, KC_NO, KC_NO - ), + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_END, KC_INSERT, KC_DELETE, KC_KB_MUTE, + KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BACKSPACE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LEFT_BRACKET, KC_RIGHT_BRACKET, KC_ENTER, + OSM(MOD_LCTL), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SEMICOLON, KC_QUOTE, KC_BACKSLASH, + OSM(MOD_LSFT), KC_LEFT_ANGLE_BRACKET, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_SLASH, OSM(MOD_RSFT), + CW_TOGG, OSM(MOD_LGUI), KC_LEFT_ALT, MO(1), OSM(MOD_LALT), KC_SPACE, OSM(MOD_RALT), KC_RIGHT_CTRL, KC_NO, KC_NO + ), + [1] = LAYOUT( - _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, KC_DEL, _______, _______, _______, _______, _______, _______ - )}; + QK_REBOOT, _______, _______, _______, _______, KC_PSCR, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + KC_TAB, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, _______, _______, + _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, KC_PGDN, _______, _______, _______, _______ + ) +}; From a0b15d08bc56ccbea9990dde884136425e9886f7 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 8 Jan 2026 05:36:40 +0000 Subject: [PATCH 06/21] Short term fix for avr-libc@2.3.0 (#25938) --- quantum/send_string/send_string.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quantum/send_string/send_string.c b/quantum/send_string/send_string.c index 602f24dabe38..6471d5140c67 100644 --- a/quantum/send_string/send_string.c +++ b/quantum/send_string/send_string.c @@ -281,6 +281,10 @@ void send_nibble(uint8_t number) { } } +#if defined(__AVR_ATmega32U4__) +# include +#endif + void tap_random_base64(void) { #if defined(__AVR_ATmega32U4__) uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; From e31384babf7cb77fb6b076541ba3373f3f709b46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 19:50:23 +0000 Subject: [PATCH 07/21] Bump JamesIves/github-pages-deploy-action from 4.7.6 to 4.8.0 (#25943) Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.7.6 to 4.8.0. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.7.6...v4.8.0) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-version: 4.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8a0229f8731a..104b19892b4e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -57,7 +57,7 @@ jobs: - name: Deploy if: ${{ github.event_name == 'push' && github.repository == 'qmk/qmk_firmware' }} - uses: JamesIves/github-pages-deploy-action@v4.7.6 + uses: JamesIves/github-pages-deploy-action@v4.8.0 with: token: ${{ secrets.GITHUB_TOKEN }} branch: gh-pages From 56a2e332e10e6c8d7bc41a45310fa983cbd8c577 Mon Sep 17 00:00:00 2001 From: Thanh Son Tran <62438883+trnthsn@users.noreply.github.com> Date: Sat, 10 Jan 2026 07:01:15 +0700 Subject: [PATCH 08/21] Update tyson60 pid (#25935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update support S6xty5 * Delete chconf.h * Update manufacturer, community layout for hhkb * Update layout * fix row index * Update tyson60s * Update community layout and layout name * Update remove rgb test mode * Update capslock led * Apply suggestions from code review Co-authored-by: Duncan Sutherland * Remove deprecated s6xty5 * Update tyson60 product id --------- Co-authored-by: Trần Thanh Sơn Co-authored-by: Duncan Sutherland --- keyboards/trnthsn/tyson60/info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboards/trnthsn/tyson60/info.json b/keyboards/trnthsn/tyson60/info.json index 6f4df15d9999..27e10a1333db 100644 --- a/keyboards/trnthsn/tyson60/info.json +++ b/keyboards/trnthsn/tyson60/info.json @@ -34,7 +34,7 @@ }, "usb": { "device_version": "0.0.1", - "pid": "0x5336", + "pid": "0x3633", "vid": "0x5453" }, "ws2812": { From 70c36c6c97094bae79e7766dabdb75f0cd91ff85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20A=2E=20Volpato?= Date: Sun, 11 Jan 2026 14:47:23 -0300 Subject: [PATCH 09/21] First support for KKC Wily (#25852) --- keyboards/wily/info.json | 20 ++++ keyboards/wily/readme.md | 26 +++++ keyboards/wily/wily_h625/keyboard.json | 90 ++++++++++++++++ .../wily/wily_h625/keymaps/default/keymap.c | 34 ++++++ keyboards/wily/wily_h700/keyboard.json | 89 ++++++++++++++++ .../wily/wily_h700/keymaps/default/keymap.c | 34 ++++++ keyboards/wily/wily_s/config.h | 21 ++++ keyboards/wily/wily_s/halconf.h | 21 ++++ keyboards/wily/wily_s/keyboard.json | 100 ++++++++++++++++++ .../wily/wily_s/keymaps/default/keymap.c | 34 ++++++ keyboards/wily/wily_s/mcuconf.h | 22 ++++ 11 files changed, 491 insertions(+) create mode 100644 keyboards/wily/info.json create mode 100644 keyboards/wily/readme.md create mode 100644 keyboards/wily/wily_h625/keyboard.json create mode 100644 keyboards/wily/wily_h625/keymaps/default/keymap.c create mode 100644 keyboards/wily/wily_h700/keyboard.json create mode 100644 keyboards/wily/wily_h700/keymaps/default/keymap.c create mode 100644 keyboards/wily/wily_s/config.h create mode 100644 keyboards/wily/wily_s/halconf.h create mode 100644 keyboards/wily/wily_s/keyboard.json create mode 100644 keyboards/wily/wily_s/keymaps/default/keymap.c create mode 100644 keyboards/wily/wily_s/mcuconf.h diff --git a/keyboards/wily/info.json b/keyboards/wily/info.json new file mode 100644 index 000000000000..9bba2de91024 --- /dev/null +++ b/keyboards/wily/info.json @@ -0,0 +1,20 @@ +{ + "manufacturer": "KKC", + "maintainer": "Gondolindrim", + "usb": { + "vid": "0x5750", + "device_version": "0.0.1" + }, + "features": { + "bootmagic": true, + "mousekey": true, + "extrakey": true, + "nkro": true + }, + "build": { + "lto": true + }, + "diode_direction": "COL2ROW", + "processor": "STM32F411", + "bootloader": "stm32-dfu" +} diff --git a/keyboards/wily/readme.md b/keyboards/wily/readme.md new file mode 100644 index 000000000000..e70ac11a1609 --- /dev/null +++ b/keyboards/wily/readme.md @@ -0,0 +1,26 @@ +# KKC Wily + +The Wily is a 65% keyboard by Keyote Key Company. + +* Keyboard Maintainer: [gondolindrim](https://github.com/gondolindrim) +* Hardware Supported: three PCB variants (solderable, hotswap with Tsangan bottom row, hotswap with default bottom row), both based on STM32F072 +* Hardware Availability: not yet available for purchase as of november 2025. + +Make example for this keyboard (after setting up your build environment): + + make wily/:default + +Where `` can be either `wily_s` , `wily_h625` or `wily_h700`. Flashing example for this keyboard: + + make wily/: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 (0,0) in the matrix (Escape) and plug in the keyboard +* **Physical reset button**: press and hold the button on the back of the PCB for five seconds +* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available + diff --git a/keyboards/wily/wily_h625/keyboard.json b/keyboards/wily/wily_h625/keyboard.json new file mode 100644 index 000000000000..915c3459aa53 --- /dev/null +++ b/keyboards/wily/wily_h625/keyboard.json @@ -0,0 +1,90 @@ +{ + "keyboard_name": "Keyote Wily-H625", + "usb": { + "pid": "0x5053", + "device_version": "0.0.1" + }, + "matrix_pins": { + "cols": ["A15", "B10", "C15", "C14", "C13", "B1", "B0", "A7", "A6", "A5", "B14", "B13", "B12", "A4", "A3"], + "rows": ["A0", "B8", "B3", "B5", "B9"] + }, + "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":[0,3], "x":3, "y":0}, + {"matrix":[0,4], "x":4, "y":0}, + {"matrix":[0,5], "x":5, "y":0}, + {"matrix":[0,6], "x":6, "y":0}, + {"matrix":[0,7], "x":7, "y":0}, + {"matrix":[0,8], "x":8, "y":0}, + {"matrix":[0,9], "x":9, "y":0}, + {"matrix":[0,10], "x":10, "y":0}, + {"matrix":[0,11], "x":11, "y":0}, + {"matrix":[0,12], "x":12, "y":0}, + {"matrix":[0,13], "x":13, "y":0}, + {"matrix":[0,14], "x":14, "y":0}, + {"matrix":[1,14], "x":15, "y":0}, + + {"matrix":[1,0], "x":0, "y":1, "w":1.5}, + {"matrix":[1,1], "x":1.5, "y":1}, + {"matrix":[1,2], "x":2.5, "y":1}, + {"matrix":[1,3], "x":3.5, "y":1}, + {"matrix":[1,4], "x":4.5, "y":1}, + {"matrix":[1,5], "x":5.5, "y":1}, + {"matrix":[1,6], "x":6.5, "y":1}, + {"matrix":[1,7], "x":7.5, "y":1}, + {"matrix":[1,8], "x":8.5, "y":1}, + {"matrix":[1,9], "x":9.5, "y":1}, + {"matrix":[1,10], "x":10.5, "y":1}, + {"matrix":[1,11], "x":11.5, "y":1}, + {"matrix":[1,12], "x":12.5, "y":1}, + {"matrix":[1,13], "x":13.5, "y":1, "w":1.5}, + {"matrix":[2,14], "x":15 , "y":1}, + + {"matrix":[2,0], "x":0 , "y":2}, + {"matrix":[2,1], "x":1.75 , "y":2}, + {"matrix":[2,2], "x":2.75 , "y":2}, + {"matrix":[2,3], "x":3.75, "y":2}, + {"matrix":[2,4], "x":4.75, "y":2}, + {"matrix":[2,5], "x":5.75, "y":2}, + {"matrix":[2,6], "x":6.75, "y":2}, + {"matrix":[2,7], "x":7.75, "y":2}, + {"matrix":[2,8], "x":8.75, "y":2}, + {"matrix":[2,9], "x":9.75, "y":2}, + {"matrix":[2,10], "x":10.75, "y":2}, + {"matrix":[2,11], "x":11.75, "y":2}, + {"matrix":[2,12], "x":12.75, "y":2, "w":2.25}, + {"matrix":[2,13], "x":15 , "y":2}, + + {"matrix":[3,0], "x":0 , "y":3, "w":2.25}, + {"matrix":[3,2], "x":2.25, "y":3}, + {"matrix":[3,3], "x":3.25, "y":3}, + {"matrix":[3,4], "x":4.25, "y":3}, + {"matrix":[3,5], "x":5.25, "y":3}, + {"matrix":[3,6], "x":6.25, "y":3}, + {"matrix":[3,7], "x":7.25, "y":3}, + {"matrix":[3,8], "x":8.25, "y":3}, + {"matrix":[3,9], "x":9.25, "y":3}, + {"matrix":[3,10], "x":10.25 , "y":3}, + {"matrix":[3,11], "x":11.25, "y":3}, + {"matrix":[3,12], "x":12.25, "y":3, "w":1.75}, + {"matrix":[3,13], "x":14, "y":3}, + {"matrix":[3,14], "x":15, "y":3}, + + {"matrix":[4,0], "x":0 , "y":4, "w":1.25}, + {"matrix":[4,1], "x":1.25, "y":4, "w":1.25}, + {"matrix":[4,2], "x":2.5 , "y":4, "w":1.25}, + {"matrix":[4,6], "x":3.75, "y":4, "w":6.25}, + {"matrix":[4,8], "x":10, "y":4}, + {"matrix":[4,9], "x":11, "y":4}, + {"matrix":[4,10], "x":12, "y":4}, + {"matrix":[4,12], "x":13, "y":4}, + {"matrix":[4,13], "x":14, "y":4}, + {"matrix":[4,14], "x":15, "y":4} + ] + } + } +} diff --git a/keyboards/wily/wily_h625/keymaps/default/keymap.c b/keyboards/wily/wily_h625/keymaps/default/keymap.c new file mode 100644 index 000000000000..36c2eda7b9eb --- /dev/null +++ b/keyboards/wily/wily_h625/keymaps/default/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2025 Gondolindrim + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include QMK_KEYBOARD_H +#define LT1GUI LT(1, KC_RGUI) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT( /* Base */ + QK_GESC, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINS, KC_EQL , KC_BSPC, KC_BSPC, KC_DEL , + KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, + KC_CAPS, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_ENT , KC_END , + KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_UP , KC_INS , + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC , KC_RALT, LT1GUI , KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT +), +[1] = LAYOUT( + QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS +) +}; diff --git a/keyboards/wily/wily_h700/keyboard.json b/keyboards/wily/wily_h700/keyboard.json new file mode 100644 index 000000000000..1dfe3d24a4f8 --- /dev/null +++ b/keyboards/wily/wily_h700/keyboard.json @@ -0,0 +1,89 @@ +{ + "keyboard_name": "Keyote Wily-H700", + "usb": { + "pid": "0x5052", + "device_version": "0.0.1" + }, + "matrix_pins": { + "cols": ["A15", "B10", "C15", "C14", "C13", "B1", "B0", "A7", "A6", "A5", "B14", "B13", "B12", "A4", "A3"], + "rows": ["A0", "B8", "B3", "B5", "B9"] + }, + "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":[0,3], "x":3, "y":0}, + {"matrix":[0,4], "x":4, "y":0}, + {"matrix":[0,5], "x":5, "y":0}, + {"matrix":[0,6], "x":6, "y":0}, + {"matrix":[0,7], "x":7, "y":0}, + {"matrix":[0,8], "x":8, "y":0}, + {"matrix":[0,9], "x":9, "y":0}, + {"matrix":[0,10], "x":10, "y":0}, + {"matrix":[0,11], "x":11, "y":0}, + {"matrix":[0,12], "x":12, "y":0}, + {"matrix":[0,13], "x":13, "y":0}, + {"matrix":[0,14], "x":14, "y":0}, + {"matrix":[1,14], "x":15, "y":0}, + + {"matrix":[1,0], "x":0, "y":1, "w":1.5}, + {"matrix":[1,1], "x":1.5, "y":1}, + {"matrix":[1,2], "x":2.5, "y":1}, + {"matrix":[1,3], "x":3.5, "y":1}, + {"matrix":[1,4], "x":4.5, "y":1}, + {"matrix":[1,5], "x":5.5, "y":1}, + {"matrix":[1,6], "x":6.5, "y":1}, + {"matrix":[1,7], "x":7.5, "y":1}, + {"matrix":[1,8], "x":8.5, "y":1}, + {"matrix":[1,9], "x":9.5, "y":1}, + {"matrix":[1,10], "x":10.5, "y":1}, + {"matrix":[1,11], "x":11.5, "y":1}, + {"matrix":[1,12], "x":12.5, "y":1}, + {"matrix":[1,13], "x":13.5, "y":1, "w":1.5}, + {"matrix":[2,14], "x":15 , "y":1}, + + {"matrix":[2,0], "x":0 , "y":2}, + {"matrix":[2,1], "x":1.75 , "y":2}, + {"matrix":[2,2], "x":2.75 , "y":2}, + {"matrix":[2,3], "x":3.75, "y":2}, + {"matrix":[2,4], "x":4.75, "y":2}, + {"matrix":[2,5], "x":5.75, "y":2}, + {"matrix":[2,6], "x":6.75, "y":2}, + {"matrix":[2,7], "x":7.75, "y":2}, + {"matrix":[2,8], "x":8.75, "y":2}, + {"matrix":[2,9], "x":9.75, "y":2}, + {"matrix":[2,10], "x":10.75, "y":2}, + {"matrix":[2,11], "x":11.75, "y":2}, + {"matrix":[2,12], "x":12.75, "y":2, "w":2.25}, + {"matrix":[2,13], "x":15 , "y":2}, + + {"matrix":[3,0], "x":0 , "y":3, "w":2.25}, + {"matrix":[3,2], "x":2.25, "y":3}, + {"matrix":[3,3], "x":3.25, "y":3}, + {"matrix":[3,4], "x":4.25, "y":3}, + {"matrix":[3,5], "x":5.25, "y":3}, + {"matrix":[3,6], "x":6.25, "y":3}, + {"matrix":[3,7], "x":7.25, "y":3}, + {"matrix":[3,8], "x":8.25, "y":3}, + {"matrix":[3,9], "x":9.25, "y":3}, + {"matrix":[3,10], "x":10.25 , "y":3}, + {"matrix":[3,11], "x":11.25, "y":3}, + {"matrix":[3,12], "x":12.25, "y":3, "w":1.75}, + {"matrix":[3,13], "x":14, "y":3}, + {"matrix":[3,14], "x":15, "y":3}, + + {"matrix":[4,0], "x":0 , "y":4, "w":1.5}, + {"matrix":[4,1], "x":1, "y":4}, + {"matrix":[4,2], "x":2.5 , "y":4, "w":1.5}, + {"matrix":[4,6], "x":4, "y":4, "w":7}, + {"matrix":[4,9], "x":11, "y":4}, + {"matrix":[4,10], "x":12, "y":4}, + {"matrix":[4,12], "x":13, "y":4}, + {"matrix":[4,13], "x":14, "y":4}, + {"matrix":[4,14], "x":15, "y":4} + ] + } + } +} diff --git a/keyboards/wily/wily_h700/keymaps/default/keymap.c b/keyboards/wily/wily_h700/keymaps/default/keymap.c new file mode 100644 index 000000000000..0929de8fa385 --- /dev/null +++ b/keyboards/wily/wily_h700/keymaps/default/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2025 Gondolindrim + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include QMK_KEYBOARD_H +#define LT1GUI LT(1, KC_RGUI) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT( /* Base */ + QK_GESC, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINS, KC_EQL , KC_BSPC, KC_BSPC, KC_DEL , + KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, + KC_CAPS, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_ENT , KC_END , + KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_UP , KC_INS , + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC , LT1GUI , KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT +), +[1] = LAYOUT( + QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS +) +}; diff --git a/keyboards/wily/wily_s/config.h b/keyboards/wily/wily_s/config.h new file mode 100644 index 000000000000..580f722f154f --- /dev/null +++ b/keyboards/wily/wily_s/config.h @@ -0,0 +1,21 @@ +/* Copyright 2025 Gondolindrim + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#define BACKLIGHT_PWM_DRIVER PWMD3 +#define BACKLIGHT_PWM_CHANNEL 4 +#define BACKLIGHT_PWM_PAL_MOPDE 2 diff --git a/keyboards/wily/wily_s/halconf.h b/keyboards/wily/wily_s/halconf.h new file mode 100644 index 000000000000..6c98f31f9b16 --- /dev/null +++ b/keyboards/wily/wily_s/halconf.h @@ -0,0 +1,21 @@ +/* Copyright 2025 Gondolindrim + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define HAL_USE_PWM TRUE + +#include_next diff --git a/keyboards/wily/wily_s/keyboard.json b/keyboards/wily/wily_s/keyboard.json new file mode 100644 index 000000000000..a6df026ef3b3 --- /dev/null +++ b/keyboards/wily/wily_s/keyboard.json @@ -0,0 +1,100 @@ +{ + "keyboard_name": "Keyote Wily-S", + "usb": { + "pid": "0x5051", + "device_version": "0.0.1" + }, + "matrix_pins": { + "cols": ["A15", "B10", "C15", "C14", "C13", "B1", "B0", "A7", "A6", "A5", "B14", "B13", "B12", "A4", "A3"], + "rows": ["A0", "B8", "B3", "B5", "B9"] + }, + "features": { + "backlight": true + }, + "backlight": { + "pin": "B4", + "levels": 20, + "as_caps_lock": true + }, + "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":[0,3], "x":3, "y":0}, + {"matrix":[0,4], "x":4, "y":0}, + {"matrix":[0,5], "x":5, "y":0}, + {"matrix":[0,6], "x":6, "y":0}, + {"matrix":[0,7], "x":7, "y":0}, + {"matrix":[0,8], "x":8, "y":0}, + {"matrix":[0,9], "x":9, "y":0}, + {"matrix":[0,10], "x":10, "y":0}, + {"matrix":[0,11], "x":11, "y":0}, + {"matrix":[0,12], "x":12, "y":0}, + {"matrix":[0,13], "x":13, "y":0}, + {"matrix":[0,14], "x":14, "y":0}, + {"matrix":[1,14], "x":15, "y":0}, + + {"matrix":[1,0], "x":0, "y":1, "w":1.5}, + {"matrix":[1,1], "x":1.5, "y":1}, + {"matrix":[1,2], "x":2.5, "y":1}, + {"matrix":[1,3], "x":3.5, "y":1}, + {"matrix":[1,4], "x":4.5, "y":1}, + {"matrix":[1,5], "x":5.5, "y":1}, + {"matrix":[1,6], "x":6.5, "y":1}, + {"matrix":[1,7], "x":7.5, "y":1}, + {"matrix":[1,8], "x":8.5, "y":1}, + {"matrix":[1,9], "x":9.5, "y":1}, + {"matrix":[1,10], "x":10.5, "y":1}, + {"matrix":[1,11], "x":11.5, "y":1}, + {"matrix":[1,12], "x":12.5, "y":1}, + {"matrix":[1,13], "x":13.5, "y":1, "w":1.5}, + {"matrix":[2,14], "x":15 , "y":1}, + + {"matrix":[2,0], "x":0 , "y":2}, + {"matrix":[2,1], "x":1.75 , "y":2}, + {"matrix":[2,2], "x":2.75 , "y":2}, + {"matrix":[2,3], "x":3.75, "y":2}, + {"matrix":[2,4], "x":4.75, "y":2}, + {"matrix":[2,5], "x":5.75, "y":2}, + {"matrix":[2,6], "x":6.75, "y":2}, + {"matrix":[2,7], "x":7.75, "y":2}, + {"matrix":[2,8], "x":8.75, "y":2}, + {"matrix":[2,9], "x":9.75, "y":2}, + {"matrix":[2,10], "x":10.75, "y":2}, + {"matrix":[2,11], "x":11.75, "y":2}, + {"matrix":[4,11], "x":12.75, "y":2}, + {"matrix":[2,12], "x":13.75, "y":2, "w":1.25}, + {"matrix":[2,13], "x":15 , "y":2}, + + {"matrix":[3,0], "x":0 , "y":3, "w":1.25}, + {"matrix":[3,1], "x":1.25, "y":3}, + {"matrix":[3,2], "x":2.25, "y":3}, + {"matrix":[3,3], "x":3.25, "y":3}, + {"matrix":[3,4], "x":4.25, "y":3}, + {"matrix":[3,5], "x":5.25, "y":3}, + {"matrix":[3,6], "x":6.25, "y":3}, + {"matrix":[3,7], "x":7.25, "y":3}, + {"matrix":[3,8], "x":8.25, "y":3}, + {"matrix":[3,9], "x":9.25, "y":3}, + {"matrix":[3,10], "x":10.25 , "y":3}, + {"matrix":[3,11], "x":11.25, "y":3}, + {"matrix":[3,12], "x":12.25, "y":3, "w":1.75}, + {"matrix":[3,13], "x":14, "y":3}, + {"matrix":[3,14], "x":15, "y":3}, + + {"matrix":[4,0], "x":0 , "y":4, "w":1.25}, + {"matrix":[4,1], "x":1.25, "y":4, "w":1.25}, + {"matrix":[4,2], "x":2.5 , "y":4, "w":1.25}, + {"matrix":[4,6], "x":3.75, "y":4, "w":6.25}, + {"matrix":[4,8], "x":10, "y":4}, + {"matrix":[4,9], "x":11, "y":4}, + {"matrix":[4,10], "x":12, "y":4}, + {"matrix":[4,12], "x":13, "y":4}, + {"matrix":[4,13], "x":14, "y":4}, + {"matrix":[4,14], "x":15, "y":4} + ] + } + } +} diff --git a/keyboards/wily/wily_s/keymaps/default/keymap.c b/keyboards/wily/wily_s/keymaps/default/keymap.c new file mode 100644 index 000000000000..22c0188c3089 --- /dev/null +++ b/keyboards/wily/wily_s/keymaps/default/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2025 Gondolindrim + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include QMK_KEYBOARD_H +#define LT1GUI LT(1, KC_RGUI) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT( /* Base */ + QK_GESC, KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_MINS, KC_EQL , KC_BSPC, KC_BSPC, KC_DEL , + KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, + KC_CAPS, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT , KC_END , + KC_LSFT, KC_NUBS, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_UP , KC_INS , + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC , KC_RALT, LT1GUI , KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT +), +[1] = LAYOUT( + QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS +) +}; diff --git a/keyboards/wily/wily_s/mcuconf.h b/keyboards/wily/wily_s/mcuconf.h new file mode 100644 index 000000000000..a9bbcfc62ca1 --- /dev/null +++ b/keyboards/wily/wily_s/mcuconf.h @@ -0,0 +1,22 @@ +/* Copyright 2025 Gondolindrim + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include_next + +#undef STM32_PWM_USE_TIM3 +#define STM32_PWM_USE_TIM3 TRUE From e391793f7317ca406989cea30dcd43ebbdb1f0e8 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 11 Jan 2026 18:15:14 +0000 Subject: [PATCH 10/21] Remove binary symbols from keymaps (#25947) --- keyboards/keycapsss/kimiko/rev1/keymaps/default/keymap.c | 4 ++-- keyboards/keycapsss/kimiko/rev2/keymaps/default/keymap.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/keyboards/keycapsss/kimiko/rev1/keymaps/default/keymap.c b/keyboards/keycapsss/kimiko/rev1/keymaps/default/keymap.c index c61fdfc03a55..5834ef9c26da 100644 --- a/keyboards/keycapsss/kimiko/rev1/keymaps/default/keymap.c +++ b/keyboards/keycapsss/kimiko/rev1/keymaps/default/keymap.c @@ -53,7 +53,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), /* LOWER * ,-------------------------------------------. ,-----------------------------------------. - * | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | + * | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | * |--------+------+------+------+------+------| |------+------+------+------+------+------| * | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | F12 | * |--------+------+------+------+------+------| |------+------+------+------+------+------| @@ -78,7 +78,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |------+------+------+------+------+------| |------+------+------+------+------+------| * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | * |------+------+------+------+------+------| |------+------+------+------+------+------| - * | F1 | F2 | F3 | F4 | F5 | F6 |-------. ,-------| | Left | Down | Up |Right | | + * | F1 | F2 | F3 | F4 | F5 | F6 |-------. ,-------| | Left | Down | Up |Right | | * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------| * | F7 | F8 | F9 | F10 | F11 | F12 |-------| |-------| + | - | = | [ | ] | \ | * `-----------------------------------------/ / \ \-----------------------------------------' diff --git a/keyboards/keycapsss/kimiko/rev2/keymaps/default/keymap.c b/keyboards/keycapsss/kimiko/rev2/keymaps/default/keymap.c index a569beed2244..4050a038d303 100644 --- a/keyboards/keycapsss/kimiko/rev2/keymaps/default/keymap.c +++ b/keyboards/keycapsss/kimiko/rev2/keymaps/default/keymap.c @@ -50,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* LOWER * QWERTY * ,--------------------------------------------. ,----------------------------------------------. - * | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | + * | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | * |---------+------+------+------+------+------| |------+------+------+------+------+-----------| * | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | F12 | * |---------+------+------+------+------+------| |------+------+------+------+------+-----------| @@ -74,7 +74,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |---------+------+------+------+------+------| |------+------+------+------+------+-----------| * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | * |---------+------+------+------+------+------| |------+------+------+------+------+-----------| - * | F1 | F2 | F3 | F4 | F5 | F6 |---------------. ,---------------| Left | Down | Up |Right | ; | | + * | F1 | F2 | F3 | F4 | F5 | F6 |---------------. ,---------------| Left | Down | Up |Right | ; | | * |---------+------+------+------+------+------| [ | [ | | [ | [ |------+------+------+------+------+-----------| * | F7 | F8 | F9 | F10 | F11 | F12 |------|--------| |-------|-------| + | - | = | [ | ] | \ | * `--------------------------------------------| / \ |----------------------------------------------' From 7d66c11f378acd46e03506ff573a61912a1eda5e Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 13 Jan 2026 05:48:59 +0000 Subject: [PATCH 11/21] Lint default dynamic keymap layer count (#25948) --- data/mappings/info_defaults.hjson | 3 +++ data/schemas/keyboard.jsonschema | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/data/mappings/info_defaults.hjson b/data/mappings/info_defaults.hjson index d1f1579c55b3..fd59dacac0d4 100644 --- a/data/mappings/info_defaults.hjson +++ b/data/mappings/info_defaults.hjson @@ -11,6 +11,9 @@ "on_state": 1 }, "debounce": 5, + "dynamic_keymap": { + "layer_count": 4 + }, "features": { "command": false, "console": false diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 57aeb3de22fc..d3a26923b541 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -333,6 +333,17 @@ } } }, + "dynamic_keymap": { + "type": "object", + "properties": { + "eeprom_max_addr": {"$ref": "./definitions.jsonschema#/unsigned_int"}, + "layer_count": { + "type": "integer", + "minimum": 1, + "maximum": 32 + } + } + }, "eeprom": { "properties": { "driver": {"type": "string"}, From 127c664647bb234ea9b586741a39f910b771eac5 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Thu, 15 Jan 2026 11:47:35 +1100 Subject: [PATCH 12/21] Backport GitHub Copilot instructions. (#25953) --- .github/copilot-instructions.md | 430 ++++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000000..ee51380bd5a6 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,430 @@ +--- +applyTo: "**" +excludeAgent: + - "coding-agent" +--- +# GitHub Copilot Instructions for QMK Pull Request Review +This document provides automated review guidance based on the [QMK PR Checklist](https://docs.qmk.fm/pr_checklist) and it is intended only for use by GitHub Copilot code-review agent during pull request reviews. + +## General PR Requirements + +### Branch and Submission Standards +- **Source Branch Policy**: Verify PR is NOT submitted from submitter's own `master` branch + - Flag if submitter is using their own `master` branch as source + - Suggest using feature branches instead for cleaner fork management +- **Target Branch Policy**: + - **New keyboard additions** → `master` branch (new folders under `keyboards/`) + - **All other changes** → `develop` branch: + - Keyboard updates, refactors, or moves + - Core code changes + - Data-driven configuration migrations + - Any modifications to existing keyboards +- **PR Scope**: PRs should contain the smallest set of modifications for a single change + - Flag PRs that modify multiple keyboards simultaneously + - Suggest splitting large PRs into focused, incremental changes +- **Merge Conflicts**: Check for unresolved merge conflicts + +### File Naming and Structure +- **Lowercase Requirement**: All new directories and filenames must be lowercase + - Exception: Upstream sources with original uppercase (LUFA, ChibiOS) + - Exception: Core files with valid justification + - **Reject**: Board designer preference for uppercase is NOT valid justification + +### License Headers +- **Required**: Valid license headers on all `*.c` and `*.h` files +- **Recommended**: GPL2/GPL3 for consistency +- **Format**: Check for proper GPL2+ header or SPDX identifier + ```c + // Copyright 2024 Your Name (@yourgithub) + // SPDX-License-Identifier: GPL-2.0-or-later + ``` +- **Exception**: Simple assignment-only `rules.mk` files don't need headers +- **Flag**: Missing or ambiguous license headers (blocks merge) + +### QMK Best Practices +- **Include Guards**: Use `#pragma once` instead of `#ifndef` guards in headers +- **Abstractions Required**: No low-level GPIO/I2C/SPI functions + - Must use QMK abstractions (flag direct hardware access) +- **Timing Functions**: + - Use `wait_ms()` instead of `_delay_ms()` + - Remove `#include ` + - Use `timer_read()`, `timer_read32()` from `timer.h` +- **New Abstractions**: If proposing new abstraction, suggest: + 1. Prototype in own keyboard first + 2. Discuss with QMK Collaborators on Discord + 3. Refactor as separate core change + 4. Remove the keyboard-specific implementation from board + +--- + +## Keymap PR Reviews + +**Scope**: These rules apply to files within `keyboards/*/keymaps/*` subdirectories. + +### Note on Personal Keymaps +- **Policy Change**: Personal keymap submissions no longer accepted +- **Permitted**: Vendor-specific keymaps only + - Naming convention: `default_${vendor}` (e.g., `default_clueboard`) + - Can be more feature-rich than stock `default` keymaps + +### Keymap Code Standards +- **Includes**: `#include QMK_KEYBOARD_H` preferred over specific board files +- **Enums**: Prefer layer enums to `#define`s +- **Custom Keycodes**: First entry must be `QK_USER` +- **Formatting**: Check spacing alignment on commas and keycodes (spaces, not tabs) +- **VIA**: Keymaps should NOT enable VIA + - VIA keymaps belong in [VIA QMK Userspace](https://github.com/the-via/qmk_userspace_via) + +--- + +## Keyboard PR Reviews + +**Scope**: These rules apply to keyboard-level files in `keyboards/*` directories, excluding files within the `keymaps/` subdirectories. This includes: +- `info.json` or `keyboard.json` (keyboard root or variant level) +- `readme.md` (keyboard level) +- `rules.mk` (keyboard level) +- `config.h` (keyboard level, not keymap level) +- `.c` and `.h` files +- Hardware configuration files (`halconf.h`, `mcuconf.h`, `chconf.h`) + +### Branch Targeting +- **New Keyboards**: Target `master` branch + - New additions to `keyboards/` folder submit to `master` +- **Keyboard Moves**: Must target `develop` branch + - Check `data/mappings/keyboard_aliases.hjson` is updated for moves +- **Keyboard Updates/Refactors**: Must target `develop` to reduce merge conflicts +- **Data Driven Migration**: Must target `develop` + +### info.json and keyboard.json Requirements +- **Data-Driven Configuration**: Encourage maximum use of `info.json` and `keyboard.json` schema features +- **Schema Validation**: All `info.json` and `keyboard.json` files must validate against `data/schemas/keyboard.jsonschema` + - Use QMK CLI: `qmk lint -kb ` to validate + - Schema defines required fields, data types, and valid values + - Check for schema validation errors before submitting PR +- **Mandatory Elements**: + - Valid URL + - Valid maintainer + - Valid USB VID/PID and device version + - Displays correctly in Configurator (Ctrl+Shift+I to preview) + - `layout` definitions include matrix positions + - Standard layout definitions where applicable + - Community Layout macro names when applicable + - Microcontroller and bootloader specified + - Diode direction (if not using direct pins) +- **Layout Naming**: + - Single layout: Use `LAYOUT` or community layout name + - Multiple layouts: Include `LAYOUT_all` + alternate names + - Prefer community layout names (e.g., `LAYOUT_tkl_ansi`, `LAYOUT_ortho_4x4`) +- **Configuration in info.json or keyboard.json** (when applicable): + - Direct pin configuration + - Backlight, Split keyboard, Encoder, Bootmagic configs + - LED Indicator, RGB Light, RGB Matrix configs +- **Format**: Run `qmk format-json -i` before submitting + +### USB VID/PID Uniqueness +VID+PID combination must be unique across all keyboards. Individual VID or PID values can be reused with different partners. +**Validation Steps:** +1. Extract VID and PID from keyboard.json/info.json in the PR +2. Search for existing usage: `grep -r '"vid".*"0xVVVV"' keyboards/ --include="*.json" | grep -l '"pid".*"0xPPPP"'` +3. If results found: Check if BOTH VID AND PID match in same file + - Both match = **COLLISION** - request different PID + - Only one matches = **OK** - different keyboards can share individual values +4. For keyboard variants/revisions under same keyboard folder: + - Different PID recommended for functionally different variants + - Same PID acceptable if revisions only differ in hardware routing/pin assignments +**Quick Reference:** +- Same PID + Different VID = Valid +- Same VID + Different PID = Valid +- Same VID + Same PID = Invalid +**Review Response:** +For collision: +``` +VID+PID collision: 0xVVVV:0xPPPP already used by keyboards/[path]/file.json ++Please assign a different PID. VID can remain the same. +``` +For uniqueness confirmed: +``` +VID+PID validation: 0xVVVV:0xPPPP is unique (no collisions found) +``` + +### readme.md Requirements +- **Template**: Must follow [official template](https://github.com/qmk/qmk_firmware/blob/master/data/templates/keyboard/readme.md) +- **Flash Command**: Present with `:flash` at end +- **Hardware Link**: Valid availability link (unless handwired) + - Private groupbuys acceptable + - One-off prototypes will be questioned + - Open-source should link to files +- **Reset Instructions**: Clear bootloader mode instructions +- **Images Required**: + - Keyboard and PCB photos preferred + - Must be hosted externally (imgur, etc.) + - Direct image links required (not preview pages) + - Example: `https://i.imgur.com/vqgE7Ok.jpg` not `https://imgur.com/vqgE7Ok` + +### rules.mk Standards +- **Removed Items**: + - `MIDI_ENABLE`, `FAUXCLICKY_ENABLE`, `HD44780_ENABLE` + - Size comments like `(-/+size)` + - Alternate bootloader lists if one specified + - MCU parameter re-definitions matching defaults in `mcu_selection.mk` +- **Comment Updates**: Change bootloader comments to generic +- **Forbidden Features at Keyboard Level** (these belong in keymap-level `rules.mk` only): + - `COMBO_ENABLE` + - `ENCODER_MAP_ENABLE` + +### config.h Standards (Keyboard Level) +- **Prohibited**: + - `#define DESCRIPTION` + - Magic Key Options, MIDI Options, HD44780 configuration + - User preference `#define`s (belong in keymap) + - Re-defining default values (`DEBOUNCE`, RGB settings) + - Copy/pasted comment blocks explaining features + - Commented-out unused defines + - `#include "config_common.h"` + - `#define MATRIX_ROWS/COLS` (unless custom matrix) +- **Minimal Code**: Only critical board boot code required +- **No Vial**: Vial-related files/changes not accepted + +### Keyboard Implementation Files + +#### `.c` +- **Remove Empty Functions**: Delete empty or commented-out weak-defined functions + - `xxxx_xxxx_kb()`, `xxxx_xxxx_user()` implementations +- **Migration**: `matrix_init_board()` → `keyboard_pre_init_kb()` +- **Custom Matrix**: Use `lite` variant when possible for standard debounce + - `CUSTOM_MATRIX = lite` preferred + - Full custom matrix (`yes`) requires justification +- **LED Indicators**: Prefer Configuration Options over custom `led_update_*()` implementations +- **Hardware Configuration**: Basic functionality for OLED, encoders, etc. at keyboard level + +#### `.h` +- **Include**: `#include "quantum.h"` at top +- **Layout Macros**: Move to `info.json` or `keyboard.json` (no longer in header) + +### Default Keymap Standards + +**Scope**: These rules specifically apply to files within `keyboards/*/keymaps/default/` directories. + +- **Pristine Requirement**: Bare minimum clean slate + - No custom keycodes + - No advanced features (non-exhaustive list of examples: tap dance, macros) + - Basic mod taps and home row mods acceptable when necessary + - Standard layouts preferred -- see examples in `layouts/default/` and `layouts/community/` +- **Removed Examples**: Delete `QMKBEST`/`QMKURL` macros +- **Tri Layer**: Use Tri Layer feature instead of manual `layer_on/off()` + `update_tri_layer()` +- **Encoder Map**: Use encoder map feature, `encoder_update_user()` may not be present +- **No VIA**: Default keymap should not enable VIA +- **Additional Keymaps**: Example/bells-and-whistles keymaps acceptable in same PR (separate from default) + +### Prohibited Files +- **No VIA JSON**: Belongs in [VIA Keyboard Repo](https://github.com/the-via/keyboards) +- **No KLE JSON**: Not used within QMK +- **No Cross-Keyboard Sources**: Don't include files from other keyboard vendors + - Exception: Core files (e.g., `drivers/sensors/pmw3360.c`) + - Use of vendor-specific code (e.g., `wilba_tech/wt_main.c`) only when keyboard exists in the same enclosing vendor folder (e.g. a `wilba_tech` keyboard) + - Multi-board code is candidate for core refactoring when intended for use by multiple vendors + +### Wireless Keyboards +- **Policy**: Wireless/Bluetooth PRs rejected without complete wireless code + - Wireless code may not include anything resembling precompiled data such as `*.a` files or other libraries + - Firmware blobs are not permitted in raw form or as compiled C-style arrays either. + - GPL2+ license requires full source disclosure + - Historically abused for VIA compatibility without releasing sources + - PRs without wireless capability will be held indefinitely + - Existing merged wireless boards from same vendor held until sources provided + +### ChibiOS-Specific Requirements +- **Board Definitions**: Strong preference for existing ChibiOS board definitions + - Use equivalent Nucleo boards when possible + - Example: STM32L082KZ can use `BOARD = ST_NUCLEO64_L073RZ` + - QMK is eliminating custom board definitions due to maintenance burden +- **New Board Definitions**: + - Must NOT be embedded in keyboard PR + - Submit as separate Core PR + - `board.c` must have standard `__early_init()` and empty `boardInit()` + - Migrate code intended for `__early_init()` → keyboard-local `early_hardware_init_pre/post()` + - Migrate code intended for `boardInit()` → keyboard-local `board_init()` + +--- + +## Core PR Reviews + +### Targeting and Scope +- **Branch**: All core PRs must target `develop` branch +- **Single Focus**: Smallest set of changes per PR + - PRs with multiple areas will be asked to split + - Keyboard/keymap changes only if affecting base builds or default-like keymaps + - Keymap modifications (non-default) should be followup PR after core merge + - Large refactoring PRs affecting other keymaps raised separately + +### Testing Requirements +- **New Hardware Support**: Requires test keyboard under `keyboards/handwired/onekey` + - New MCUs: Add child keyboard targeting new MCU for build verification + - New hardware (displays, matrix, peripherals): Provide associated keymap + - Exception: If existing keymap can leverage functionality (consult Collaborators) +- **Callbacks**: New `_kb`/`_user` callbacks must return `bool` for user override +- **Unit Tests**: Strongly recommended, may be required + - Critical code areas (keycode pipeline) will require tests + - Boost confidence in current and future correctness + +### Code Quality +- **Subjective Review**: Other requirements at QMK Collaborators' discretion +- **Documentation**: Core changes should be well-documented + +--- + +## Automated Review Checklist + +When reviewing PRs, check the following systematically: + +### File Changes Review +1. **License headers** on all C/H files (GPL2+ preferred, others must be GPL2+ compatible, SPDX format preferred) +2. **File naming** lowercase (flag exceptions needing justification) +3. **Include guards** use `#pragma once` +4. **No low-level hardware access** (GPIO, I2C, SPI direct register writes) +5. **Timing abstractions** (`wait_ms()`, `timer_read()` usage) + +### info.json and keyboard.json Validation +1. **Schema Compliance**: `keyboard.json` and `info.json` files validate against `data/schemas/keyboard.jsonschema` + - Both files are identical syntax, however the `keyboard.json` dictates a buildable target, `info.json` does not + - Run `qmk lint -kb ` to check schema validation + - Check for proper data types (strings, integers, arrays, objects) + - Verify required fields are present + - Ensure enum values match allowed options in schema +2. All mandatory fields present and valid +3. `qmk format-json -i` has been run (formats and validates) +4. Layout macros moved from headers +5. Community layout names used where applicable + +### rules.mk Cleanup +1. Deprecated features removed +2. No size comments +3. No keymap-only features at keyboard level +4. No redundant MCU parameter definitions + +### config.h Cleanup +1. No `DESCRIPTION`, `config_common.h`, or prohibited includes +2. No default value re-definitions +3. No commented-out defines or feature documentation blocks +4. No user preference defines at keyboard level + +### Keymap Quality +1. Default keymaps are pristine (no custom keycodes/advanced features) +2. No `QMKBEST`/`QMKURL` macros +3. Encoder map feature used instead of `encoder_update_user()` +4. Tri Layer feature used for multi-layer access +5. No VIA enabled in default keymap + +### Documentation +1. readme.md follows template +2. Flash command present with `:flash` +3. Reset instructions clear +4. External image hosting (direct links) +5. Valid hardware availability link + +### Code Organization +1. Empty weak-defined functions removed from `.c` +2. Proper migration of init functions +3. No cross-vendor source files +4. No VIA/KLE JSON files + +### Branch and Scope +1. Not submitted from submitter's own `master` branch (use feature branches) +2. PR is focused on single change +3. Targets correct branch: + - `master` for new keyboard additions + - `develop` for keyboard updates/refactors/moves and core changes +4. No merge conflicts + +--- + +## Review Response Templates + +### For source master branch usage: +``` +⚠️ This PR appears to be submitted from your own `master` branch. For future PRs, we recommend using feature branches instead of committing to your `master`. This makes it easier to keep your fork updated and manage multiple PRs. + +See: [Best Practices: Your Fork's Master](https://docs.qmk.fm/newbs_git_using_your_master_branch) +``` + +### For incorrect target branch: +``` +❌ This PR targets the wrong branch: +- **New keyboard additions** should target `master` +- **Keyboard updates/refactors/moves** should target `develop` +- **Core changes** should target `develop` + +Please change the target branch accordingly. +``` + +### For missing license headers: +``` +❌ Missing GPL-compatible license headers on the following files: +- [list files] + +Please add GPL2+ headers (GPL2/GPL3 recommended). Example: +\`\`\`c +// Copyright 2024 Your Name (@yourgithub) +// SPDX-License-Identifier: GPL-2.0-or-later +\`\`\` +``` + +### For non-lowercase filenames: +``` +❌ The following files/directories must be lowercase: +- [list files] + +Exception: Only valid if from upstream sources (LUFA, ChibiOS) or justified by core consistency. +``` + +### For config.h violations: +``` +⚠️ Found prohibited config.h elements: +- [list specific issues: DESCRIPTION, default value re-definitions, etc.] + +Please remove these and refer to [Data Driven Configuration](https://docs.qmk.fm/data_driven_config). +``` + +### For info.json or keyboard.json issues: +``` +⚠️ info.json or keyboard.json needs attention: +- [list missing mandatory fields] +- Please run: \`qmk format-json -i path/to/info.json\` (or keyboard.json) +- Validate with: \`qmk lint -kb \` +``` + +### For schema validation errors: +``` +❌ Schema validation failed for info.json or keyboard.json: +- [list specific validation errors from schema] +- Check `data/schemas/keyboard.jsonschema` for valid field definitions +- Common issues: + - Invalid data types (e.g., string instead of integer) + - Missing required fields + - Invalid enum values + - Incorrectly formatted pin definitions +``` + +### For non-pristine default keymap: +``` +⚠️ Default keymap should be pristine (clean slate for users): +- Remove: [custom keycodes/tap dance/macros/etc.] +- Keep it minimal with standard layouts where possible + +Consider moving advanced features to a separate example keymap. +``` + +--- + +## Notes for GitHub Copilot + +- Focus reviews on **objective checklist items** that can be automatically verified +- Flag **definite violations** with ❌ +- Suggest improvements for **recommendations** with ⚠️ +- **Provide specific file/line references** when flagging issues +- **Link to relevant QMK documentation** for each issue +- **Prioritize blocking issues** (license, merge conflicts, branch policy) +- **Be constructive**: Suggest fixes, not just problems +- **Acknowledge trade-offs**: Some guidelines have valid exceptions + +This is meant as a **first-pass review** to catch common issues before human review. Complex architectural decisions, code quality, and subjective assessments still require human QMK Collaborator review. From 863b30851949cf1f045328820d27bdc83d942190 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Tue, 20 Jan 2026 08:48:51 +0000 Subject: [PATCH 13/21] Fix avrdude version check logic (#25957) --- lib/python/qmk/cli/doctor/check.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py index 8a13cb083282..a717bcb591e4 100644 --- a/lib/python/qmk/cli/doctor/check.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -152,8 +152,10 @@ def _check_avr_gcc_installation(): def _check_avrdude_version(): - last_line = ESSENTIAL_BINARIES['avrdude']['output'].split('\n')[-2] - version_number = last_line.split()[2][:-1] + lines = ESSENTIAL_BINARIES['avrdude']['output'].split('\n') + # avrdude version text is currently not translated, however we fall back to old behaviour of assuming a line + version_line = next((line for line in lines if 'version' in line), lines[-2]) + version_number = version_line.split()[2][:-1] cli.log.info('Found avrdude version %s', version_number) return CheckStatus.OK From 38815db760f24268561f7fd138f1094d546b4f13 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 24 Jan 2026 16:43:55 -0800 Subject: [PATCH 14/21] Fixup tominabox1 le chiffre default keymap (#25966) * Fixup tominabox1 le chiffre default keymap * Apply suggestions from code review Co-authored-by: Jack Sangdahl --------- Co-authored-by: Jack Sangdahl --- .../le_chiffre/keymaps/default/config.h | 18 -- .../le_chiffre/keymaps/default/keymap.c | 155 ------------------ .../le_chiffre/keymaps/default/keymap.json | 36 ++++ .../le_chiffre/keymaps/default/rules.mk | 2 - 4 files changed, 36 insertions(+), 175 deletions(-) delete mode 100644 keyboards/tominabox1/le_chiffre/keymaps/default/config.h delete mode 100644 keyboards/tominabox1/le_chiffre/keymaps/default/keymap.c create mode 100644 keyboards/tominabox1/le_chiffre/keymaps/default/keymap.json delete mode 100644 keyboards/tominabox1/le_chiffre/keymaps/default/rules.mk diff --git a/keyboards/tominabox1/le_chiffre/keymaps/default/config.h b/keyboards/tominabox1/le_chiffre/keymaps/default/config.h deleted file mode 100644 index 8f0df1847a59..000000000000 --- a/keyboards/tominabox1/le_chiffre/keymaps/default/config.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2020 tominabox1 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once - -#define COMBO_TERM 30 diff --git a/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.c b/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.c deleted file mode 100644 index 756eb06506f8..000000000000 --- a/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright 2020 tominabox1 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include QMK_KEYBOARD_H - -enum layers { - _BASE, - _NUM_SYM, - _NAV -}; - -#define KC_NUM_SPC LT(_NUM_SYM, KC_SPC) -#define KC_GA LGUI_T(KC_A) -#define KC_AS LALT_T(KC_S) -#define KC_CD LCTL_T(KC_D) -#define KC_SF LSFT_T(KC_F) -#define KC_SJ RSFT_T(KC_J) -#define KC_CK RCTL_T(KC_K) -#define KC_AL RALT_T(KC_L) -#define KC_GSCLN RGUI_T(KC_SCLN) - -// clang-format off -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [_BASE] = LAYOUT( - KC_Q, KC_W, KC_E, KC_R, KC_T, KC_MPLY, KC_Y, KC_U, KC_I, KC_O, KC_P, - KC_GA, KC_AS, KC_CD, KC_SF, KC_G, KC_H, KC_SJ, KC_CK, KC_AL, KC_GSCLN, - KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, - KC_LCTL, KC_ENT, KC_NUM_SPC, MO(_NAV) - ), - - [_NUM_SYM] = LAYOUT( - KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_EQUAL, KC_MINS, - KC_BSLS,KC_LCBR, KC_LBRC, KC_LPRN, KC_UNDS, KC_RPRN, KC_RBRC, KC_RCBR, KC_DOT, KC_GRV, - KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS - ), - - [_NAV] = LAYOUT( - QK_BOOT, _______, AG_NORM, AG_SWAP, DB_TOGG, KC_TRNS, KC_GRV, KC_PGDN, KC_UP, KC_PGUP, KC_SCLN, - RM_TOGG, RM_HUEU, RM_SATU, RM_VALU, KC_NO, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, - RM_NEXT, RM_HUED, RM_SATD, RM_VALD, KC_NO, KC_MINS, KC_INT1, KC_COMM, KC_DOT, KC_BSLS, - KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS - ) -}; -// clang-format on - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_BASE] = {ENCODER_CCW_CW(KC_MNXT, KC_MPRV) }, - [_NUM_SYM] = { ENCODER_CCW_CW(MS_WHLD, MS_WHLU) }, - [_NAV] = { ENCODER_CCW_CW(KC_PGDN, KC_PGUP) } -}; -#endif - -#ifdef COMBO_ENABLE -enum combo_events { - COMBO_BSPC, - COMBO_NUMBAK, - COMBO_TAB, - COMBO_ESC, - COMBO_DEL, -}; - -const uint16_t PROGMEM combo_bspc[] = {KC_O, KC_P, COMBO_END}; -const uint16_t PROGMEM combo_numbak[] = {KC_0, KC_9, COMBO_END}; -const uint16_t PROGMEM combo_tab[] = {KC_Q, KC_W, COMBO_END}; -const uint16_t PROGMEM combo_esc[] = {KC_E, KC_W, COMBO_END}; -const uint16_t PROGMEM combo_del[] = {KC_MINS, KC_EQL, COMBO_END}; - -combo_t key_combos[] = { - [COMBO_BSPC] = COMBO(combo_bspc, KC_BSPC), - [COMBO_NUMBAK] = COMBO(combo_numbak, KC_BSPC), - [COMBO_TAB] = COMBO(combo_tab, KC_TAB), - [COMBO_ESC] = COMBO(combo_esc, KC_ESC), - [COMBO_DEL] = COMBO(combo_del, KC_DEL) -}; -#endif - -#ifdef OLED_ENABLE - -// Add additional layer names here if desired. Only first 5 characters will be copied to display. -const char PROGMEM layer_base[] = "BASE"; -const char PROGMEM layer_num_sym[] = " SYM"; -const char PROGMEM layer_nav[] = " NAV"; -// Add layer name variables to array here. Make sure these are in order. -const char* const PROGMEM layer_names[] = { - layer_base, - layer_num_sym, - layer_nav -}; - -static char oled_layer_buf[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static layer_state_t top_layer_cache; - -/* BEGIN STANDARD QMK FUNCTIONS */ -bool oled_task_user(void) { - oled_write_raw_P(lechiffre_logo, sizeof(lechiffre_logo)); - // Renders the current keyboard state (layer, lock, caps, scroll, etc); - oled_set_cursor(0, 3); - oled_write_P(oled_section_break, false); - render_layer_status(oled_layer_buf); - oled_write_P(oled_section_break, false); - render_mod_status(get_mods() | get_oneshot_mods()); - oled_write_P(oled_section_break, false); - render_keylock_status(host_keyboard_led_state()); - oled_write_P(oled_section_break, false); - render_keylogger_status(); - - return false; -} - -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - if (record->event.pressed) { - add_keylog(keycode, record); - } - - return true; -} - -// If we don't force an update during initialization, the layer name buffer will start out blank. -layer_state_t default_layer_state_set_user(layer_state_t state) { - update_layer_namebuf(get_highest_layer(state), true); - return state; -} -layer_state_t layer_state_set_user(layer_state_t state) { - update_layer_namebuf(get_highest_layer(state | default_layer_state), false); - return state; -} - -/* END STANDARD QMK FUNCTIONS */ -/* BEGIN CUSTOM HELPER FUNCTION FOR OLED */ -// Avoid excessive copying by only updating the layer name buffer when the layer changes -void update_layer_namebuf(layer_state_t layer, bool force_update) { - if (force_update || layer != top_layer_cache) { - top_layer_cache = layer; - if (layer < ARRAY_SIZE(layer_names)) { - memcpy_P(oled_layer_buf, pgm_read_ptr(&layer_names[layer]), ARRAY_SIZE(oled_layer_buf) - 1); - } else { - memcpy(oled_layer_buf, get_u8_str(layer, ' '), ARRAY_SIZE(oled_layer_buf) - 1); - } - } -} -#endif diff --git a/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.json b/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.json new file mode 100644 index 000000000000..252db21f5d87 --- /dev/null +++ b/keyboards/tominabox1/le_chiffre/keymaps/default/keymap.json @@ -0,0 +1,36 @@ +{ + "keyboard": "tominabox1/le_chiffre", + "keymap": "default", + "config": { + "features": { + "encoder_map": true + } + }, + "layout": "LAYOUT", + "layers": [ + [ + "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_MPLY", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P", + "LGUI_T(KC_A)", "LALT_T(KC_S)", "LCTL_T(KC_D)", "LSFT_T(KC_F)", "KC_G", "KC_H", "RSFT_T(KC_J)", "RCTL_T(KC_K)", "RALT_T(KC_L)", "RGUI_T(KC_SCLN)", + "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", + "KC_LCTL", "KC_ENT", "LT(1, KC_SPC)", "MO(2)" + ], + [ + "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_TRNS", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", + "KC_EXLM", "KC_AT", "KC_HASH", "KC_DLR", "KC_PERC", "KC_CIRC", "KC_AMPR", "KC_ASTR", "KC_EQUAL", "KC_MINS", + "KC_BSLS", "KC_LCBR", "KC_LBRC", "KC_LPRN", "KC_UNDS", "KC_RPRN", "KC_RBRC", "KC_RCBR", "KC_DOT", "KC_GRV", + "KC_CAPS", "KC_TRNS", "KC_TRNS", "KC_TRNS" + ], + [ + "QK_BOOT", "KC_TRNS", "AG_NORM", "AG_SWAP", "DB_TOGG", "KC_TRNS", "KC_GRV", "KC_PGDN", "KC_UP", "KC_PGUP", + "KC_SCLN", "RM_TOGG", "RM_HUEU", "RM_SATU", "RM_VALU", "KC_NO", "KC_HOME", "KC_LEFT", "KC_DOWN", "KC_RGHT", + "KC_END", "RM_NEXT", "RM_HUED", "RM_SATD", "RM_VALD", "KC_NO", "KC_MINS", "KC_INT1", "KC_COMM", "KC_DOT", "KC_BSLS", + "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS" + ] + + ], + "encoders": [ + [{"ccw": "KC_MNXT", "cw": "KC_MPRV"}], + [{"ccw": "MS_WHLD", "cw": "MS_WHLU"}], + [{"ccw": "KC_PGDN", "cw": "KC_PGUP"}] + ] +} diff --git a/keyboards/tominabox1/le_chiffre/keymaps/default/rules.mk b/keyboards/tominabox1/le_chiffre/keymaps/default/rules.mk deleted file mode 100644 index cbd8b4aa81ff..000000000000 --- a/keyboards/tominabox1/le_chiffre/keymaps/default/rules.mk +++ /dev/null @@ -1,2 +0,0 @@ -COMBO_ENABLE = yes -ENCODER_MAP_ENABLE = yes From b02b222f171166eb05e197b69dd05a60e6d23324 Mon Sep 17 00:00:00 2001 From: schuay Date: Sun, 27 Jul 2025 12:09:15 +0200 Subject: [PATCH 15/21] Import cheapino https://github.com/tompi/qmk_firmware/tree/cheapinov2-miryoku# at b1e2da5dc395e82db8096cb80575a02c7e1b7079 --- keyboards/cheapino/cheapino.c | 75 +++++++++++++++++ keyboards/cheapino/config.h | 43 ++++++++++ keyboards/cheapino/encoder.c | 63 ++++++++++++++ keyboards/cheapino/encoder.h | 5 ++ keyboards/cheapino/ghosting.c | 128 ++++++++++++++++++++++++++++ keyboards/cheapino/ghosting.h | 5 ++ keyboards/cheapino/halconf.h | 8 ++ keyboards/cheapino/info.json | 93 +++++++++++++++++++++ keyboards/cheapino/matrix.c | 152 ++++++++++++++++++++++++++++++++++ keyboards/cheapino/mcuconf.h | 6 ++ keyboards/cheapino/readme.md | 27 ++++++ keyboards/cheapino/rules.mk | 8 ++ 12 files changed, 613 insertions(+) create mode 100644 keyboards/cheapino/cheapino.c create mode 100644 keyboards/cheapino/config.h create mode 100644 keyboards/cheapino/encoder.c create mode 100644 keyboards/cheapino/encoder.h create mode 100644 keyboards/cheapino/ghosting.c create mode 100644 keyboards/cheapino/ghosting.h create mode 100644 keyboards/cheapino/halconf.h create mode 100644 keyboards/cheapino/info.json create mode 100644 keyboards/cheapino/matrix.c create mode 100644 keyboards/cheapino/mcuconf.h create mode 100644 keyboards/cheapino/readme.md create mode 100644 keyboards/cheapino/rules.mk diff --git a/keyboards/cheapino/cheapino.c b/keyboards/cheapino/cheapino.c new file mode 100644 index 000000000000..cfc4592bf4e1 --- /dev/null +++ b/keyboards/cheapino/cheapino.c @@ -0,0 +1,75 @@ +#include "wait.h" +#include "quantum.h" + +// This is to keep state between callbacks, when it is 0 the +// initial RGB flash is finished +uint8_t _hue_countdown = 50; + +// These are to keep track of user selected color, so we +// can restore it after RGB flash +uint8_t _hue; +uint8_t _saturation; +uint8_t _value; + +// Do a little 2.5 seconds display of the different colors +// Use the deferred executor so the LED flash dance does not +// stop us from using the keyboard. +// https://docs.qmk.fm/#/custom_quantum_functions?id=deferred-executor-registration +uint32_t flash_led(uint32_t next_trigger_time, void *cb_arg) { + rgblight_sethsv(_hue_countdown * 5, 230, 70); + _hue_countdown--; + if (_hue_countdown == 0) { + // Finished, reset to user chosen led color + rgblight_sethsv(_hue, _saturation, _value); + return 0; + } else { + return 50; + } +} + +void keyboard_post_init_user(void) { + //debug_enable=true; + //debug_matrix=true; + //debug_keyboard=true; + //debug_mouse=true; + + // Store user selected rgb hsv: + _hue = rgblight_get_hue(); + _saturation = rgblight_get_sat(); + _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; +} +*/ diff --git a/keyboards/cheapino/config.h b/keyboards/cheapino/config.h new file mode 100644 index 000000000000..616feccf9a49 --- /dev/null +++ b/keyboards/cheapino/config.h @@ -0,0 +1,43 @@ +// Copyright 2023 Thomas Haukland (@tompi) +// SPDX-License-Identifier: GPL-2.0-or-later + +#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 +#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 diff --git a/keyboards/cheapino/encoder.c b/keyboards/cheapino/encoder.c new file mode 100644 index 000000000000..e5920dce49a8 --- /dev/null +++ b/keyboards/cheapino/encoder.c @@ -0,0 +1,63 @@ +#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; +} diff --git a/keyboards/cheapino/encoder.h b/keyboards/cheapino/encoder.h new file mode 100644 index 000000000000..e393e5da2dac --- /dev/null +++ b/keyboards/cheapino/encoder.h @@ -0,0 +1,5 @@ +// +// Created by Thomas Haukland on 25/03/2023. +// + +void fix_encoder_action(matrix_row_t current_matrix[]); \ No newline at end of file diff --git a/keyboards/cheapino/ghosting.c b/keyboards/cheapino/ghosting.c new file mode 100644 index 000000000000..c349b0abe198 --- /dev/null +++ b/keyboards/cheapino/ghosting.c @@ -0,0 +1,128 @@ +// +// Created by Thomas Haukland on 2024-05-05. +// + +#include "matrix.h" +#include "quantum.h" +#include "print.h" + +// This is just to be able to declare constants as they appear in the qmk console +#define rev(b) \ + ((b & 1) << 15) | \ + ((b & (1 << 1)) << 13) | \ + ((b & (1 << 2)) << 11) | \ + ((b & (1 << 3)) << 9) | \ + ((b & (1 << 4)) << 7) | \ + ((b & (1 << 5)) << 5) | \ + ((b & (1 << 6)) << 3) | \ + ((b & (1 << 7)) << 1) | \ + ((b & (1 << 8)) >> 1) | \ + ((b & (1 << 9)) >> 3) | \ + ((b & (1 << 10)) >> 5) | \ + ((b & (1 << 11)) >> 7) | \ + ((b & (1 << 12)) >> 9) | \ + ((b & (1 << 13)) >> 11) | \ + ((b & (1 << 14)) >> 13) | \ + b >> 15 + +/* This is for debugging the matrix rows +void printBits(uint16_t n) +{ + long i; + for (i = 15; i >= 0; i--) { + if ((n & (1 << i)) != 0) { + printf("1"); + } + else { + printf("0"); + } + } + printf("\n"); +} +*/ + +bool bit_pattern_set(uint16_t number, uint16_t bitPattern) { + return !(~number & bitPattern); +} + +void fix_ghosting_instance( + matrix_row_t current_matrix[], + unsigned short row_num_with_possible_error_cause, + uint16_t possible_error_cause, + unsigned short row_num_with_possible_error, + uint16_t possible_error, + uint16_t error_fix) { + if (bit_pattern_set(current_matrix[row_num_with_possible_error_cause], possible_error_cause)) { + if (bit_pattern_set(current_matrix[row_num_with_possible_error], possible_error)) { + current_matrix[row_num_with_possible_error] = current_matrix[row_num_with_possible_error] ^ error_fix; + } + } +} + +void fix_ghosting_column( + matrix_row_t matrix[], + uint16_t possible_error_cause, + uint16_t possible_error, + uint16_t error_fix) { + // First the right side + for (short i = 0; i<3; i++) { + fix_ghosting_instance(matrix, i, possible_error_cause, (i+1)%3, possible_error, error_fix); + fix_ghosting_instance(matrix, i, possible_error_cause, (i+2)%3, possible_error, error_fix); + } + + // Then exactly same procedure on the left side + for (short i = 0; i<3; i++) { + fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+1)%3), possible_error<<6, error_fix<<6); + fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+2)%3), possible_error<<6, error_fix<<6); + } +} + +// For QWERTY layout, key combo a+s+e also outputs q. This suppresses the q, and other similar ghosts +// These are observed ghosts(following a pattern). TODO: need to fix this for v3 +// Might need to add 2 diodes(one in each direction) for every row, to increase voltage drop. +void fix_ghosting(matrix_row_t matrix[]) { + fix_ghosting_column(matrix, + rev(0B0110000000000000), + rev(0B1010000000000000), + rev(0B0010000000000000)); + fix_ghosting_column(matrix, + rev(0B0110000000000000), + rev(0B0101000000000000), + rev(0B0100000000000000)); + + fix_ghosting_column(matrix, + rev(0B0001100000000000), + rev(0B0010100000000000), + rev(0B0000100000000000)); + fix_ghosting_column(matrix, + rev(0B0001100000000000), + rev(0B0001010000000000), + rev(0B0001000000000000)); + + fix_ghosting_column(matrix, + rev(0B1000010000000000), + rev(0B1000100000000000), + rev(0B1000000000000000)); + fix_ghosting_column(matrix, + rev(0B1000010000000000), + rev(0B0100010000000000), + rev(0B0000010000000000)); + + fix_ghosting_column(matrix, + rev(0B1001000000000000), + rev(0B0101000000000000), + rev(0B0001000000000000)); + fix_ghosting_column(matrix, + rev(0B1001000000000000), + rev(0B1010000000000000), + rev(0B1000000000000000)); + + fix_ghosting_column(matrix, + rev(0B0100100000000000), + rev(0B0100010000000000), + rev(0B0100000000000000)); + fix_ghosting_column(matrix, + rev(0B0100100000000000), + rev(0B1000100000000000), + rev(0B0000100000000000)); +} diff --git a/keyboards/cheapino/ghosting.h b/keyboards/cheapino/ghosting.h new file mode 100644 index 000000000000..1dfef2af3fde --- /dev/null +++ b/keyboards/cheapino/ghosting.h @@ -0,0 +1,5 @@ +// +// Created by Thomas Haukland on 2024-05-05. +// + +void fix_ghosting(matrix_row_t current_matrix[]); \ No newline at end of file diff --git a/keyboards/cheapino/halconf.h b/keyboards/cheapino/halconf.h new file mode 100644 index 000000000000..c06a0cbf6cce --- /dev/null +++ b/keyboards/cheapino/halconf.h @@ -0,0 +1,8 @@ + +#pragma once + +#define HAL_USE_PWM TRUE +#define HAL_USE_PAL TRUE +#define HAL_USE_I2C TRUE + +#include_next diff --git a/keyboards/cheapino/info.json b/keyboards/cheapino/info.json new file mode 100644 index 000000000000..e12d8f2ab043 --- /dev/null +++ b/keyboards/cheapino/info.json @@ -0,0 +1,93 @@ +{ + "manufacturer": "Thomas Haukland", + "keyboard_name": "cheapino2", + "maintainer": "tompi", + "bootloader": "rp2040", + "diode_direction": "ROW2COL", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": false + }, + "community_layouts": ["split_3x5_3"], + "matrix_pins": { + "cols": [ + "GP6", + "GP6", + "GP5", + "GP5", + "GP4", + "GP4", + + "GP14", + "GP14", + "GP15", + "GP15", + "GP26", + "GP26" + ], + "rows": ["GP3", "GP1", "GP2", "GP0", "GP27", "GP28", "GP29", "GP8"] + }, + "processor": "RP2040", + "url": "", + "usb": { + "device_version": "1.0.0", + "pid": "0x0000", + "vid": "0xFEE3" + }, + "layouts": { + "LAYOUT_split_3x5_3": { + "layout": [ + { "matrix": [4, 10], "x": 0, "y": 0.25 }, + { "matrix": [4, 9], "x": 1, "y": 0.125 }, + { "matrix": [4, 8], "x": 2, "y": 0 }, + { "matrix": [4, 7], "x": 3, "y": 0.125 }, + { "matrix": [4, 6], "x": 4, "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 }, + { "matrix": [0, 3], "x": 10, "y": 0.125 }, + { "matrix": [0, 4], "x": 11, "y": 0.25 }, + + + { "matrix": [5, 10], "x": 0, "y": 1.25 }, + { "matrix": [5, 9], "x": 1, "y": 1.125 }, + { "matrix": [5, 8], "x": 2, "y": 1 }, + { "matrix": [5, 7], "x": 3, "y": 1.125 }, + { "matrix": [5, 6], "x": 4, "y": 1.25 }, + + { "matrix": [1, 0], "x": 7, "y": 1.25 }, + { "matrix": [1, 1], "x": 8, "y": 1.125 }, + { "matrix": [1, 2], "x": 9, "y": 1 }, + { "matrix": [1, 3], "x": 10, "y": 1.125 }, + { "matrix": [1, 4], "x": 11, "y": 1.25 }, + + + { "matrix": [6, 10], "x": 0, "y": 2.25 }, + { "matrix": [6, 9], "x": 1, "y": 2.125 }, + { "matrix": [6, 8], "x": 2, "y": 2 }, + { "matrix": [6, 7], "x": 3, "y": 2.125 }, + { "matrix": [6, 6], "x": 4, "y": 2.25 }, + + { "matrix": [2, 0], "x": 7, "y": 2.25 }, + { "matrix": [2, 1], "x": 8, "y": 2.125 }, + { "matrix": [2, 2], "x": 9, "y": 2 }, + { "matrix": [2, 3], "x": 10, "y": 2.125 }, + { "matrix": [2, 4], "x": 11, "y": 2.25 }, + + + { "matrix": [6, 11], "x": 2.5, "y": 3.25 }, + { "matrix": [5, 11], "x": 3.5, "y": 3.5 }, + { "matrix": [4, 11], "x": 4.5, "y": 3.75 }, + + { "matrix": [0, 5], "x": 6.5, "y": 3.75 }, + { "matrix": [1, 5], "x": 7.5, "y": 3.5 }, + { "matrix": [2, 5], "x": 8.5, "y": 3.25 } + ] + } + } +} diff --git a/keyboards/cheapino/matrix.c b/keyboards/cheapino/matrix.c new file mode 100644 index 000000000000..f6f518318b26 --- /dev/null +++ b/keyboards/cheapino/matrix.c @@ -0,0 +1,152 @@ +/* +Copyright 2012 Jun Wako +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . + + Copied from here: https://github.com/e3w2q/qmk_firmware/blob/762fe3e0a7cbea768245a75520f06ff5a2f00b9f/keyboards/2x3test/matrix.c +*/ + +/* + * scan matrix + */ +#include +#include +#include "wait.h" +#include "util.h" +#include "matrix.h" +#include "config.h" +#include "quantum.h" +#include "debounce.h" +#include "encoder.h" +#include "ghosting.h" +#include "print.h" + +// How long the scanning code waits for changed io to settle. +// Adjust from default 30 to weigh up for increased time spent ghost-hunting. +// (the rp2040 does not seem to have any problems with this value...) +#define MATRIX_IO_DELAY 25 + +#define COL_SHIFTER ((uint16_t)1) + +static const pin_t row_pins[] = MATRIX_ROW_PINS; +static const pin_t col_pins[] = MATRIX_COL_PINS; +static matrix_row_t previous_matrix[MATRIX_ROWS]; + +static void select_row(uint8_t row) { + setPinOutput(row_pins[row]); + writePinLow(row_pins[row]); +} + +static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); } + +static void unselect_rows(void) { + for (uint8_t x = 0; x < MATRIX_ROWS; x++) { + setPinInputHigh(row_pins[x]); + } +} + +static void select_col(uint8_t col) { + setPinOutput(col_pins[col]); + writePinLow(col_pins[col]); +} + +static void unselect_col(uint8_t col) { + setPinInputHigh(col_pins[col]); +} + +static void unselect_cols(void) { + for (uint8_t x = 0; x < MATRIX_COLS/2; x++) { + setPinInputHigh(col_pins[x*2]); + } +} + +static void read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { + // Select row and wait for row selection to stabilize + select_row(current_row); + wait_us(MATRIX_IO_DELAY); + + // For each col... + for (uint8_t col_index = 0; col_index < MATRIX_COLS / 2; col_index++) { + uint16_t column_index_bitmask = COL_SHIFTER << ((col_index * 2) + 1); + // Check row pin state + if (readPin(col_pins[col_index*2])) { + // Pin HI, clear col bit + current_matrix[current_row] &= ~column_index_bitmask; + } else { + // Pin LO, set col bit + current_matrix[current_row] |= column_index_bitmask; + } + } + + // Unselect row + unselect_row(current_row); +} + +static void read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { + // Select col and wait for col selection to stabilize + select_col(current_col*2); + wait_us(MATRIX_IO_DELAY); + + uint16_t column_index_bitmask = COL_SHIFTER << (current_col * 2); + // For each row... + for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { + // Check row pin state + if (readPin(row_pins[row_index])) { + // Pin HI, clear col bit + current_matrix[row_index] &= ~column_index_bitmask; + } else { + // Pin LO, set col bit + current_matrix[row_index] |= column_index_bitmask; + } + } + // Unselect col + unselect_col(current_col*2); +} + + +void matrix_init_custom(void) { + // initialize key pins + unselect_cols(); + unselect_rows(); + debounce_init(MATRIX_ROWS); +} + +void store_old_matrix(matrix_row_t current_matrix[]) { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + previous_matrix[i] = current_matrix[i]; + } +} + +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; +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + store_old_matrix(current_matrix); + // Set row, read cols + for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { + read_cols_on_row(current_matrix, current_row); + } + // Set col, read rows + for (uint8_t current_col = 0; current_col < MATRIX_COLS/2; current_col++) { + read_rows_on_col(current_matrix, current_col); + } + + fix_encoder_action(current_matrix); + + fix_ghosting(current_matrix); + + return has_matrix_changed(current_matrix); +} + diff --git a/keyboards/cheapino/mcuconf.h b/keyboards/cheapino/mcuconf.h new file mode 100644 index 000000000000..7ed3f874511e --- /dev/null +++ b/keyboards/cheapino/mcuconf.h @@ -0,0 +1,6 @@ + #pragma once + +#include_next + +#undef RP_I2C_USE_I2C1 +#define RP_I2C_USE_I2C1 TRUE diff --git a/keyboards/cheapino/readme.md b/keyboards/cheapino/readme.md new file mode 100644 index 000000000000..4901584a1ca7 --- /dev/null +++ b/keyboards/cheapino/readme.md @@ -0,0 +1,27 @@ +# cheapino + +![cheapino](imgur.com image replace me!) + +*A short description of the keyboard/project* + +* Keyboard Maintainer: [Thomas Haukland](https://github.com/tompi) +* Hardware Supported: *The PCBs, controllers supported* +* Hardware Availability: *Links to where you can find this hardware* + +Make example for this keyboard (after setting up your build environment): + + make cheapino:default + +Flashing example for this keyboard: + + make cheapino: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 (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard +* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead +* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available diff --git a/keyboards/cheapino/rules.mk b/keyboards/cheapino/rules.mk new file mode 100644 index 000000000000..70ed45868bc3 --- /dev/null +++ b/keyboards/cheapino/rules.mk @@ -0,0 +1,8 @@ +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 \ No newline at end of file From 3236973ced26d9f3a6bdd58b32a4a9bfdc8c2a68 Mon Sep 17 00:00:00 2001 From: schuay Date: Wed, 30 Jul 2025 18:07:15 +0200 Subject: [PATCH 16/21] 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. --- keyboards/cheapino/cheapino.c | 49 +++------------ keyboards/cheapino/config.h | 39 +----------- keyboards/cheapino/encoder.c | 63 ------------------- keyboards/cheapino/encoder.h | 5 -- keyboards/cheapino/halconf.h | 8 --- .../cheapino/{info.json => keyboard.json} | 52 ++++++++++++++- keyboards/cheapino/matrix-encoder.c | 50 +++++++++++++++ keyboards/cheapino/matrix-encoder.h | 6 ++ .../{ghosting.c => matrix-ghosting.c} | 0 .../{ghosting.h => matrix-ghosting.h} | 0 keyboards/cheapino/matrix.c | 13 ++-- keyboards/cheapino/rules.mk | 11 +--- 12 files changed, 122 insertions(+), 174 deletions(-) delete mode 100644 keyboards/cheapino/encoder.c delete mode 100644 keyboards/cheapino/encoder.h delete mode 100644 keyboards/cheapino/halconf.h rename keyboards/cheapino/{info.json => keyboard.json} (73%) create mode 100644 keyboards/cheapino/matrix-encoder.c create mode 100644 keyboards/cheapino/matrix-encoder.h rename keyboards/cheapino/{ghosting.c => matrix-ghosting.c} (100%) rename keyboards/cheapino/{ghosting.h => matrix-ghosting.h} (100%) diff --git a/keyboards/cheapino/cheapino.c b/keyboards/cheapino/cheapino.c index cfc4592bf4e1..284ba3a755d4 100644 --- a/keyboards/cheapino/cheapino.c +++ b/keyboards/cheapino/cheapino.c @@ -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; -} -*/ diff --git a/keyboards/cheapino/config.h b/keyboards/cheapino/config.h index 616feccf9a49..f4cd51d9d17e 100644 --- a/keyboards/cheapino/config.h +++ b/keyboards/cheapino/config.h @@ -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 diff --git a/keyboards/cheapino/encoder.c b/keyboards/cheapino/encoder.c deleted file mode 100644 index e5920dce49a8..000000000000 --- a/keyboards/cheapino/encoder.c +++ /dev/null @@ -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; -} diff --git a/keyboards/cheapino/encoder.h b/keyboards/cheapino/encoder.h deleted file mode 100644 index e393e5da2dac..000000000000 --- a/keyboards/cheapino/encoder.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by Thomas Haukland on 25/03/2023. -// - -void fix_encoder_action(matrix_row_t current_matrix[]); \ No newline at end of file diff --git a/keyboards/cheapino/halconf.h b/keyboards/cheapino/halconf.h deleted file mode 100644 index c06a0cbf6cce..000000000000 --- a/keyboards/cheapino/halconf.h +++ /dev/null @@ -1,8 +0,0 @@ - -#pragma once - -#define HAL_USE_PWM TRUE -#define HAL_USE_PAL TRUE -#define HAL_USE_I2C TRUE - -#include_next diff --git a/keyboards/cheapino/info.json b/keyboards/cheapino/keyboard.json similarity index 73% rename from keyboards/cheapino/info.json rename to keyboards/cheapino/keyboard.json index e12d8f2ab043..1c6d426651a2 100644 --- a/keyboards/cheapino/info.json +++ b/keyboards/cheapino/keyboard.json @@ -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 }, diff --git a/keyboards/cheapino/matrix-encoder.c b/keyboards/cheapino/matrix-encoder.c new file mode 100644 index 000000000000..26101198c89e --- /dev/null +++ b/keyboards/cheapino/matrix-encoder.c @@ -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; +} diff --git a/keyboards/cheapino/matrix-encoder.h b/keyboards/cheapino/matrix-encoder.h new file mode 100644 index 000000000000..b32b25c59484 --- /dev/null +++ b/keyboards/cheapino/matrix-encoder.h @@ -0,0 +1,6 @@ +// +// Created by Thomas Haukland on 25/03/2023. +// +#include "quantum.h" + +void fix_encoder_action(matrix_row_t current_matrix[]); diff --git a/keyboards/cheapino/ghosting.c b/keyboards/cheapino/matrix-ghosting.c similarity index 100% rename from keyboards/cheapino/ghosting.c rename to keyboards/cheapino/matrix-ghosting.c diff --git a/keyboards/cheapino/ghosting.h b/keyboards/cheapino/matrix-ghosting.h similarity index 100% rename from keyboards/cheapino/ghosting.h rename to keyboards/cheapino/matrix-ghosting.h diff --git a/keyboards/cheapino/matrix.c b/keyboards/cheapino/matrix.c index f6f518318b26..ff3b3b7bb1c0 100644 --- a/keyboards/cheapino/matrix.c +++ b/keyboards/cheapino/matrix.c @@ -25,8 +25,8 @@ along with this program. If not, see . #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[]) { diff --git a/keyboards/cheapino/rules.mk b/keyboards/cheapino/rules.mk index 70ed45868bc3..8ca133bf1eb3 100644 --- a/keyboards/cheapino/rules.mk +++ b/keyboards/cheapino/rules.mk @@ -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 \ No newline at end of file +SRC += matrix-encoder.c +SRC += matrix-ghosting.c +SRC += matrix.c From 03715991769f768556712c30ba29513e298a2b52 Mon Sep 17 00:00:00 2001 From: schuay Date: Wed, 31 Dec 2025 10:25:27 +0100 Subject: [PATCH 17/21] disable lto and enable encoder by default --- keyboards/cheapino/keyboard.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/keyboards/cheapino/keyboard.json b/keyboards/cheapino/keyboard.json index 1c6d426651a2..e7dc06f6651e 100644 --- a/keyboards/cheapino/keyboard.json +++ b/keyboards/cheapino/keyboard.json @@ -8,15 +8,13 @@ "driver": "vendor", "pin": "GP16" }, - "build": { - "lto": true - }, "features": { "bootmagic": true, "caps_word": true, "command": false, "console": false, "deferred_exec": true, + "encoder": true, "extrakey": true, "mousekey": true, "nkro": false, From b7936ccfcd07c341902eb4bc49af43c02f2d0900 Mon Sep 17 00:00:00 2001 From: schuay Date: Wed, 31 Dec 2025 10:29:56 +0100 Subject: [PATCH 18/21] update debounce_init signature --- keyboards/cheapino/matrix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboards/cheapino/matrix.c b/keyboards/cheapino/matrix.c index ff3b3b7bb1c0..88c18f8a2d14 100644 --- a/keyboards/cheapino/matrix.c +++ b/keyboards/cheapino/matrix.c @@ -116,7 +116,7 @@ void matrix_init_custom(void) { // initialize key pins unselect_cols(); unselect_rows(); - debounce_init(MATRIX_ROWS); + debounce_init(); } void store_old_matrix(matrix_row_t current_matrix[]) { From b4abbab680debe2034f43b9125dab1058d73858b Mon Sep 17 00:00:00 2001 From: schuay Date: Thu, 1 Jan 2026 09:08:13 +0100 Subject: [PATCH 19/21] simplify file structure --- keyboards/cheapino/cheapino.c | 172 +++++++++++++++++++++++++++ keyboards/cheapino/matrix-encoder.c | 50 -------- keyboards/cheapino/matrix-encoder.h | 6 - keyboards/cheapino/matrix-ghosting.c | 128 -------------------- keyboards/cheapino/matrix-ghosting.h | 5 - keyboards/cheapino/matrix.c | 5 +- keyboards/cheapino/rules.mk | 2 - 7 files changed, 175 insertions(+), 193 deletions(-) delete mode 100644 keyboards/cheapino/matrix-encoder.c delete mode 100644 keyboards/cheapino/matrix-encoder.h delete mode 100644 keyboards/cheapino/matrix-ghosting.c delete mode 100644 keyboards/cheapino/matrix-ghosting.h diff --git a/keyboards/cheapino/cheapino.c b/keyboards/cheapino/cheapino.c index 284ba3a755d4..6cda581600a1 100644 --- a/keyboards/cheapino/cheapino.c +++ b/keyboards/cheapino/cheapino.c @@ -1,3 +1,7 @@ +#include "matrix.h" +#include "quantum.h" +#include "print.h" + #include QMK_KEYBOARD_H // This is to keep state between callbacks, when it is 0 the @@ -40,3 +44,171 @@ void keyboard_post_init_kb(void) { // Flash a little on start defer_exec(50, flash_led, NULL); } + +// This is just to be able to declare constants as they appear in the qmk console +#define rev(b) \ + ((b & 1) << 15) | \ + ((b & (1 << 1)) << 13) | \ + ((b & (1 << 2)) << 11) | \ + ((b & (1 << 3)) << 9) | \ + ((b & (1 << 4)) << 7) | \ + ((b & (1 << 5)) << 5) | \ + ((b & (1 << 6)) << 3) | \ + ((b & (1 << 7)) << 1) | \ + ((b & (1 << 8)) >> 1) | \ + ((b & (1 << 9)) >> 3) | \ + ((b & (1 << 10)) >> 5) | \ + ((b & (1 << 11)) >> 7) | \ + ((b & (1 << 12)) >> 9) | \ + ((b & (1 << 13)) >> 11) | \ + ((b & (1 << 14)) >> 13) | \ + b >> 15 + +/* This is for debugging the matrix rows +void printBits(uint16_t n) +{ + long i; + for (i = 15; i >= 0; i--) { + if ((n & (1 << i)) != 0) { + printf("1"); + } + else { + printf("0"); + } + } + printf("\n"); +} +*/ + +bool bit_pattern_set(uint16_t number, uint16_t bitPattern) { + return !(~number & bitPattern); +} + +void fix_ghosting_instance( + matrix_row_t current_matrix[], + unsigned short row_num_with_possible_error_cause, + uint16_t possible_error_cause, + unsigned short row_num_with_possible_error, + uint16_t possible_error, + uint16_t error_fix) { + if (bit_pattern_set(current_matrix[row_num_with_possible_error_cause], possible_error_cause)) { + if (bit_pattern_set(current_matrix[row_num_with_possible_error], possible_error)) { + current_matrix[row_num_with_possible_error] = current_matrix[row_num_with_possible_error] ^ error_fix; + } + } +} + +void fix_ghosting_column( + matrix_row_t matrix[], + uint16_t possible_error_cause, + uint16_t possible_error, + uint16_t error_fix) { + // First the right side + for (short i = 0; i<3; i++) { + fix_ghosting_instance(matrix, i, possible_error_cause, (i+1)%3, possible_error, error_fix); + fix_ghosting_instance(matrix, i, possible_error_cause, (i+2)%3, possible_error, error_fix); + } + + // Then exactly same procedure on the left side + for (short i = 0; i<3; i++) { + fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+1)%3), possible_error<<6, error_fix<<6); + fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+2)%3), possible_error<<6, error_fix<<6); + } +} + +// For QWERTY layout, key combo a+s+e also outputs q. This suppresses the q, and other similar ghosts +// These are observed ghosts(following a pattern). TODO: need to fix this for v3 +// Might need to add 2 diodes(one in each direction) for every row, to increase voltage drop. +void fix_ghosting(matrix_row_t matrix[]) { + fix_ghosting_column(matrix, + rev(0B0110000000000000), + rev(0B1010000000000000), + rev(0B0010000000000000)); + fix_ghosting_column(matrix, + rev(0B0110000000000000), + rev(0B0101000000000000), + rev(0B0100000000000000)); + + fix_ghosting_column(matrix, + rev(0B0001100000000000), + rev(0B0010100000000000), + rev(0B0000100000000000)); + fix_ghosting_column(matrix, + rev(0B0001100000000000), + rev(0B0001010000000000), + rev(0B0001000000000000)); + + fix_ghosting_column(matrix, + rev(0B1000010000000000), + rev(0B1000100000000000), + rev(0B1000000000000000)); + fix_ghosting_column(matrix, + rev(0B1000010000000000), + rev(0B0100010000000000), + rev(0B0000010000000000)); + + fix_ghosting_column(matrix, + rev(0B1001000000000000), + rev(0B0101000000000000), + rev(0B0001000000000000)); + fix_ghosting_column(matrix, + rev(0B1001000000000000), + rev(0B1010000000000000), + rev(0B1000000000000000)); + + fix_ghosting_column(matrix, + rev(0B0100100000000000), + rev(0B0100010000000000), + rev(0B0100000000000000)); + fix_ghosting_column(matrix, + rev(0B0100100000000000), + rev(0B1000100000000000), + rev(0B0000100000000000)); +} + +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; +} diff --git a/keyboards/cheapino/matrix-encoder.c b/keyboards/cheapino/matrix-encoder.c deleted file mode 100644 index 26101198c89e..000000000000 --- a/keyboards/cheapino/matrix-encoder.c +++ /dev/null @@ -1,50 +0,0 @@ -#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; -} diff --git a/keyboards/cheapino/matrix-encoder.h b/keyboards/cheapino/matrix-encoder.h deleted file mode 100644 index b32b25c59484..000000000000 --- a/keyboards/cheapino/matrix-encoder.h +++ /dev/null @@ -1,6 +0,0 @@ -// -// Created by Thomas Haukland on 25/03/2023. -// -#include "quantum.h" - -void fix_encoder_action(matrix_row_t current_matrix[]); diff --git a/keyboards/cheapino/matrix-ghosting.c b/keyboards/cheapino/matrix-ghosting.c deleted file mode 100644 index c349b0abe198..000000000000 --- a/keyboards/cheapino/matrix-ghosting.c +++ /dev/null @@ -1,128 +0,0 @@ -// -// Created by Thomas Haukland on 2024-05-05. -// - -#include "matrix.h" -#include "quantum.h" -#include "print.h" - -// This is just to be able to declare constants as they appear in the qmk console -#define rev(b) \ - ((b & 1) << 15) | \ - ((b & (1 << 1)) << 13) | \ - ((b & (1 << 2)) << 11) | \ - ((b & (1 << 3)) << 9) | \ - ((b & (1 << 4)) << 7) | \ - ((b & (1 << 5)) << 5) | \ - ((b & (1 << 6)) << 3) | \ - ((b & (1 << 7)) << 1) | \ - ((b & (1 << 8)) >> 1) | \ - ((b & (1 << 9)) >> 3) | \ - ((b & (1 << 10)) >> 5) | \ - ((b & (1 << 11)) >> 7) | \ - ((b & (1 << 12)) >> 9) | \ - ((b & (1 << 13)) >> 11) | \ - ((b & (1 << 14)) >> 13) | \ - b >> 15 - -/* This is for debugging the matrix rows -void printBits(uint16_t n) -{ - long i; - for (i = 15; i >= 0; i--) { - if ((n & (1 << i)) != 0) { - printf("1"); - } - else { - printf("0"); - } - } - printf("\n"); -} -*/ - -bool bit_pattern_set(uint16_t number, uint16_t bitPattern) { - return !(~number & bitPattern); -} - -void fix_ghosting_instance( - matrix_row_t current_matrix[], - unsigned short row_num_with_possible_error_cause, - uint16_t possible_error_cause, - unsigned short row_num_with_possible_error, - uint16_t possible_error, - uint16_t error_fix) { - if (bit_pattern_set(current_matrix[row_num_with_possible_error_cause], possible_error_cause)) { - if (bit_pattern_set(current_matrix[row_num_with_possible_error], possible_error)) { - current_matrix[row_num_with_possible_error] = current_matrix[row_num_with_possible_error] ^ error_fix; - } - } -} - -void fix_ghosting_column( - matrix_row_t matrix[], - uint16_t possible_error_cause, - uint16_t possible_error, - uint16_t error_fix) { - // First the right side - for (short i = 0; i<3; i++) { - fix_ghosting_instance(matrix, i, possible_error_cause, (i+1)%3, possible_error, error_fix); - fix_ghosting_instance(matrix, i, possible_error_cause, (i+2)%3, possible_error, error_fix); - } - - // Then exactly same procedure on the left side - for (short i = 0; i<3; i++) { - fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+1)%3), possible_error<<6, error_fix<<6); - fix_ghosting_instance(matrix, i+4, possible_error_cause<<6, 4+((i+2)%3), possible_error<<6, error_fix<<6); - } -} - -// For QWERTY layout, key combo a+s+e also outputs q. This suppresses the q, and other similar ghosts -// These are observed ghosts(following a pattern). TODO: need to fix this for v3 -// Might need to add 2 diodes(one in each direction) for every row, to increase voltage drop. -void fix_ghosting(matrix_row_t matrix[]) { - fix_ghosting_column(matrix, - rev(0B0110000000000000), - rev(0B1010000000000000), - rev(0B0010000000000000)); - fix_ghosting_column(matrix, - rev(0B0110000000000000), - rev(0B0101000000000000), - rev(0B0100000000000000)); - - fix_ghosting_column(matrix, - rev(0B0001100000000000), - rev(0B0010100000000000), - rev(0B0000100000000000)); - fix_ghosting_column(matrix, - rev(0B0001100000000000), - rev(0B0001010000000000), - rev(0B0001000000000000)); - - fix_ghosting_column(matrix, - rev(0B1000010000000000), - rev(0B1000100000000000), - rev(0B1000000000000000)); - fix_ghosting_column(matrix, - rev(0B1000010000000000), - rev(0B0100010000000000), - rev(0B0000010000000000)); - - fix_ghosting_column(matrix, - rev(0B1001000000000000), - rev(0B0101000000000000), - rev(0B0001000000000000)); - fix_ghosting_column(matrix, - rev(0B1001000000000000), - rev(0B1010000000000000), - rev(0B1000000000000000)); - - fix_ghosting_column(matrix, - rev(0B0100100000000000), - rev(0B0100010000000000), - rev(0B0100000000000000)); - fix_ghosting_column(matrix, - rev(0B0100100000000000), - rev(0B1000100000000000), - rev(0B0000100000000000)); -} diff --git a/keyboards/cheapino/matrix-ghosting.h b/keyboards/cheapino/matrix-ghosting.h deleted file mode 100644 index 1dfef2af3fde..000000000000 --- a/keyboards/cheapino/matrix-ghosting.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by Thomas Haukland on 2024-05-05. -// - -void fix_ghosting(matrix_row_t current_matrix[]); \ No newline at end of file diff --git a/keyboards/cheapino/matrix.c b/keyboards/cheapino/matrix.c index 88c18f8a2d14..9a3194827b37 100644 --- a/keyboards/cheapino/matrix.c +++ b/keyboards/cheapino/matrix.c @@ -25,8 +25,6 @@ along with this program. If not, see . #include "config.h" #include "quantum.h" #include "debounce.h" -#include "matrix-encoder.h" -#include "matrix-ghosting.h" #include "print.h" // How long the scanning code waits for changed io to settle. @@ -128,6 +126,9 @@ bool has_matrix_changed(matrix_row_t current_matrix[]) { } bool matrix_scan_custom(matrix_row_t current_matrix[]) { + extern void fix_encoder_action(matrix_row_t current_matrix[]); + extern void fix_ghosting(matrix_row_t matrix[]); + store_old_matrix(current_matrix); // Set row, read cols for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { diff --git a/keyboards/cheapino/rules.mk b/keyboards/cheapino/rules.mk index 8ca133bf1eb3..36ee49ccb093 100644 --- a/keyboards/cheapino/rules.mk +++ b/keyboards/cheapino/rules.mk @@ -1,3 +1 @@ -SRC += matrix-encoder.c -SRC += matrix-ghosting.c SRC += matrix.c From 8e9936181c4e1a6be7f5e1151bd46c7f2807a787 Mon Sep 17 00:00:00 2001 From: Jakob Linke <36006+schuay@users.noreply.github.com> Date: Wed, 4 Feb 2026 10:30:22 +0100 Subject: [PATCH 20/21] add default keymap --- keyboards/cheapino/keyboard.json | 2 +- .../cheapino/keymaps/default/keymap.json | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 keyboards/cheapino/keymaps/default/keymap.json diff --git a/keyboards/cheapino/keyboard.json b/keyboards/cheapino/keyboard.json index e7dc06f6651e..42cc2e01b4d2 100644 --- a/keyboards/cheapino/keyboard.json +++ b/keyboards/cheapino/keyboard.json @@ -1,6 +1,6 @@ { "manufacturer": "Thomas Haukland", - "keyboard_name": "cheapino2", + "keyboard_name": "cheapino", "maintainer": "tompi", "bootloader": "rp2040", "diode_direction": "ROW2COL", diff --git a/keyboards/cheapino/keymaps/default/keymap.json b/keyboards/cheapino/keymaps/default/keymap.json new file mode 100644 index 000000000000..b992102c91b1 --- /dev/null +++ b/keyboards/cheapino/keymaps/default/keymap.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "notes": "Cheapino default keymap", + "documentation": "\"This file is a QMK Configurator export. You can import this at . It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: \n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n", + "keyboard": "bastardkb/skeletyl/blackpill", + "keymap": "default", + "layout": "LAYOUT_split_3x5_3", + "layers": [ + [ + "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_NO", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P", + "KC_A", "KC_S", "KC_D", "KC_F", "KC_G", "KC_H", "KC_J", "KC_K", "KC_L", "KC_SCLN", + "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", + "KC_LGUI", "KC_SPC", "MO(1)", "MO(2)", "KC_ENT", "KC_RALT" + ], + [ + "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_NO", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_LEFT", "KC_DOWN", "KC_UP", "KC_RIGHT", "KC_NO", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", + "KC_LGUI", "KC_SPC", "KC_TRNS", "MO(3)", "KC_ENT", "KC_RALT" + ], + [ + "KC_EXLM", "KC_AT", "KC_HASH", "KC_DLR", "KC_NO", "KC_PERC", "KC_CIRC", "KC_AMPR", "KC_ASTR", "KC_LPRN", "KC_RPRN", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_MINS", "KC_EQL", "KC_LBRC", "KC_RBRC", "KC_BSLS", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_UNDS", "KC_PLUS", "KC_LCBR", "KC_RCBR", "KC_PIPE", + "KC_LGUI", "KC_SPC", "MO(3)", "KC_TRNS", "KC_ENT", "KC_RALT" + ], + [ + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", + "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", + "KC_LGUI", "KC_SPC", "KC_TRNS", "KC_TRNS", "KC_ENT", "KC_RALT"] + + ], + "author": "thomas.haukland@gmail.com" +} From 4d41e564890ab60ebebecbffb971eed934d80781 Mon Sep 17 00:00:00 2001 From: Jens Getreu Date: Sun, 8 Feb 2026 21:14:29 +0000 Subject: [PATCH 21/21] Fix keymap layout by swapping key positions I think in the 3. table, row 1 is mistake. --- keyboards/cheapino/keymaps/default/keymap.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboards/cheapino/keymaps/default/keymap.json b/keyboards/cheapino/keymaps/default/keymap.json index b992102c91b1..cb2256460272 100644 --- a/keyboards/cheapino/keymaps/default/keymap.json +++ b/keyboards/cheapino/keymaps/default/keymap.json @@ -19,7 +19,7 @@ "KC_LGUI", "KC_SPC", "KC_TRNS", "MO(3)", "KC_ENT", "KC_RALT" ], [ - "KC_EXLM", "KC_AT", "KC_HASH", "KC_DLR", "KC_NO", "KC_PERC", "KC_CIRC", "KC_AMPR", "KC_ASTR", "KC_LPRN", "KC_RPRN", + "KC_EXLM", "KC_AT", "KC_HASH", "KC_DLR", "KC_PERC", "KC_NO", "KC_CIRC", "KC_AMPR", "KC_ASTR", "KC_LPRN", "KC_RPRN", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_MINS", "KC_EQL", "KC_LBRC", "KC_RBRC", "KC_BSLS", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_NO", "KC_UNDS", "KC_PLUS", "KC_LCBR", "KC_RCBR", "KC_PIPE", "KC_LGUI", "KC_SPC", "MO(3)", "KC_TRNS", "KC_ENT", "KC_RALT"