diff --git a/keyboards/revolt/keymaps/default/keymap.c b/keyboards/revolt/keymaps/default/keymap.c new file mode 100644 index 00000000000..b866065fc4a --- /dev/null +++ b/keyboards/revolt/keymaps/default/keymap.c @@ -0,0 +1,47 @@ +// Copyright 2025 Jacek Królikowski (@nietaki) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +enum custom_keycodes { + _QWERTY, + _FUN, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_QWERTY] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + KC_GRV ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 , KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_BSPC + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_INS , KC_DEL ,KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_BSLS + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,KC_ESC ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G ,KC_LBRC , KC_RBRC ,KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_QUOT + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B ,TO(0) , TO(1) ,KC_N ,KC_M ,KC_COMM ,KC_DOT ,KC_SLSH ,KC_RSFT + //├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┐ ┌────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤ + ,KC_LCTL ,KC_LGUI ,KC_LGUI ,MO(1) , KC_LALT , KC_SPC ,KC_EQL , KC_ENT , KC_MINS, KC_RALT , KC_LEFT ,KC_DOWN ,KC_UP ,KC_RGHT + //└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘ + // ┌───────────┬───────────┬───────────┐ + ,MS_BTN1 ,MS_BTN3 ,MS_BTN2 + // └───────────┴───────────┴───────────┘ + ), + + [_FUN] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + _______ ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,_______ + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,_______ ,KC_F11 ,KC_F12 ,_______ ,_______ ,_______ ,QK_BOOT , RMS_TOG ,_______ ,_______ ,_______ ,_______ ,_______ ,_______ + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,TO(0) ,_______ ,_______ ,_______ ,_______ ,_______ ,QK_RBT , RMS_OFF ,KC_MPRV ,KC_VOLD , KC_VOLU,KC_MNXT ,KC_MPLY ,_______ + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + ,KC_CAPS ,_______ ,_______ ,BL_STEP ,_______ ,_______ ,_______ , _______ ,TO(0) ,QK_LLCK ,_______ ,_______ ,_______ ,_______ + //├────────┼────────┼────────┼────────┼────┬───┴────┬───┼────────┼────────┐ ┌────────┼────────┼───┬────┴───┬────┼────────┼────────┼────────┼────────┤ + ,_______ ,_______ ,_______ ,_______ , _______ , _______ ,_______ , _______ , _______ , _______ , KC_HOME ,KC_PGDN ,KC_PGUP ,KC_END + //└────────┴────────┴────────┴────────┘ └────────┘ └────────┴────────┘ └────────┴────────┘ └────────┘ └────────┴────────┴────────┴────────┘ + // ┌───────────┬───────────┬───────────┐ + ,MS_WHLD ,MS_WHLU , _______ + // └───────────┴───────────┴───────────┘ + ), +}; + diff --git a/keyboards/revolt/readme.md b/keyboards/revolt/readme.md new file mode 100644 index 00000000000..5f3c3094af8 --- /dev/null +++ b/keyboards/revolt/readme.md @@ -0,0 +1,45 @@ +# Revolt + +![Imgur](https://i.imgur.com/agVoXko.jpeg) + +- Keyboard Maintainer: [Jacek Królikowski](https://github.com/nietaki) +- Hardware Supported: RPI 2040, Revolt Keyboard rev2 +- Hardware Availability: + - [purchase from NTK studio](https://ntkstudio.net/products/revolt-keyboard/) + - [make your own](https://github.com/nietaki/revolt-keyboard) (Kicad, CC-BY-SA-4.0 license) + +## Non-basic functionality + +- backlight cycling +- midi (advanced) functionality is enabled (although currently not mapped in the default keymap) +- capslock indicator is mapped to the LED on the underside of the RP2040 board +- You can use the custom keycodes: `RMS_ON` to enable the joystick mouse and `RMS_OFF` to disable it, `RMS_TOG` to toggle it. + - it can be useful in case the joystick potentiometers wear out and you don't have a spare + - the setting is saved in EEPROM, so the behaviour will be retained if you unplug the keyboard and plug it back in. + +## Revisions + +The firmware revision you want to use is determined by the revision of the commander +PCB. You want the largest revision number that's less than or equal to your commander PCB revision. + +So if you have commander PCB rev3, you want to use firmware rev2, unless rev3 is available. Firmware rev4 is likely incompatible with rev3 commander PCBs. + +## Building + +Make example for this keyboard (after setting up your build environment), using the `default` keymap: + + $ make revolt/rev2:default + # alternatively, using qmk cli + $ qmk compile -kb revolt/rev2 -km default + +This will create a `revolt_rev2_default.uf2` file in the root `qmk_firmware` repo directory. + +Flash the firmware by putting the kyboard into the bootloader mode and copying the compiled `.uf2` file into the `RPI-RP2` drive that appears. + +## Bootloader + +Enter the bootloader in one of 3 ways: + +- **Bootmagic reset**: Hold down the top left key of the left hand board and plug in or reset the keyboard +- **Physical reset button**: Briefly press the reset button on the top side of the Commander board +- **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available diff --git a/keyboards/revolt/rev2/config.h b/keyboards/revolt/rev2/config.h new file mode 100644 index 00000000000..3e2e90f5b8c --- /dev/null +++ b/keyboards/revolt/rev2/config.h @@ -0,0 +1,20 @@ +// Copyright 2025 Jacek Królikowski (@nietaki) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#define BACKLIGHT_PWM_DRIVER PWMD6 +#define BACKLIGHT_PWM_CHANNEL RP2040_PWM_CHANNEL_A + +#define ANALOG_JOYSTICK_READ_INTERVAL 2 +#define ANALOG_JOYSTICK_X_AXIS_PIN GP26 +#define ANALOG_JOYSTICK_Y_AXIS_PIN GP27 +#define ANALOG_JOYSTICK_AUTO_AXIS + +// Lower Values Create Faster Movement +#define ANALOG_JOYSTICK_SPEED_REGULATOR 10 + +// Weights topping out at 100 early to account for the circular gate of the PSP joystick +// JSON.stringify(Array.from(Array(101).keys()).map(x =>Math.min(Math.round( x / 4 + Math.pow(Math.max(x - 20, 0), 3)/2000), 100))) +#define ANALOG_JOYSTICK_WEIGHTS {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 26, 28, 29, 31, 33, 35, 37, 40, 42, 44, 47, 50, 53, 56, 59, 62, 65, 69, 72, 76, 80, 84, 88, 93, 97, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100} + +#define MIDI_ADVANCED diff --git a/keyboards/revolt/rev2/halconf.h b/keyboards/revolt/rev2/halconf.h new file mode 100644 index 00000000000..a249b91ef91 --- /dev/null +++ b/keyboards/revolt/rev2/halconf.h @@ -0,0 +1,8 @@ +// Copyright 2025 Jacek Królikowski (@nietaki) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define HAL_USE_PWM TRUE + +#include_next diff --git a/keyboards/revolt/rev2/keyboard.json b/keyboards/revolt/rev2/keyboard.json new file mode 100644 index 00000000000..88b33eafe02 --- /dev/null +++ b/keyboards/revolt/rev2/keyboard.json @@ -0,0 +1,131 @@ +{ + "manufacturer": "NTK studio", + "keyboard_name": "revolt/rev2", + "maintainer": "nietaki", + "backlight": { + "pin": "GP28" + }, + "bootloader": "rp2040", + "bootloader_instructions": "hold the button on the MCU while plugging in the keyboard (or pressing the reset button on the top surface of the commander board)", + "diode_direction": "COL2ROW", + "dynamic_keymap": { + "layer_count": 7 + }, + "features": { + "backlight": true, + "bootmagic": true, + "extrakey": true, + "layer_lock": true, + "midi": true, + "mousekey": true, + "nkro": true, + "pointing_device": true + }, + "indicators": { + "caps_lock": "GP25" + }, + "keycodes": [ + { + "key": "RMS_OFF", + "label": "revolt mouse off" + }, + { + "key": "RMS_ON", + "label": "revolt mouse on" + }, + { + "key": "RMS_TOG", + "label": "revolt mouse toggle" + } + ], + "matrix_pins": { + "cols": ["GP22", "GP21", "GP20", "GP19", "GP18", "GP17", "GP16", "GP8", "GP7", "GP6", "GP3", "GP2", "GP1", "GP0", "GP14", "GP15", "GP4"], + "masked": true, + "rows": ["GP13", "GP12", "GP11", "GP10", "GP9"] + }, + "processor": "RP2040", + "tags": ["split", "ergonomic", "ortho", "choc v1", "rp2040", "choc spaced", "65%"], + "url": "https://ntkstudio.net/products/revolt-keyboard/", + "usb": { + "device_version": "2.0.0", + "pid": "0x0002", + "vid": "0x1987" + }, + "layouts": { + "LAYOUT": { + "layout": [ + {"label": "`", "matrix": [0, 0], "x": 0, "y": 0.25}, + {"label": "1", "matrix": [0, 1], "x": 1, "y": 0.25}, + {"label": "2", "matrix": [0, 2], "x": 2, "y": 0}, + {"label": "3", "matrix": [0, 3], "x": 3, "y": 0}, + {"label": "4", "matrix": [0, 4], "x": 4, "y": 0}, + {"label": "5", "matrix": [0, 5], "x": 5, "y": 0}, + {"label": "6", "matrix": [0, 8], "x": 12, "y": 0}, + {"label": "7", "matrix": [0, 9], "x": 13, "y": 0}, + {"label": "8", "matrix": [0, 10], "x": 14, "y": 0}, + {"label": "9", "matrix": [0, 11], "x": 15, "y": 0}, + {"label": "0", "matrix": [0, 12], "x": 16, "y": 0.25}, + {"label": "=", "matrix": [0, 13], "x": 17, "y": 0.25}, + {"label": "Tab", "matrix": [1, 0], "x": 0, "y": 1.25}, + {"label": "Q", "matrix": [1, 1], "x": 1, "y": 1.25}, + {"label": "W", "matrix": [1, 2], "x": 2, "y": 1}, + {"label": "E", "matrix": [1, 3], "x": 3, "y": 1}, + {"label": "R", "matrix": [1, 4], "x": 4, "y": 1}, + {"label": "T", "matrix": [1, 5], "x": 5, "y": 1}, + {"label": "LB1", "matrix": [1, 6], "x": 6, "y": 1}, + {"label": "RB1", "matrix": [1, 7], "x": 11, "y": 1}, + {"label": "Y", "matrix": [1, 8], "x": 12, "y": 1}, + {"label": "U", "matrix": [1, 9], "x": 13, "y": 1}, + {"label": "I", "matrix": [1, 10], "x": 14, "y": 1}, + {"label": "O", "matrix": [1, 11], "x": 15, "y": 1}, + {"label": "P", "matrix": [1, 12], "x": 16, "y": 1.25}, + {"label": "backslash", "matrix": [1, 13], "x": 17, "y": 1.25}, + {"label": "Caps", "matrix": [2, 0], "x": 0, "y": 2.25}, + {"label": "A", "matrix": [2, 1], "x": 1, "y": 2.25}, + {"label": "S", "matrix": [2, 2], "x": 2, "y": 2}, + {"label": "D", "matrix": [2, 3], "x": 3, "y": 2}, + {"label": "F", "matrix": [2, 4], "x": 4, "y": 2}, + {"label": "G", "matrix": [2, 5], "x": 5, "y": 2}, + {"label": "LB2", "matrix": [2, 6], "x": 6, "y": 2}, + {"label": "RB2", "matrix": [2, 7], "x": 11, "y": 2}, + {"label": "H", "matrix": [2, 8], "x": 12, "y": 2}, + {"label": "J", "matrix": [2, 9], "x": 13, "y": 2}, + {"label": "K", "matrix": [2, 10], "x": 14, "y": 2}, + {"label": "L", "matrix": [2, 11], "x": 15, "y": 2}, + {"label": ";", "matrix": [2, 12], "x": 16, "y": 2.25}, + {"label": "'", "matrix": [2, 13], "x": 17, "y": 2.25}, + {"label": "Shift", "matrix": [3, 0], "x": 0, "y": 3.25}, + {"label": "Z", "matrix": [3, 1], "x": 1, "y": 3.25}, + {"label": "X", "matrix": [3, 2], "x": 2, "y": 3}, + {"label": "C", "matrix": [3, 3], "x": 3, "y": 3}, + {"label": "V", "matrix": [3, 4], "x": 4, "y": 3}, + {"label": "B", "matrix": [3, 5], "x": 5, "y": 3}, + {"label": "LT3", "matrix": [3, 6], "x": 6.25, "y": 3.25}, + {"label": "RT3", "matrix": [3, 7], "x": 10.75, "y": 3.25}, + {"label": "N", "matrix": [3, 8], "x": 12, "y": 3}, + {"label": "M", "matrix": [3, 9], "x": 13, "y": 3}, + {"label": ",", "matrix": [3, 10], "x": 14, "y": 3}, + {"label": ".", "matrix": [3, 11], "x": 15, "y": 3}, + {"label": "/", "matrix": [3, 12], "x": 16, "y": 3.25}, + {"label": "SHIFT", "matrix": [3, 13], "x": 17, "y": 3.25}, + {"label": "Ctrl", "matrix": [4, 0], "x": 0, "y": 4.25}, + {"label": "WIN", "matrix": [4, 1], "x": 1, "y": 4.25}, + {"label": "SUPER", "matrix": [4, 2], "x": 2, "y": 4}, + {"label": "HYPER", "matrix": [4, 3], "x": 3, "y": 4}, + {"label": "ALT", "matrix": [4, 4], "x": 4.5, "y": 4}, + {"label": "LT1", "matrix": [4, 5], "x": 6.25, "y": 4.25}, + {"label": "LT2", "matrix": [4, 6], "x": 7.25, "y": 4.25}, + {"label": "RT2", "matrix": [4, 7], "x": 9.75, "y": 4.25}, + {"label": "RT1", "matrix": [4, 8], "x": 10.75, "y": 4.25}, + {"label": "ALT", "matrix": [4, 9], "x": 12.5, "y": 4}, + {"label": "left", "matrix": [4, 10], "x": 14, "y": 4}, + {"label": "down", "matrix": [4, 11], "x": 15, "y": 4}, + {"label": "up", "matrix": [4, 12], "x": 16, "y": 4.25}, + {"label": "right", "matrix": [4, 13], "x": 17, "y": 4.25}, + {"label": "LMB", "matrix": [4, 14], "x": 7.5, "y": 5.5}, + {"label": "MMB", "matrix": [4, 15], "x": 8.5, "y": 5.5}, + {"label": "RMB", "matrix": [4, 16], "x": 9.5, "y": 5.5} + ] + } + } +} diff --git a/keyboards/revolt/rev2/mcuconf.h b/keyboards/revolt/rev2/mcuconf.h new file mode 100644 index 00000000000..e33b86cdcee --- /dev/null +++ b/keyboards/revolt/rev2/mcuconf.h @@ -0,0 +1,9 @@ +// Copyright 2025 Jacek Królikowski (@nietaki) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include_next + +#undef RP_PWM_USE_PWM6 +#define RP_PWM_USE_PWM6 TRUE diff --git a/keyboards/revolt/rev2/rev2.c b/keyboards/revolt/rev2/rev2.c new file mode 100644 index 00000000000..db0a17856fb --- /dev/null +++ b/keyboards/revolt/rev2/rev2.c @@ -0,0 +1,61 @@ +// Copyright 2025 Jacek Królikowski (@nietaki) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +typedef union { + uint32_t raw; + struct { + bool mouseEnabled : 1; + }; +} keyboard_config_t; + +keyboard_config_t revoltConfig; + +void persistConfig(void) { + eeconfig_update_kb(revoltConfig.raw); +} + +void eeconfig_init_kb(void) { + // default config values + revoltConfig.mouseEnabled = true; + + persistConfig(); + + eeconfig_init_user(); +} + +void keyboard_post_init_kb(void) { + revoltConfig.raw = eeconfig_read_kb(); + keyboard_post_init_user(); +} + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + /* provide a way to disable the pointing device functionality at runtime */ + switch (keycode) { + case RMS_ON: + revoltConfig.mouseEnabled = true; + persistConfig(); + return false; + case RMS_OFF: + revoltConfig.mouseEnabled = false; + persistConfig(); + return false; + case RMS_TOG: + revoltConfig.mouseEnabled = !revoltConfig.mouseEnabled; + persistConfig(); + return false; + default: + break; + } + + return process_record_user(keycode, record); +} + +report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { + if (!revoltConfig.mouseEnabled) { + mouse_report.x = 0; + mouse_report.y = 0; + } + return pointing_device_task_user(mouse_report); +} diff --git a/keyboards/revolt/rev2/rules.mk b/keyboards/revolt/rev2/rules.mk new file mode 100644 index 00000000000..c76a8bf8a18 --- /dev/null +++ b/keyboards/revolt/rev2/rules.mk @@ -0,0 +1 @@ +POINTING_DEVICE_DRIVER = analog_joystick