Przeglądaj źródła

[Keyboard] Update Tractyl Manuform and add F405 (weact) variant (#24764)

Drashna Jaelre 1 rok temu
rodzic
commit
55909141ef

+ 0 - 9
keyboards/handwired/tractyl_manuform/5x6_right/config.h

@@ -21,13 +21,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define ROTATIONAL_TRANSFORM_ANGLE  -25
 #define POINTING_DEVICE_INVERT_X
 
-#define DYNAMIC_KEYMAP_LAYER_COUNT  16
-#define LAYER_STATE_16BIT
-
-
-/* disable action features */
-//#define NO_ACTION_LAYER
-//#define NO_ACTION_TAPPING
-//#define NO_ACTION_ONESHOT
-
 #define POINTING_DEVICE_RIGHT

+ 23 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/board.h

@@ -0,0 +1,23 @@
+/* Copyright 2020 Nick Brassel (tzarc)
+ *
+ *  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 3 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 <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include_next <board.h>
+
+#undef STM32_HSECLK
+#define STM32_HSECLK 8000000U
+#undef STM32_LSECLK
+#define STM32_LSECLK 32768U

+ 89 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/config.h

@@ -0,0 +1,89 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+Copyright 2015 Jack Humbert
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#define USER_BUTTON_PIN     C13
+#define DEBUG_LED_PIN       B2
+#define USB_VBUS_PIN        B10
+
+#ifdef USE_USB_OTG_HS_PORT
+#    define USB_DRIVER USBD2
+#endif
+
+// WS2812 RGB LED strip input and number of LEDs
+#define WS2812_PWM_DRIVER        PWMD3
+#define WS2812_PWM_CHANNEL       1
+#define WS2812_PWM_PAL_MODE      2
+#define WS2812_PWM_DMA_STREAM    STM32_DMA1_STREAM2
+#define WS2812_PWM_DMA_CHANNEL   5
+#define WS2812_EXTERNAL_PULLUP
+
+#define BACKLIGHT_PWM_DRIVER     PWMD8
+#define BACKLIGHT_PWM_CHANNEL    2
+#define BACKLIGHT_PAL_MODE       3
+
+/* Audio config */
+#define AUDIO_PIN               A4
+#define AUDIO_PIN_ALT           A5
+#define AUDIO_PIN_ALT_AS_NEGATIVE
+
+/* serial.c configuration for split keyboard */
+#define SERIAL_USART_DRIVER      SD1
+#define SERIAL_USART_TX_PIN      A10
+#define SERIAL_USART_TX_PAL_MODE 7
+#define SERIAL_USART_RX_PIN      A9
+#define SERIAL_USART_RX_PAL_MODE 7
+#define SERIAL_USART_TIMEOUT     10
+#define SERIAL_USART_SPEED       (1 * 1024 * 1024)
+#define SERIAL_USART_FULL_DUPLEX
+
+
+/* i2c config for oleds */
+#define I2C_DRIVER        I2CD1
+#define I2C1_CLOCK_SPEED  400000
+#define I2C1_DUTY_CYCLE   FAST_DUTY_CYCLE_16_9
+
+/* spi config for eeprom and pmw3360 sensor */
+#define SPI_DRIVER        SPID1
+#define SPI_SCK_PIN       B3
+#define SPI_SCK_PAL_MODE  5
+#define SPI_MOSI_PIN      B5
+#define SPI_MOSI_PAL_MODE 5
+#define SPI_MISO_PIN      B4
+#define SPI_MISO_PAL_MODE 5
+
+#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN B13
+#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR    4
+#define EXTERNAL_FLASH_SIZE                 (8 * 1024 * 1024)
+
+/* pmw3360 config  */
+#define POINTING_DEVICE_CS_PIN B8
+#define POINTING_DEVICE_ROTATION_270
+#undef ROTATIONAL_TRANSFORM_ANGLE
+#define PMW33XX_SPI_DIVISOR 16
+
+// lcd
+#define DISPLAY_RST_PIN NO_PIN
+#define DISPLAY_DC_PIN B12
+#define DISPLAY_CS_PIN B9
+#define DISPLAY_SPI_DIVIDER 1
+
+#define DRV2605L_FB_ERM_LRA   0
+#define DRV2605L_GREETING     DRV2605L_EFFECT_750_MS_ALERT_100
+#define DRV2605L_DEFAULT_MODE DRV2605L_EFFECT_BUZZ_1_100

+ 52 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/f405.c

@@ -0,0 +1,52 @@
+/* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "tractyl_manuform.h"
+
+#ifdef USB_VBUS_PIN
+bool usb_vbus_state(void) {
+    gpio_set_pin_input_low(USB_VBUS_PIN);
+    wait_us(5);
+    return gpio_read_pin(USB_VBUS_PIN);
+}
+#endif
+
+#ifdef USER_BUTTON_PIN
+void user_button_init(void) {
+    // Pin needs to be configured as input low
+    gpio_set_pin_input_low(USER_BUTTON_PIN);
+}
+
+bool check_user_button_state(void) {
+    return gpio_read_pin(USER_BUTTON_PIN);
+}
+#endif // USER_BUTTON_PIN
+
+void board_init(void) {
+    // Board setup sets these pins as SPI, but we aren't using them as such.
+    // So to prevent them from misbehaving, we need to set them to a different, non-spi mode.
+    // This is a bit of a hack, but nothing else runs soon enough, without re-implementing spi_init().
+    gpio_set_pin_input(A5);
+    gpio_set_pin_input(A6);
+    gpio_set_pin_input(A7);
+
+    // If using USB_OTG_HS, we need to set the data pins since they're set wrong for our needs by default.
+    // We set it here by default, in case it's bridged with A11/A12, as to reduce the chance of issues.
+    palSetLineMode(
+        B14, PAL_MODE_ALTERNATE(12) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING);
+    palSetLineMode(
+        B15, PAL_MODE_ALTERNATE(12) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING);
+}

+ 35 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/halconf.h

@@ -0,0 +1,35 @@
+/* Copyright 2020 Nick Brassel (tzarc)
+ *
+ *  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 3 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 <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#define HAL_USE_SERIAL  TRUE
+#define SERIAL_BUFFERS_SIZE 256
+
+#if defined(WS2812_PWM) || defined(BACKLIGHT_PWM)
+#    define HAL_USE_PWM TRUE
+#endif // defined(WS2812_PWM) || defined(BACKLIGHT_PWM)
+
+#if HAL_USE_SPI == TRUE
+#    define SPI_USE_WAIT TRUE
+#    define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+#ifdef AUDIO_DRIVER_DAC
+#    define HAL_USE_GPT TRUE
+#    define HAL_USE_DAC TRUE
+#endif
+
+#include_next <halconf.h>

+ 66 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/keyboard.json

@@ -0,0 +1,66 @@
+{
+    "keyboard_name": "Tractyl Manuform (5x6) WeAct STM32F405",
+    "audio": {
+        "driver": "dac_additive",
+        "power_control": {
+            "pin": "A3"
+        }
+    },
+    "backlight": {
+        "levels": 16,
+        "pin": "C7"
+    },
+    "bootloader": "stm32-dfu",
+    "build": {
+        "debounce_type": "asym_eager_defer_pk"
+    },
+    "diode_direction": "COL2ROW",
+    "encoder": {
+        "rotary": [
+            {"pin_a": "C0", "pin_b": "A15"}
+        ]
+    },
+    "eeprom": {
+        "driver": "wear_leveling",
+        "wear_leveling": {
+            "driver": "spi_flash",
+            "backing_size": 16384,
+            "logical_size": 4096
+        }
+    },
+    "features": {
+        "console": true,
+        "haptic": true
+    },
+    "haptic": {
+        "driver": "drv2605l"
+    },
+    "matrix_pins": {
+        "cols": ["C1", "C2", "C3", "A0", "A1", "A2"],
+        "rows": ["A6", "A7", "C4", "C5", "B0", "B1"]
+    },
+    "processor": "STM32F405",
+    "rgblight": {
+        "led_count": 24,
+        "split": true
+    },
+    "split": {
+        "handedness": {
+            "pin": "B11"
+        },
+        "serial": {
+            "driver": "usart"
+        },
+        "transport": {
+            "sync": {
+                "activity": true,
+                "haptic": true,
+                "matrix_state": true
+            }
+        }
+    },
+    "ws2812": {
+        "driver": "pwm",
+        "pin": "C6"
+    }
+}

+ 82 - 0
keyboards/handwired/tractyl_manuform/5x6_right/f405/mcuconf.h

@@ -0,0 +1,82 @@
+/* Copyright 2020 Nick Brassel (tzarc)
+ *
+ *  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 3 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 <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include_next <mcuconf.h>
+
+#undef STM32_LSE_ENABLED
+#define STM32_LSE_ENABLED TRUE
+
+#undef STM32_PLLM_VALUE
+#define STM32_PLLM_VALUE 8
+
+#undef STM32_RTCSEL
+#define STM32_RTCSEL STM32_RTCSEL_LSE
+
+#undef STM32_SERIAL_USE_USART1
+#define STM32_SERIAL_USE_USART1 TRUE
+
+#if HAL_USE_WDG == TRUE
+#    undef STM32_WDG_USE_IWDG
+#    define STM32_WDG_USE_IWDG TRUE
+#endif
+
+#if HAL_USE_I2C == TRUE
+#    undef STM32_I2C_USE_I2C1
+#    define STM32_I2C_USE_I2C1 TRUE
+
+#    undef STM32_I2C_BUSY_TIMEOUT
+#    define STM32_I2C_BUSY_TIMEOUT 10
+
+#    undef STM32_I2C_I2C1_RX_DMA_STREAM
+#    define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#    undef STM32_I2C_I2C1_TX_DMA_STREAM
+#    define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#endif // HAL_USE_I2C
+
+#ifdef WS2812_PWM
+#    undef STM32_PWM_USE_TIM3
+#    define STM32_PWM_USE_TIM3 TRUE
+#endif // WS2812_PWM
+
+#ifdef BACKLIGHT_PWM
+#    undef STM32_PWM_USE_TIM8
+#    define STM32_PWM_USE_TIM8 TRUE
+#endif
+
+#if HAL_USE_SPI == TRUE
+#    undef STM32_SPI_USE_SPI1
+#    define STM32_SPI_USE_SPI1 TRUE
+#endif
+
+#ifdef AUDIO_DRIVER_DAC
+#    undef STM32_DAC_USE_DAC1_CH1
+#    define STM32_DAC_USE_DAC1_CH1 TRUE
+#    undef STM32_DAC_USE_DAC1_CH2
+#    define STM32_DAC_USE_DAC1_CH2 TRUE
+
+#    undef STM32_GPT_USE_TIM6
+#    define STM32_GPT_USE_TIM6 TRUE
+#endif // AUDIO_DRIVER_DAC
+
+
+#ifdef USE_USB_OTG_HS_PORT
+#    undef STM32_USB_USE_OTG1
+#    define STM32_USB_USE_OTG1 FALSE
+#    undef STM32_USB_USE_OTG2
+#    define STM32_USB_USE_OTG2 TRUE
+#endif

+ 3 - 1
keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h

@@ -19,6 +19,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #pragma once
 
 // #define USB_VBUS_PIN        B10 // doesn't seem to work for me on one of my controllers... */
+#define USER_BUTTON_PIN     A0
 
 // WS2812 RGB LED strip input and number of LEDs
 #define WS2812_PWM_DRIVER   PWMD2  // default: PWMD2
@@ -70,7 +71,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 /* eeprom config */
 #define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN A4
-#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR    64
+#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR    8
 
 /* pmw3360 config  */
 #define PMW33XX_CS_PIN                       B0
+#define PMW33XX_SPI_DIVISOR                  8

+ 0 - 41
keyboards/handwired/tractyl_manuform/5x6_right/f411/f411.c

@@ -16,41 +16,6 @@
 
 #include "tractyl_manuform.h"
 
-void keyboard_pre_init_sub(void) { gpio_set_pin_input_high(A0); }
-
-void matrix_scan_sub_kb(void) {
-    if (!gpio_read_pin(A0)) {
-        reset_keyboard();
-    }
-}
-
-__attribute__((weak)) void bootmagic_scan(void) {
-    // We need multiple scans because debouncing can't be turned off.
-    matrix_scan();
-#if defined(DEBOUNCE) && DEBOUNCE > 0
-    wait_ms(DEBOUNCE * 2);
-#else
-    wait_ms(30);
-#endif
-    matrix_scan();
-
-    uint8_t row = BOOTMAGIC_ROW;
-    uint8_t col = BOOTMAGIC_COLUMN;
-
-#if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_ROW_RIGHT) && defined(BOOTMAGIC_COLUMN_RIGHT)
-    if (!is_keyboard_left()) {
-        row = BOOTMAGIC_ROW_RIGHT;
-        col = BOOTMAGIC_COLUMN_RIGHT;
-    }
-#endif
-
-    if (matrix_get_row(row) & (1 << col) || !gpio_read_pin(A0)) {
-        eeconfig_disable();
-        bootloader_jump();
-    }
-}
-
-
 #ifdef USB_VBUS_PIN
 bool usb_vbus_state(void) {
     gpio_set_pin_input_low(USB_VBUS_PIN);
@@ -58,9 +23,3 @@ bool usb_vbus_state(void) {
     return gpio_read_pin(USB_VBUS_PIN);
 }
 #endif
-
-void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
-    for (int32_t i = 0; i < 40; i++) {
-        __asm__ volatile("nop" ::: "memory");
-    }
-}

+ 0 - 2
keyboards/handwired/tractyl_manuform/5x6_right/f411/rules.mk

@@ -1,2 +0,0 @@
-KEYBOARD_SHARED_EP = yes
-MOUSE_SHARED_EP    = yes

+ 203 - 0
keyboards/handwired/tractyl_manuform/5x6_right/info.json

@@ -95,9 +95,212 @@
                 {"matrix": [5, 2], "x": 6, "y": 7},
                 {"matrix": [5, 3], "x": 7, "y": 7},
 
+                {"matrix": [11, 2], "x": 9, "y": 7},
+                {"matrix": [11, 3], "x": 10, "y": 7}
+            ]
+        },
+        "LAYOUT_5x6_full_right": {
+            "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": [6, 0], "x": 11, "y": 0},
+                {"matrix": [6, 1], "x": 12, "y": 0},
+                {"matrix": [6, 2], "x": 13, "y": 0},
+                {"matrix": [6, 3], "x": 14, "y": 0},
+                {"matrix": [6, 4], "x": 15, "y": 0},
+                {"matrix": [6, 5], "x": 16, "y": 0},
+
+                {"matrix": [1, 0], "x": 0, "y": 1},
+                {"matrix": [1, 1], "x": 1, "y": 1},
+                {"matrix": [1, 2], "x": 2, "y": 1},
+                {"matrix": [1, 3], "x": 3, "y": 1},
+                {"matrix": [1, 4], "x": 4, "y": 1},
+                {"matrix": [1, 5], "x": 5, "y": 1},
+
+                {"matrix": [7, 0], "x": 11, "y": 1},
+                {"matrix": [7, 1], "x": 12, "y": 1},
+                {"matrix": [7, 2], "x": 13, "y": 1},
+                {"matrix": [7, 3], "x": 14, "y": 1},
+                {"matrix": [7, 4], "x": 15, "y": 1},
+                {"matrix": [7, 5], "x": 16, "y": 1},
+
+                {"matrix": [2, 0], "x": 0, "y": 2},
+                {"matrix": [2, 1], "x": 1, "y": 2},
+                {"matrix": [2, 2], "x": 2, "y": 2},
+                {"matrix": [2, 3], "x": 3, "y": 2},
+                {"matrix": [2, 4], "x": 4, "y": 2},
+                {"matrix": [2, 5], "x": 5, "y": 2},
+
+                {"matrix": [8, 0], "x": 11, "y": 2},
+                {"matrix": [8, 1], "x": 12, "y": 2},
+                {"matrix": [8, 2], "x": 13, "y": 2},
+                {"matrix": [8, 3], "x": 14, "y": 2},
+                {"matrix": [8, 4], "x": 15, "y": 2},
+                {"matrix": [8, 5], "x": 16, "y": 2},
+
+                {"matrix": [3, 0], "x": 0, "y": 3},
+                {"matrix": [3, 1], "x": 1, "y": 3},
+                {"matrix": [3, 2], "x": 2, "y": 3},
+                {"matrix": [3, 3], "x": 3, "y": 3},
+                {"matrix": [3, 4], "x": 4, "y": 3},
+                {"matrix": [3, 5], "x": 5, "y": 3},
+
+                {"matrix": [9, 0], "x": 11, "y": 3},
+                {"matrix": [9, 1], "x": 12, "y": 3},
+                {"matrix": [9, 2], "x": 13, "y": 3},
+                {"matrix": [9, 3], "x": 14, "y": 3},
+                {"matrix": [9, 4], "x": 15, "y": 3},
+                {"matrix": [9, 5], "x": 16, "y": 3},
+
+                {"matrix": [4, 0], "x": 0, "y": 4},
+                {"matrix": [4, 1], "x": 1, "y": 4},
+                {"matrix": [4, 2], "x": 2, "y": 4},
+                {"matrix": [4, 3], "x": 3, "y": 4},
+
+                {"matrix": [10, 2], "x": 13, "y": 4},
+                {"matrix": [10, 3], "x": 14, "y": 4},
+                {"matrix": [10, 4], "x": 15, "y": 4},
+                {"matrix": [10, 5], "x": 16, "y": 4},
+
+                {"matrix": [4, 4], "x": 4, "y": 5},
+                {"matrix": [4, 5], "x": 5, "y": 5},
+
+                {"matrix": [10, 1], "x": 12, "y": 5},
+
+                {"matrix": [5, 4], "x": 6, "y": 6},
+                {"matrix": [5, 5], "x": 7, "y": 6},
+
+                {"matrix": [11, 1], "x": 10, "y": 6},
+
+                {"matrix": [5, 2], "x": 6, "y": 7},
+                {"matrix": [5, 3], "x": 7, "y": 7},
+
                 {"matrix": [11, 2], "x": 9, "y": 7},
                 {"matrix": [11, 3], "x": 10, "y": 7}
             ]
         }
+    },
+    "rgb_matrix": {
+        "animations": {
+            "alphas_mods": true,
+            "gradient_up_down": true,
+            "gradient_left_right": true,
+            "breathing": true,
+            "band_sat": true,
+            "band_val": true,
+            "band_pinwheel_sat": true,
+            "band_pinwheel_val": true,
+            "band_spiral_sat": true,
+            "band_spiral_val": true,
+            "cycle_all": true,
+            "cycle_left_right": true,
+            "cycle_up_down": true,
+            "rainbow_moving_chevron": true,
+            "cycle_out_in": true,
+            "cycle_out_in_dual": true,
+            "cycle_pinwheel": true,
+            "cycle_spiral": true,
+            "dual_beacon": true,
+            "rainbow_beacon": true,
+            "rainbow_pinwheels": true,
+            "raindrops": true,
+            "jellybean_raindrops": true,
+            "hue_breathing": true,
+            "hue_pendulum": true,
+            "hue_wave": true,
+            "pixel_rain": true,
+            "pixel_flow": true,
+            "pixel_fractal": true,
+            "typing_heatmap": true,
+            "digital_rain": true,
+            "solid_reactive_simple": true,
+            "solid_reactive": true,
+            "solid_reactive_wide": true,
+            "solid_reactive_multiwide": true,
+            "solid_reactive_cross": true,
+            "solid_reactive_multicross": true,
+            "solid_reactive_nexus": true,
+            "solid_reactive_multinexus": true,
+            "splash": true,
+            "multisplash": true,
+            "solid_splash": true,
+            "solid_multisplash": true
+        },
+        "driver": "ws2812",
+        "led_count": 64,
+        "max_brightness": 100,
+        "split_count": [33, 31],
+        "sleep": true,
+        "layout": [
+            {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1},
+            {"matrix": [1, 0], "x": 0, "y": 10, "flags": 1},
+            {"matrix": [2, 0], "x": 0, "y": 20, "flags": 1},
+            {"matrix": [3, 0], "x": 0, "y": 30, "flags": 1},
+            {"matrix": [3, 1], "x": 12, "y": 30, "flags": 4},
+            {"matrix": [2, 1], "x": 12, "y": 20, "flags": 4},
+            {"matrix": [1, 1], "x": 12, "y": 10, "flags": 4},
+            {"matrix": [0, 1], "x": 12, "y": 0, "flags": 4},
+            {"matrix": [0, 2], "x": 24, "y": 0, "flags": 4},
+            {"matrix": [1, 2], "x": 24, "y": 10, "flags": 4},
+            {"matrix": [2, 2], "x": 24, "y": 20, "flags": 4},
+            {"matrix": [3, 2], "x": 24, "y": 30, "flags": 4},
+            {"matrix": [4, 2], "x": 24, "y": 40, "flags": 1},
+            {"matrix": [4, 3], "x": 36, "y": 40, "flags": 1},
+            {"matrix": [3, 3], "x": 36, "y": 30, "flags": 4},
+            {"matrix": [2, 3], "x": 36, "y": 20, "flags": 4},
+            {"matrix": [1, 3], "x": 36, "y": 10, "flags": 4},
+            {"matrix": [0, 3], "x": 36, "y": 0, "flags": 4},
+            {"matrix": [0, 4], "x": 48, "y": 0, "flags": 4},
+            {"matrix": [1, 4], "x": 48, "y": 10, "flags": 4},
+            {"matrix": [2, 4], "x": 48, "y": 40, "flags": 4},
+            {"matrix": [3, 4], "x": 48, "y": 30, "flags": 4},
+            {"matrix": [3, 5], "x": 60, "y": 30, "flags": 4},
+            {"matrix": [2, 5], "x": 60, "y": 20, "flags": 4},
+            {"matrix": [1, 5], "x": 60, "y": 10, "flags": 4},
+            {"matrix": [0, 5], "x": 60, "y": 0, "flags": 4},
+            {"matrix": [4, 4], "x": 48, "y": 50, "flags": 1},
+            {"matrix": [5, 4], "x": 65, "y": 56, "flags": 1},
+            {"matrix": [5, 5], "x": 70, "y": 60, "flags": 1},
+            {"matrix": [5, 3], "x": 65, "y": 64, "flags": 1},
+            {"matrix": [5, 2], "x": 60, "y": 60, "flags": 1},
+            {"matrix": [4, 1], "x": 0, "y": 40, "flags": 1},
+            {"matrix": [4, 0], "x": 12, "y": 40, "flags": 1},
+            {"matrix": [6, 5], "x": 224, "y": 0, "flags": 1},
+            {"matrix": [7, 5], "x": 224, "y": 10, "flags": 1},
+            {"matrix": [8, 5], "x": 224, "y": 20, "flags": 1},
+            {"matrix": [9, 5], "x": 224, "y": 30, "flags": 1},
+            {"matrix": [9, 4], "x": 212, "y": 30, "flags": 4},
+            {"matrix": [8, 4], "x": 212, "y": 20, "flags": 4},
+            {"matrix": [7, 4], "x": 212, "y": 10, "flags": 4},
+            {"matrix": [6, 4], "x": 212, "y": 0, "flags": 4},
+            {"matrix": [6, 3], "x": 200, "y": 0, "flags": 4},
+            {"matrix": [7, 3], "x": 200, "y": 10, "flags": 4},
+            {"matrix": [8, 3], "x": 200, "y": 20, "flags": 4},
+            {"matrix": [9, 3], "x": 200, "y": 30, "flags": 4},
+            {"matrix": [10, 3], "x": 200, "y": 40, "flags": 1},
+            {"matrix": [10, 2], "x": 188, "y": 40, "flags": 1},
+            {"matrix": [9, 2], "x": 188, "y": 30, "flags": 4},
+            {"matrix": [8, 2], "x": 188, "y": 20, "flags": 4},
+            {"matrix": [7, 2], "x": 188, "y": 10, "flags": 4},
+            {"matrix": [6, 2], "x": 188, "y": 0, "flags": 4},
+            {"matrix": [6, 1], "x": 176, "y": 0, "flags": 4},
+            {"matrix": [7, 1], "x": 176, "y": 10, "flags": 4},
+            {"matrix": [8, 1], "x": 176, "y": 20, "flags": 4},
+            {"matrix": [9, 1], "x": 176, "y": 30, "flags": 4},
+            {"matrix": [9, 0], "x": 164, "y": 30, "flags": 4},
+            {"matrix": [8, 0], "x": 164, "y": 20, "flags": 4},
+            {"matrix": [7, 0], "x": 164, "y": 10, "flags": 4},
+            {"matrix": [6, 0], "x": 164, "y": 0, "flags": 4},
+            {"matrix": [11, 1], "x": 164, "y": 60, "flags": 1},
+            {"matrix": [11, 3], "x": 152, "y": 70, "flags": 1},
+            {"matrix": [11, 2], "x": 140, "y": 70, "flags": 1},
+            {"matrix": [10, 4], "x": 224, "y": 40, "flags": 1},
+            {"matrix": [10, 5], "x": 208, "y": 40, "flags": 1}
+        ]
     }
 }

+ 1 - 0
keyboards/handwired/tractyl_manuform/5x6_right/post_rules.mk

@@ -0,0 +1 @@
+POINTING_DEVICE_DRIVER = pmw3360

+ 0 - 4
keyboards/handwired/tractyl_manuform/5x6_right/rules.mk

@@ -1,4 +0,0 @@
-POINTING_DEVICE_DRIVER = pmw3360
-MOUSE_SHARED_EP = yes
-
-DEFAULT_FOLDER = handwired/tractyl_manuform/5x6_right/teensy2pp

+ 0 - 12
keyboards/handwired/tractyl_manuform/config.h

@@ -18,18 +18,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #pragma once
 
-
-/* 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 SPLIT_POINTING_ENABLE
 #define POINTING_DEVICE_TASK_THROTTLE_MS 1
 

+ 5 - 1
keyboards/handwired/tractyl_manuform/info.json

@@ -2,6 +2,10 @@
     "manufacturer": "QMK Community",
     "maintainer": "Drashna Jael're",
     "usb": {
-        "vid": "0x44DD"
+        "vid": "0x44DD",
+        "shared_endpoint": {
+            "keyboard": true,
+            "mouse": true
+        }
     }
 }

+ 0 - 112
keyboards/handwired/tractyl_manuform/post_config.h

@@ -1,112 +0,0 @@
-/*
-Copyright 2012 Jun Wako <wakojun@gmail.com>
-Copyright 2015 Jack Humbert
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-// mouse config
-#ifdef MOUSEKEY_ENABLE
-#    ifndef MOUSEKEY_MOVE_DELTA
-#        ifndef MK_KINETIC_SPEED
-#            define MOUSEKEY_MOVE_DELTA 5
-#        else
-#            define MOUSEKEY_MOVE_DELTA 25
-#        endif
-#    endif
-#    ifndef MOUSEKEY_DELAY
-#        ifndef MK_KINETIC_SPEED
-#            define MOUSEKEY_DELAY 300
-#        else
-#            define MOUSEKEY_DELAY 8
-#        endif
-#    endif
-#    ifndef MOUSEKEY_INTERVAL
-#        ifndef MK_KINETIC_SPEED
-#            define MOUSEKEY_INTERVAL 50
-#        else
-#            define MOUSEKEY_INTERVAL 20
-#        endif
-#    endif
-#    ifndef MOUSEKEY_MAX_SPEED
-#        define MOUSEKEY_MAX_SPEED 7
-#    endif
-#    ifndef MOUSEKEY_TIME_TO_MAX
-#        define MOUSEKEY_TIME_TO_MAX 60
-#    endif
-#    ifndef MOUSEKEY_INITIAL_SPEED
-#        define MOUSEKEY_INITIAL_SPEED 100
-#    endif
-#    ifndef MOUSEKEY_BASE_SPEED
-#        define MOUSEKEY_BASE_SPEED 1000
-#    endif
-#    ifndef MOUSEKEY_DECELERATED_SPEED
-#        define MOUSEKEY_DECELERATED_SPEED 400
-#    endif
-#    ifndef MOUSEKEY_ACCELERATED_SPEED
-#        define MOUSEKEY_ACCELERATED_SPEED 3000
-#    endif
-
-// mouse scroll config
-#    ifndef MOUSEKEY_WHEEL_DELAY
-#        define MOUSEKEY_WHEEL_DELAY 15
-#    endif
-#    ifndef MOUSEKEY_WHEEL_DELTA
-#        define MOUSEKEY_WHEEL_DELTA 1
-#    endif
-#    ifndef MOUSEKEY_WHEEL_INTERVAL
-#        define MOUSEKEY_WHEEL_INTERVAL 50
-#    endif
-#    ifndef MOUSEKEY_WHEEL_MAX_SPEED
-#        define MOUSEKEY_WHEEL_MAX_SPEED 8
-#    endif
-#    ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
-#        define MOUSEKEY_WHEEL_TIME_TO_MAX 80
-#    endif
-
-#    ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
-#        define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 8
-#    endif
-#    ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
-#        define MOUSEKEY_WHEEL_BASE_MOVEMENTS 48
-#    endif
-#    ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
-#        define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
-#    endif
-#    ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
-#        define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
-#    endif
-#endif
-
-#ifndef DEBOUNCE
-#    define DEBOUNCE 5
-#endif
-
-#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_LIMIT_VAL)
-#    if defined(OLED_ENABLE)
-#        define RGBLIGHT_LIMIT_VAL 100
-#    else
-#        define RGBLIGHT_LIMIT_VAL 150
-#    endif
-#endif
-
-#if !defined(OLED_BRIGHTNESS)
-#    if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
-#        define OLED_BRIGHTNESS 80
-#    else
-#        define OLED_BRIGHTNESS 150
-#    endif
-#endif

+ 150 - 81
keyboards/handwired/tractyl_manuform/tractyl_manuform.c

@@ -15,48 +15,47 @@
  */
 
 #include "tractyl_manuform.h"
+#ifdef POINTING_DEVICE_ENABLE
+#    include "pointing_device.h"
+#endif
 #include "transactions.h"
 #include <string.h>
 
 #ifdef CONSOLE_ENABLE
 #    include "print.h"
-#endif  // CONSOLE_ENABLE
+#endif // CONSOLE_ENABLE
 
 #ifdef POINTING_DEVICE_ENABLE
 #    ifndef CHARYBDIS_MINIMUM_DEFAULT_DPI
 #        define CHARYBDIS_MINIMUM_DEFAULT_DPI 400
-#    endif  // CHARYBDIS_MINIMUM_DEFAULT_DPI
+#    endif // CHARYBDIS_MINIMUM_DEFAULT_DPI
 
 #    ifndef CHARYBDIS_DEFAULT_DPI_CONFIG_STEP
 #        define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 200
-#    endif  // CHARYBDIS_DEFAULT_DPI_CONFIG_STEP
+#    endif // CHARYBDIS_DEFAULT_DPI_CONFIG_STEP
 
 #    ifndef CHARYBDIS_MINIMUM_SNIPING_DPI
 #        define CHARYBDIS_MINIMUM_SNIPING_DPI 200
-#    endif  // CHARYBDIS_MINIMUM_SNIPER_MODE_DPI
+#    endif // CHARYBDIS_MINIMUM_SNIPER_MODE_DPI
 
 #    ifndef CHARYBDIS_SNIPING_DPI_CONFIG_STEP
 #        define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 100
-#    endif  // CHARYBDIS_SNIPING_DPI_CONFIG_STEP
+#    endif // CHARYBDIS_SNIPING_DPI_CONFIG_STEP
 
 // Fixed DPI for drag-scroll.
 #    ifndef CHARYBDIS_DRAGSCROLL_DPI
 #        define CHARYBDIS_DRAGSCROLL_DPI 100
-#    endif  // CHARYBDIS_DRAGSCROLL_DPI
+#    endif // CHARYBDIS_DRAGSCROLL_DPI
 
 #    ifndef CHARYBDIS_DRAGSCROLL_BUFFER_SIZE
 #        define CHARYBDIS_DRAGSCROLL_BUFFER_SIZE 6
-#    endif  // !CHARYBDIS_DRAGSCROLL_BUFFER_SIZE
-
-#    ifndef CHARYBDIS_POINTER_ACCELERATION_FACTOR
-#        define CHARYBDIS_POINTER_ACCELERATION_FACTOR 24
-#    endif  // !CHARYBDIS_POINTER_ACCELERATION_FACTOR
+#    endif // !CHARYBDIS_DRAGSCROLL_BUFFER_SIZE
 
 typedef union {
     uint8_t raw;
     struct {
-        uint8_t pointer_default_dpi : 4;  // 16 steps available.
-        uint8_t pointer_sniping_dpi : 2;  // 4 steps available.
+        uint8_t pointer_default_dpi : 4; // 16 steps available.
+        uint8_t pointer_sniping_dpi : 2; // 4 steps available.
         bool    is_dragscroll_enabled : 1;
         bool    is_sniping_enabled : 1;
     } __attribute__((packed));
@@ -86,13 +85,19 @@ static void read_charybdis_config_from_eeprom(charybdis_config_t* config) {
  * resets these 2 values to `false` since it does not make sense to persist
  * these across reboots of the board.
  */
-static void write_charybdis_config_to_eeprom(charybdis_config_t* config) { eeconfig_update_kb(config->raw); }
+static void write_charybdis_config_to_eeprom(charybdis_config_t* config) {
+    eeconfig_update_kb(config->raw);
+}
 
 /** \brief Return the current value of the pointer's default DPI. */
-static uint16_t get_pointer_default_dpi(charybdis_config_t* config) { return (uint16_t)config->pointer_default_dpi * CHARYBDIS_DEFAULT_DPI_CONFIG_STEP + CHARYBDIS_MINIMUM_DEFAULT_DPI; }
+static uint16_t get_pointer_default_dpi(charybdis_config_t* config) {
+    return (uint16_t)config->pointer_default_dpi * CHARYBDIS_DEFAULT_DPI_CONFIG_STEP + CHARYBDIS_MINIMUM_DEFAULT_DPI;
+}
 
 /** \brief Return the current value of the pointer's sniper-mode DPI. */
-static uint16_t get_pointer_sniping_dpi(charybdis_config_t* config) { return (uint16_t)config->pointer_sniping_dpi * CHARYBDIS_SNIPING_DPI_CONFIG_STEP + CHARYBDIS_MINIMUM_SNIPING_DPI; }
+static uint16_t get_pointer_sniping_dpi(charybdis_config_t* config) {
+    return (uint16_t)config->pointer_sniping_dpi * CHARYBDIS_SNIPING_DPI_CONFIG_STEP + CHARYBDIS_MINIMUM_SNIPING_DPI;
+}
 
 /** \brief Set the appropriate DPI for the input config. */
 static void maybe_update_pointing_device_cpi(charybdis_config_t* config) {
@@ -127,64 +132,54 @@ static void step_pointer_sniping_dpi(charybdis_config_t* config, bool forward) {
     maybe_update_pointing_device_cpi(config);
 }
 
-uint16_t charybdis_get_pointer_default_dpi(void) { return get_pointer_default_dpi(&g_charybdis_config); }
+uint16_t charybdis_get_pointer_default_dpi(void) {
+    return get_pointer_default_dpi(&g_charybdis_config);
+}
 
-uint16_t charybdis_get_pointer_sniping_dpi(void) { return get_pointer_sniping_dpi(&g_charybdis_config); }
+uint16_t charybdis_get_pointer_sniping_dpi(void) {
+    return get_pointer_sniping_dpi(&g_charybdis_config);
+}
 
-void charybdis_cycle_pointer_default_dpi_noeeprom(bool forward) { step_pointer_default_dpi(&g_charybdis_config, forward); }
+void charybdis_cycle_pointer_default_dpi_noeeprom(bool forward) {
+    step_pointer_default_dpi(&g_charybdis_config, forward);
+}
 
 void charybdis_cycle_pointer_default_dpi(bool forward) {
     step_pointer_default_dpi(&g_charybdis_config, forward);
     write_charybdis_config_to_eeprom(&g_charybdis_config);
 }
 
-void charybdis_cycle_pointer_sniping_dpi_noeeprom(bool forward) { step_pointer_sniping_dpi(&g_charybdis_config, forward); }
+void charybdis_cycle_pointer_sniping_dpi_noeeprom(bool forward) {
+    step_pointer_sniping_dpi(&g_charybdis_config, forward);
+}
 
 void charybdis_cycle_pointer_sniping_dpi(bool forward) {
     step_pointer_sniping_dpi(&g_charybdis_config, forward);
     write_charybdis_config_to_eeprom(&g_charybdis_config);
 }
 
-bool charybdis_get_pointer_sniping_enabled(void) { return g_charybdis_config.is_sniping_enabled; }
+bool charybdis_get_pointer_sniping_enabled(void) {
+    return g_charybdis_config.is_sniping_enabled;
+}
 
 void charybdis_set_pointer_sniping_enabled(bool enable) {
     g_charybdis_config.is_sniping_enabled = enable;
     maybe_update_pointing_device_cpi(&g_charybdis_config);
 }
 
-bool charybdis_get_pointer_dragscroll_enabled(void) { return g_charybdis_config.is_dragscroll_enabled; }
+bool charybdis_get_pointer_dragscroll_enabled(void) {
+    return g_charybdis_config.is_dragscroll_enabled;
+}
 
 void charybdis_set_pointer_dragscroll_enabled(bool enable) {
     g_charybdis_config.is_dragscroll_enabled = enable;
     maybe_update_pointing_device_cpi(&g_charybdis_config);
 }
 
-#    ifndef CONSTRAIN_HID
-#        define CONSTRAIN_HID(value) ((value) < XY_REPORT_MIN ? XY_REPORT_MIN : ((value) > XY_REPORT_MAX ? XY_REPORT_MAX : (value)))
-#    endif  // !CONSTRAIN_HID
-
-/**
- * \brief Add optional acceleration effect.
- *
- * If `CHARYBDIS_ENABLE_POINTER_ACCELERATION` is defined, add a simple and naive
- * acceleration effect to the provided value.  Return the value unchanged
- * otherwise.
- */
-#    ifndef DISPLACEMENT_WITH_ACCELERATION
-#        ifdef CHARYBDIS_POINTER_ACCELERATION_ENABLE
-#            define DISPLACEMENT_WITH_ACCELERATION(d) (CONSTRAIN_HID(d > 0 ? d * d / CHARYBDIS_POINTER_ACCELERATION_FACTOR + d : -d * d / CHARYBDIS_POINTER_ACCELERATION_FACTOR + d))
-#        else  // !CHARYBDIS_POINTER_ACCELERATION_ENABLE
-#            define DISPLACEMENT_WITH_ACCELERATION(d) (d)
-#        endif  // CHARYBDIS_POINTER_ACCELERATION_ENABLE
-#    endif      // !DISPLACEMENT_WITH_ACCELERATION
-
 /**
  * \brief Augment the pointing device behavior.
  *
- * Implement the Charybdis-specific features for pointing devices:
- *   - Drag-scroll
- *   - Sniping
- *   - Acceleration
+ * Implement drag-scroll.
  */
 static void pointing_device_task_charybdis(report_mouse_t* mouse_report) {
     static int16_t scroll_buffer_x = 0;
@@ -194,12 +189,12 @@ static void pointing_device_task_charybdis(report_mouse_t* mouse_report) {
         scroll_buffer_x -= mouse_report->x;
 #    else
         scroll_buffer_x += mouse_report->x;
-#    endif  // CHARYBDIS_DRAGSCROLL_REVERSE_X
+#    endif // CHARYBDIS_DRAGSCROLL_REVERSE_X
 #    ifdef CHARYBDIS_DRAGSCROLL_REVERSE_Y
         scroll_buffer_y -= mouse_report->y;
 #    else
         scroll_buffer_y += mouse_report->y;
-#    endif  // CHARYBDIS_DRAGSCROLL_REVERSE_Y
+#    endif // CHARYBDIS_DRAGSCROLL_REVERSE_Y
         mouse_report->x = 0;
         mouse_report->y = 0;
         if (abs(scroll_buffer_x) > CHARYBDIS_DRAGSCROLL_BUFFER_SIZE) {
@@ -210,16 +205,14 @@ static void pointing_device_task_charybdis(report_mouse_t* mouse_report) {
             mouse_report->v = scroll_buffer_y > 0 ? 1 : -1;
             scroll_buffer_y = 0;
         }
-    } else if (!g_charybdis_config.is_sniping_enabled) {
-        mouse_report->x = DISPLACEMENT_WITH_ACCELERATION(mouse_report->x);
-        mouse_report->y = DISPLACEMENT_WITH_ACCELERATION(mouse_report->y);
     }
 }
 
 report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
-    pointing_device_task_charybdis(&mouse_report);
-    mouse_report = pointing_device_task_user(mouse_report);
-
+    if (is_keyboard_master()) {
+        pointing_device_task_charybdis(&mouse_report);
+        mouse_report = pointing_device_task_user(mouse_report);
+    }
     return mouse_report;
 }
 
@@ -230,9 +223,9 @@ static bool has_shift_mod(void) {
     return mod_config(get_mods()) & MOD_MASK_SHIFT;
 #        else
     return mod_config(get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT;
-#        endif  // NO_ACTION_ONESHOT
+#        endif // NO_ACTION_ONESHOT
 }
-#    endif  // POINTING_DEVICE_ENABLE && !NO_CHARYBDIS_KEYCODES
+#    endif // POINTING_DEVICE_ENABLE && !NO_CHARYBDIS_KEYCODES
 
 /**
  * \brief Outputs the Charybdis configuration to console.
@@ -247,16 +240,16 @@ static bool has_shift_mod(void) {
  */
 __attribute__((unused)) static void debug_charybdis_config_to_console(charybdis_config_t* config) {
 #    ifdef CONSOLE_ENABLE
-    IGNORE_FORMAT_WARNING(dprintf("(charybdis) process_record_kb: config = {\n"
-                                  "\traw = 0x%04X,\n"
-                                  "\t{\n"
-                                  "\t\tis_dragscroll_enabled=%b\n"
-                                  "\t\tis_sniping_enabled=%b\n"
-                                  "\t\tdefault_dpi=0x%02X (%ld)\n"
-                                  "\t\tsniping_dpi=0x%01X (%ld)\n"
-                                  "\t}\n"
-                                  "}\n",
-                                  config->raw, config->is_dragscroll_enabled, config->is_sniping_enabled, config->pointer_default_dpi, get_pointer_default_dpi(config), config->pointer_sniping_dpi, get_pointer_sniping_dpi(config)));
+    dprintf("(charybdis) process_record_kb: config = {\n"
+            "\traw = 0x%X,\n"
+            "\t{\n"
+            "\t\tis_dragscroll_enabled=%u\n"
+            "\t\tis_sniping_enabled=%u\n"
+            "\t\tdefault_dpi=0x%X (%u)\n"
+            "\t\tsniping_dpi=0x%X (%u)\n"
+            "\t}\n"
+            "}\n",
+            config->raw, config->is_dragscroll_enabled, config->is_sniping_enabled, config->pointer_default_dpi, get_pointer_default_dpi(config), config->pointer_sniping_dpi, get_pointer_sniping_dpi(config));
 #    endif // CONSOLE_ENABLE
 }
 
@@ -307,7 +300,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
             }
             break;
     }
-#    endif  // !NO_CHARYBDIS_KEYCODES
+#    endif // !NO_CHARYBDIS_KEYCODES
     return true;
 }
 
@@ -318,22 +311,70 @@ void eeconfig_init_kb(void) {
     eeconfig_init_user();
 }
 
-void matrix_power_up(void) { pointing_device_task(); }
+void matrix_power_up(void) {
+    pointing_device_task();
+}
 
 void charybdis_config_sync_handler(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
     if (initiator2target_buffer_size == sizeof(g_charybdis_config)) {
         memcpy(&g_charybdis_config, initiator2target_buffer, sizeof(g_charybdis_config));
     }
 }
+#endif // POINTING_DEVICE_ENABLE
+
+__attribute__((weak)) void user_button_init(void) {
+#ifdef USER_BUTTON_PIN
+    gpio_set_pin_input_high(USER_BUTTON_PIN);
+#endif // USER_BUTTON_PIN
+}
+
+__attribute__((weak)) bool check_user_button_state(void) {
+#ifdef USER_BUTTON_PIN
+    return !gpio_read_pin(USER_BUTTON_PIN);
+#endif // USER_BUTTON_PIN
+    return false;
+}
 
 void keyboard_post_init_kb(void) {
+#ifdef DEBUG_LED_PIN
+    gpio_set_pin_output(DEBUG_LED_PIN);
+    gpio_write_pin_low(DEBUG_LED_PIN);
+#endif // DEBUG_LED_PIN
+
+#ifdef POINTING_DEVICE_ENABLE
     maybe_update_pointing_device_cpi(&g_charybdis_config);
     transaction_register_rpc(RPC_ID_KB_CONFIG_SYNC, charybdis_config_sync_handler);
-
+#endif // POINTING_DEVICE_ENABLE
     keyboard_post_init_user();
 }
 
+void keyboard_pre_init_kb(void) {
+    user_button_init();
+#ifdef POINTING_DEVICE_ENABLE
+    read_charybdis_config_from_eeprom(&g_charybdis_config);
+#endif // POINTING_DEVICE_ENAcBLE
+    keyboard_pre_init_user();
+}
+
+__attribute__((weak)) void execute_user_button_action(bool state) {
+    if (state) {
+        if (is_keyboard_master()) {
+            reset_keyboard();
+        } else {
+            soft_reset_keyboard();
+        }
+    }
+}
+
 void housekeeping_task_kb(void) {
+    static bool last_state = false;
+    bool        state      = check_user_button_state();
+    if (state != last_state) {
+        last_state = state;
+        execute_user_button_action(state);
+    }
+
+#ifdef POINTING_DEVICE_ENABLE
     if (is_keyboard_master()) {
         // Keep track of the last state, so that we can tell if we need to propagate to slave
         static charybdis_config_t last_charybdis_config = {0};
@@ -357,22 +398,50 @@ void housekeeping_task_kb(void) {
             }
         }
     }
-    // no need for user function, is called already
+#endif // POINTING_DEVICE_ENABLE
+       // no need for user function, is called already
 }
 
-#endif  // POINTING_DEVICE_ENABLE
+#ifdef USER_BUTTON_PIN
+/**
+ * @brief Replace and add upon the default bootmagic reset function.
+ * In this case, we also check the user button.
+ *
+ * @return true if the user button is pressed, or normal bootmagic key position.
+ * @return false if the user button is not pressed and normal bootmagic key position is not pressed.
+ */
+__attribute__((weak)) bool bootmagic_should_reset(void) {
+    uint8_t row = BOOTMAGIC_ROW;
+    uint8_t col = BOOTMAGIC_COLUMN;
+
+#    if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_ROW_RIGHT) && defined(BOOTMAGIC_COLUMN_RIGHT)
+    if (!is_keyboard_left()) {
+        row = BOOTMAGIC_ROW_RIGHT;
+        col = BOOTMAGIC_COLUMN_RIGHT;
+    }
+#    endif
 
-__attribute__((weak)) void matrix_init_sub_kb(void) {}
-void                       matrix_init_kb(void) {
-#ifdef POINTING_DEVICE_ENABLE
-    read_charybdis_config_from_eeprom(&g_charybdis_config);
-#endif  // POINTING_DEVICE_ENABLE
-    matrix_init_sub_kb();
-    matrix_init_user();
+    return matrix_get_row(row) & (1 << col) || check_user_button_state();
 }
+#endif // USER_BUTTON_PIN
 
-__attribute__((weak)) void matrix_scan_sub_kb(void) {}
-void                       matrix_scan_kb(void) {
-    matrix_scan_sub_kb();
-    matrix_scan_user();
+bool shutdown_kb(bool jump_to_bootloader) {
+    if (!shutdown_user(jump_to_bootloader)) {
+        return false;
+    }
+#ifdef RGB_MATRIX_ENABLE
+    void rgb_matrix_update_pwm_buffers(void);
+    rgb_matrix_set_color_all(RGB_RED);
+    rgb_matrix_update_pwm_buffers();
+#endif // RGB_MATRIX_ENABLE
+    return true;
+}
+
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) {
+    if (IS_KB_KEYCODE(keycode)) {
+        return true;
+    }
+    return is_mouse_record_user(keycode, record);
 }
+#endif // POINTING_DEVICE_AUTO_MOUSE_ENABLE

+ 10 - 12
keyboards/handwired/tractyl_manuform/tractyl_manuform.h

@@ -28,14 +28,15 @@ enum charybdis_keycodes {
     DRAGSCROLL_MODE,
     DRAGSCROLL_MODE_TOGGLE,
 };
-#        define DPI_MOD POINTER_DEFAULT_DPI_FORWARD
-#        define DPI_RMOD POINTER_DEFAULT_DPI_REVERSE
-#        define S_D_MOD POINTER_SNIPING_DPI_FORWARD
-#        define S_D_RMOD POINTER_SNIPING_DPI_REVERSE
-#        define SNIPING SNIPING_MODE
-#        define SNP_TOG SNIPING_MODE_TOGGLE
-#        define DRGSCRL DRAGSCROLL_MODE
-#        define DRG_TOG DRAGSCROLL_MODE_TOGGLE
+
+#define DPI_MOD POINTER_DEFAULT_DPI_FORWARD
+#define DPI_RMOD POINTER_DEFAULT_DPI_REVERSE
+#define S_D_MOD POINTER_SNIPING_DPI_FORWARD
+#define S_D_RMOD POINTER_SNIPING_DPI_REVERSE
+#define SNIPING SNIPING_MODE
+#define SNP_TOG SNIPING_MODE_TOGGLE
+#define DRGSCRL DRAGSCROLL_MODE
+#define DRG_TOG DRAGSCROLL_MODE_TOGGLE
 
 #ifdef POINTING_DEVICE_ENABLE
 /** \brief Return the current DPI value for the pointer's default mode. */
@@ -103,7 +104,4 @@ bool charybdis_get_pointer_dragscroll_enabled(void);
  * are translated into horizontal and vertical scroll movements.
  */
 void charybdis_set_pointer_dragscroll_enabled(bool enable);
-#endif  // POINTING_DEVICE_ENABLE
-
-void matrix_init_sub_kb(void);
-void matrix_scan_sub_kb(void);
+#endif // POINTING_DEVICE_ENABLE