diff --git a/keyboards/handwired/retrodactyl/config.h b/keyboards/handwired/retrodactyl/config.h new file mode 100644 index 0000000000..8289b00e93 --- /dev/null +++ b/keyboards/handwired/retrodactyl/config.h @@ -0,0 +1,56 @@ +// Copyright 2025 Lyderic Maillet (@lydux) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define EE_HANDS + +#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET +#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 1000U + +#define SERIAL_USART_FULL_DUPLEX +#define SERIAL_USART_TX_PIN GP0 +#define SERIAL_USART_RX_PIN GP1 + +/* key matrix size */ +#define MATRIX_ROWS 12 +#define MATRIX_COLS 6 +//#define MATRIX_MUX_COLS 3 + +// Left side +#define MATRIX_ROW_PINS { GP10, GP11, GP12, GP13, GP14, GP15 } +#define MATRIX_COL_PINS { GP16, GP17, GP18, GP19, GP20, GP21 } +#define ENCODER_A_PINS {} +#define ENCODER_B_PINS {} + +//Right side +#define MATRIX_ROW_PINS_RIGHT { GP23, GP29, GP28, GP27, GP26, GP22 } +#define MATRIX_COL_PINS_RIGHT { GP21, GP20, GP19, GP18, GP17, GP16 } +#define ENCODER_A_PINS_RIGHT { GP10 } +#define ENCODER_B_PINS_RIGHT { GP11 } + +#define OLED_DISPLAY_128x32 +#define OLED_IC OLED_IC_SH1106 + +/* OLED SPI Pins */ +#define OLED_DC_PIN GP6 +#define OLED_CS_PIN GP5 +#define OLED_RST_PIN GP7 + +/* Divisor for OLED */ +#define OLED_SPI_DIVISOR 4 + +/* ChibiOS SPI definitions */ +#define SPI_DRIVER SPID0 +#define SPI_SCK_PIN GP2 +#define SPI_MOSI_PIN GP3 +#define SPI_MISO_PIN GP4 + + +#define PMW33XX_CS_PIN GP8 +#define PMW33XX_CS_DIVISOR 64 + +//#define PMW33XX_LIFTOFF_DISTANCE 0x02 +#define PMW33XX_CPI 800 +#define ROTATIONAL_TRANSFORM_ANGLE 0x30 +#define POINTING_DEVICE_INVERT_Y diff --git a/keyboards/handwired/retrodactyl/halconf.h b/keyboards/handwired/retrodactyl/halconf.h new file mode 100644 index 0000000000..f04a44a8f4 --- /dev/null +++ b/keyboards/handwired/retrodactyl/halconf.h @@ -0,0 +1,12 @@ +#pragma once + +#include_next + +#undef HAL_USE_SPI +#define HAL_USE_SPI TRUE + +#undef SPI_USE_WAIT +#define SPI_USE_WAIT TRUE + +#undef SPI_SELECT_MODE +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD diff --git a/keyboards/handwired/retrodactyl/keyboard.json b/keyboards/handwired/retrodactyl/keyboard.json new file mode 100644 index 0000000000..fb0e3d0a00 --- /dev/null +++ b/keyboards/handwired/retrodactyl/keyboard.json @@ -0,0 +1,112 @@ +{ + "manufacturer": "Lydux", + "keyboard_name": "retrodactyl", + "maintainer": "Lydux", + "bootloader": "rp2040", + "processor": "RP2040", + "url": "", + "usb": { + "device_version": "1.0.0", + "pid": "0x0000", + "vid": "0xFEED" + }, + "features": { + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "pointing_device": true + }, + "split": { + "enabled": true, + "serial": { + "driver": "vendor" + } + }, + "diode_direction": "COL2ROW", + "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": [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, 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": [4, 4], "x": 4, "y": 5}, + {"matrix": [4, 5], "x": 5, "y": 5}, + + {"matrix": [10, 0], "x": 11, "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, 0], "x": 9, "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} + ] + } + } +} diff --git a/keyboards/handwired/retrodactyl/keymaps/default/keymap.c b/keyboards/handwired/retrodactyl/keymaps/default/keymap.c new file mode 100644 index 0000000000..8f369bed42 --- /dev/null +++ b/keyboards/handwired/retrodactyl/keymaps/default/keymap.c @@ -0,0 +1,158 @@ +// Copyright 2022 Ethan (@rocketstrong) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +/* + * ┌──┐┌──┐┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐┌──┐┌──┐ + *┌──┐│ ││ ││ ││ ││ │ │ ││ ││ ││ ││ │┌──┐ + *│ │└──┘└──┘└──┘└──┘└──┘ └──┘└──┘└──┘└──┘└──┘│ │ + *└──┘┌──┐┌──┐┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐┌──┐┌──┐└──┘ + *┌──┐│ ││ ││ ││ ││ │ │ ││ ││ ││ ││ │┌──┐ + *│ │└──┘└──┘└──┘└──┘└──┘ └──┘└──┘└──┘└──┘└──┘│ │ + *└──┘┌──┐┌──┐┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐┌──┐┌──┐└──┘ + *┌──┐│ ││ ││ ││ ││ │ │ ││ ││ ││ ││ │┌──┐ + *│ │└──┘└──┘└──┘└──┘└──┘ └──┘└──┘└──┘└──┘└──┘│ │ + *└──┘┌──┐┌──┐┌──┐┌──┐┌──┐ ┌──┐┌──┐┌──┐┌──┐┌──┐└──┘ + *┌──┐│ ││ ││ ││ ││ │ │ ││ ││ ││ ││ │┌──┐ + *│ │└──┘└──┘└──┘└──┘└──┘ └──┘└──┘└──┘└──┘└──┘│ │ + *└──┘ ┌──┐┌──┐ ┌──┐┌──┐ └──┘ + * │ ││ │ │ ││ │ + * └──┘└──┘ ┌──┐ ┌──┐ ┌──┐ ┌──┐ └──┘└──┘ + * │ │ │ │ │ │ │ │ + * └──┘ └──┘ └──┘ └──┘ + * ┌──┐ ┌──┐ ┌──┐ ┌──┐ + * │ │ │ │ │ │ │ │ + * └──┘ └──┘ └──┘ └──┘ + * ┌──┐┌──┐ ┌──┐┌──┐ + * │ ││ │ │ ││ │ + * └──┘└──┘ └──┘└──┘ + */ + +enum custom_keycodes { + DRAG_SCROLL = SAFE_RANGE, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 ,KC_9 ,KC_0 ,KC_GRV , + KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I ,KC_O ,KC_P ,KC_BSLS, + KC_LSFT, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K ,KC_L ,KC_SCLN,KC_QUOT, + KC_LCTL, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM,KC_DOT,KC_SLSH,TG(5) , + KC_LBRC,KC_RBRC, KC_MINS,KC_EQL, + KC_LGUI,KC_SPC , KC_ENT , MO(1) , + MO(3) ,KC_HOME, KC_END , KC_DEL, + KC_BSPC,MO(4) , MO(2) , KC_LALT + ), + [1] = LAYOUT( + KC_F12 , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10, KC_F11, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_PGUP, + KC_TRNS,_______,_______,_______,_______,_______, _______,_______,_______,_______,KC_UP ,KC_PGDN, + KC_TRNS,_______,_______,_______,_______,_______, _______,_______,_______,_______,KC_DOWN,KC_RGHT, + _______,_______, _______,KC_LEFT, + KC_TRNS,_______, _______,KC_TRNS, + _______,KC_INS , _______,_______, + _______,_______, _______,KC_RALT + ), + [2] = LAYOUT( + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______, _______,_______, + KC_TRNS,_______, _______,_______, + _______,_______, _______,_______, + _______,_______, KC_TRNS,_______ + ), + [3] = LAYOUT( + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______, _______,_______, + _______,_______, _______,_______, + KC_TRNS,_______, _______,_______, + _______,_______, _______,_______ + ), + [4] = LAYOUT( + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,QK_BOOT, + _______,_______, _______,_______, + _______,_______, _______,_______, + _______,_______, _______,_______, + _______,KC_TRNS, _______,_______ + ), + [5] = LAYOUT( + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,_______, + _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_TRNS, + _______,_______, _______,_______, + _______,_______, _______,_______, + _______,_______, MS_BTN2,_______, + _______,_______, MS_BTN1,DRAG_SCROLL + ) +}; + +#if defined(ENCODER_MAP_ENABLE) +const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { + [0] = { ENCODER_CCW_CW(MS_WHLU, MS_WHLD) }, + [1] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, + [2] = { ENCODER_CCW_CW(MS_WHLU, MS_WHLD) }, + [3] = { ENCODER_CCW_CW(MS_WHLU, MS_WHLD) }, + [4] = { ENCODER_CCW_CW(MS_WHLU, MS_WHLD) }, + [5] = { ENCODER_CCW_CW(MS_WHLU, MS_WHLD) }, +}; +#endif + +static void render_logo(void) { + static const char PROGMEM qmk_logo[] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 + }; + + oled_write_P(qmk_logo, false); +} + +bool oled_task_user(void) { + render_logo(); + return false; +} + + +bool set_scrolling = false; +float scroll_accumulated_h = 0; +float scroll_accumulated_v = 0; + +#define DRAGSCROLL_DIVISOR_H 16.0 +#define DRAGSCROLL_DIVISOR_V 16.0 + +report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { + if (set_scrolling) { + scroll_accumulated_h += (float)mouse_report.x / DRAGSCROLL_DIVISOR_H; + scroll_accumulated_v += (float)mouse_report.y / DRAGSCROLL_DIVISOR_V; + + // Assign integer parts of accumulated scroll values to the mouse report + mouse_report.h = (int8_t)scroll_accumulated_h; + mouse_report.v = -(int8_t)scroll_accumulated_v; + + // Update accumulated scroll values by subtracting the integer parts + scroll_accumulated_h -= (int8_t)scroll_accumulated_h; + scroll_accumulated_v -= (int8_t)scroll_accumulated_v; + + // Clear the X and Y values of the mouse report + mouse_report.x = 0; + mouse_report.y = 0; + } + return mouse_report; +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + if (keycode == DRAG_SCROLL && record->event.pressed) { + set_scrolling = !set_scrolling; + } + return true; +} diff --git a/keyboards/handwired/retrodactyl/mcuconf.h b/keyboards/handwired/retrodactyl/mcuconf.h new file mode 100644 index 0000000000..d81a1834a5 --- /dev/null +++ b/keyboards/handwired/retrodactyl/mcuconf.h @@ -0,0 +1,9 @@ +#pragma once + +#include_next + +#undef RP_SPI_USE_SPI0 +#define RP_SPI_USE_SPI0 TRUE + +#undef RP_SPI_USE_SPI1 +#define RP_SPI_USE_SPI1 TRUE diff --git a/keyboards/handwired/retrodactyl/rules.mk b/keyboards/handwired/retrodactyl/rules.mk new file mode 100644 index 0000000000..0276734272 --- /dev/null +++ b/keyboards/handwired/retrodactyl/rules.mk @@ -0,0 +1,14 @@ +POINTING_DEVICE_DRIVER = pmw3389 +POINTING_DEVICE_ROTATION_180 = yes + +MOUSE_SHARED_EP = yes + +ENCODER_ENABLE = yes +ENCODER_MAP_ENABLE = yes + +OLED_ENABLE = yes +OLED_DRIVER = ssd1306 +OLED_TRANSPORT = spi + +#QUANTUM_PAINTER_ENABLE = yes +#QUANTUM_PAINTER_DRIVERS += sh1106_spi