summaryrefslogtreecommitdiff
path: root/keyboards/spleeb
diff options
context:
space:
mode:
authorChristopher Hoage <iam@chrishoage.com>2023-03-10 21:33:52 -0800
committerGitHub <noreply@github.com>2023-03-10 22:33:52 -0700
commit96b0baa230fb0672a68d1f75ba58613526fef0e7 (patch)
tree213d1bcfd434d410ad68046b31b0e2397a6ead13 /keyboards/spleeb
parentdbd1d3cba111dabf3b2d322a3681039cf46603f7 (diff)
[Keyboard] Add Spleeb default and custom firmware (#19481)
Co-authored-by: jack <0x6a73@protonmail.com>
Diffstat (limited to 'keyboards/spleeb')
-rw-r--r--keyboards/spleeb/config.h36
-rw-r--r--keyboards/spleeb/info.json124
-rw-r--r--keyboards/spleeb/keymaps/chrishoage/config.h15
-rw-r--r--keyboards/spleeb/keymaps/chrishoage/keymap.c127
-rw-r--r--keyboards/spleeb/keymaps/chrishoage/rules.mk11
-rw-r--r--keyboards/spleeb/keymaps/default/keymap.c33
-rw-r--r--keyboards/spleeb/lib/glcdfont.c233
-rw-r--r--keyboards/spleeb/mcuconf.h9
-rw-r--r--keyboards/spleeb/readme.md109
-rw-r--r--keyboards/spleeb/rules.mk1
-rw-r--r--keyboards/spleeb/spleeb.c544
-rw-r--r--keyboards/spleeb/spleeb.h149
12 files changed, 1391 insertions, 0 deletions
diff --git a/keyboards/spleeb/config.h b/keyboards/spleeb/config.h
new file mode 100644
index 0000000000..72a09e89c9
--- /dev/null
+++ b/keyboards/spleeb/config.h
@@ -0,0 +1,36 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6// Auto mouse layer makes use of the Cirque touchdown indicator which requires
7// the touch sensor to be on the master side
8#define MASTER_RIGHT
9
10// Sync later, led, and mod state for use on OLED on slave side
11#define SPLIT_LAYER_STATE_ENABLE
12#define SPLIT_LED_STATE_ENABLE
13#define SPLIT_MODS_ENABLE
14// Transport dpi and enc mode for display on oled
15#define SPLIT_TRANSACTION_IDS_KB RPC_ID_KB_CONFIG_SYNC
16
17#ifdef POINTING_DEVICE_ENABLE
18# define POINTING_DEVICE_AUTO_MOUSE_ENABLE
19// Absolute mode allows for z/touchdown triggering of auto mouse layer with out
20// moving finger
21# define CIRQUE_PINNACLE_POSITION_MODE CIRQUE_PINNACLE_ABSOLUTE_MODE
22# define POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE
23#endif // POINTING_DEVICE_ENABLE
24
25#define I2C_DRIVER I2CD1
26#define I2C1_SDA_PIN GP16
27#define I2C1_SCL_PIN GP17
28
29#ifdef OLED_ENABLE
30# define OLED_DISPLAY_128X64
31# define OLED_FONT_H "./lib/glcdfont.c"
32#endif // OLED_ENABLE
33
34#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
35#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP17
36#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 1000U
diff --git a/keyboards/spleeb/info.json b/keyboards/spleeb/info.json
new file mode 100644
index 0000000000..0af488135d
--- /dev/null
+++ b/keyboards/spleeb/info.json
@@ -0,0 +1,124 @@
1{
2 "manufacturer": "Chris Hoage",
3 "keyboard_name": "spleeb",
4 "maintainer": "chrishoage",
5 "bootloader": "rp2040",
6 "diode_direction": "COL2ROW",
7 "encoder": {
8 "enabled": true,
9 "rotary": [
10 {
11 "pin_a": "GP4",
12 "pin_b": "GP21",
13 "resolution": 2
14 }
15 ]
16 },
17 "features": {
18 "nkro": true
19 },
20 "matrix_pins": {
21 "cols": ["GP23", "GP20", "GP22", "GP26", "GP27", "GP28", "GP29"],
22 "rows": ["GP5", "GP6", "GP7", "GP8", "GP9"]
23 },
24 "processor": "RP2040",
25 "board": "QMK_PM2040",
26 "secure": {
27 "idle_timeout": 60000,
28 "unlock_sequence": [
29 [5, 0],
30 [5, 1]
31 ],
32 "unlock_timeout": 5000
33 },
34 "split": {
35 "enabled": true,
36 "soft_serial_pin": "GP1",
37 "encoder": {
38 "right": {
39 "rotary": [
40 {
41 "pin_a": "GP21",
42 "pin_b": "GP4"
43 }
44 ]
45 }
46 }
47 },
48 "url": "https://github.com/chrishoage/spleeb",
49 "usb": {
50 "device_version": "0.0.1",
51 "pid": "0x4242",
52 "vid": "0xFEED"
53 },
54 "layouts": {
55 "LAYOUT": {
56 "layout": [
57 { "matrix": [0, 0], "x": 0, "y": 0.6 },
58 { "matrix": [0, 1], "x": 1, "y": 0.6 },
59 { "matrix": [0, 2], "x": 2, "y": 0.2 },
60 { "matrix": [0, 3], "x": 3, "y": 0 },
61 { "matrix": [0, 4], "x": 4, "y": 0.2 },
62 { "matrix": [0, 5], "x": 5, "y": 0.4 },
63 { "matrix": [0, 6], "x": 6, "y": 0.9 },
64 { "matrix": [5, 6], "x": 9.75, "y": 0.9 },
65 { "matrix": [5, 5], "x": 10.75, "y": 0.4 },
66 { "matrix": [5, 4], "x": 11.75, "y": 0.2 },
67 { "matrix": [5, 3], "x": 12.75, "y": 0 },
68 { "matrix": [5, 2], "x": 13.75, "y": 0.2 },
69 { "matrix": [5, 1], "x": 14.75, "y": 0.6 },
70 { "matrix": [5, 0], "x": 15.75, "y": 0.6 },
71 { "matrix": [1, 0], "x": 0, "y": 1.6 },
72 { "matrix": [1, 1], "x": 1, "y": 1.6 },
73 { "matrix": [1, 2], "x": 2, "y": 1.2 },
74 { "matrix": [1, 3], "x": 3, "y": 1 },
75 { "matrix": [1, 4], "x": 4, "y": 1.2 },
76 { "matrix": [1, 5], "x": 5, "y": 1.4 },
77 { "matrix": [1, 6], "x": 6, "y": 1.9 },
78 { "matrix": [6, 6], "x": 9.75, "y": 1.9 },
79 { "matrix": [6, 5], "x": 10.75, "y": 1.4 },
80 { "matrix": [6, 4], "x": 11.75, "y": 1.2 },
81 { "matrix": [6, 3], "x": 12.75, "y": 1 },
82 { "matrix": [6, 2], "x": 13.75, "y": 1.2 },
83 { "matrix": [6, 1], "x": 14.75, "y": 1.6 },
84 { "matrix": [6, 0], "x": 15.75, "y": 1.6 },
85 { "matrix": [2, 0], "x": 0, "y": 2.6 },
86 { "matrix": [2, 1], "x": 1, "y": 2.6 },
87 { "matrix": [2, 2], "x": 2, "y": 2.2 },
88 { "matrix": [2, 3], "x": 3, "y": 2 },
89 { "matrix": [2, 4], "x": 4, "y": 2.2 },
90 { "matrix": [2, 5], "x": 5, "y": 2.4 },
91 { "matrix": [2, 6], "x": 6, "y": 2.9 },
92 { "matrix": [7, 6], "x": 9.75, "y": 2.9 },
93 { "matrix": [7, 5], "x": 10.75, "y": 2.4 },
94 { "matrix": [7, 4], "x": 11.75, "y": 2.2 },
95 { "matrix": [7, 3], "x": 12.75, "y": 2 },
96 { "matrix": [7, 2], "x": 13.75, "y": 2.2 },
97 { "matrix": [7, 1], "x": 14.75, "y": 2.6 },
98 { "matrix": [7, 0], "x": 15.75, "y": 2.6 },
99 { "matrix": [3, 1], "x": 1, "y": 3.6 },
100 { "matrix": [3, 2], "x": 2, "y": 3.2 },
101 { "matrix": [3, 3], "x": 3, "y": 3 },
102 { "matrix": [3, 4], "x": 4, "y": 3.2 },
103 { "matrix": [3, 5], "x": 5, "y": 3.4 },
104 { "matrix": [3, 6], "x": 7.2, "y": 3.15 },
105 { "matrix": [8, 6], "x": 8.6, "y": 3.15 },
106 { "matrix": [8, 5], "x": 10.75, "y": 3.4 },
107 { "matrix": [8, 4], "x": 11.75, "y": 3.2 },
108 { "matrix": [8, 3], "x": 12.75, "y": 3 },
109 { "matrix": [8, 2], "x": 13.75, "y": 3.2 },
110 { "matrix": [8, 1], "x": 14.75, "y": 3.6 },
111 { "matrix": [4, 2], "x": 3, "y": 4.45 },
112 { "matrix": [4, 3], "x": 4, "y": 4.45 },
113 { "matrix": [4, 4], "x": -0.15, "y": 4.65 },
114 { "h": 1.25, "matrix": [4, 5], "x": 0.85, "y": 4.4 },
115 { "h": 1.25, "matrix": [4, 6], "x": 1.85, "y": 4.4 },
116 { "h": 1.25, "matrix": [9, 6], "x": -3.1, "y": 4.6 },
117 { "h": 1.25, "matrix": [9, 5], "x": -2.1, "y": 4.6 },
118 { "matrix": [9, 4], "x": -1.1, "y": 4.85 },
119 { "matrix": [9, 3], "x": 11.75, "y": 4.45 },
120 { "matrix": [9, 2], "x": 12.75, "y": 4.45 }
121 ]
122 }
123 }
124}
diff --git a/keyboards/spleeb/keymaps/chrishoage/config.h b/keyboards/spleeb/keymaps/chrishoage/config.h
new file mode 100644
index 0000000000..0ac75d3041
--- /dev/null
+++ b/keyboards/spleeb/keymaps/chrishoage/config.h
@@ -0,0 +1,15 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#define AUTO_MOUSE_TIME 250
7
8#define CIRQUE_PINNACLE_DIAMETER_MM 35
9#define POINTING_DEVICE_ROTATION_180
10
11#define SPLEEB_DRAGSCROLL_REVERSE_X
12#define SPLEEB_ENCODER_MODE_MAP_ENABLE
13
14#define BOOTMAGIC_LITE_ROW 5
15#define BOOTMAGIC_LITE_COLUMN 6
diff --git a/keyboards/spleeb/keymaps/chrishoage/keymap.c b/keyboards/spleeb/keymaps/chrishoage/keymap.c
new file mode 100644
index 0000000000..2650c1aebf
--- /dev/null
+++ b/keyboards/spleeb/keymaps/chrishoage/keymap.c
@@ -0,0 +1,127 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include QMK_KEYBOARD_H
5
6// Double tap TD(0) to enter bootloader
7static void enter_qk_boot(qk_tap_dance_state_t *state, void *user_data) {
8 if (state->count >= 2) {
9 reset_keyboard();
10 reset_tap_dance(state);
11 }
12}
13
14enum SpleebLayer { _BASE = 0, _FN, _MOUSE };
15
16qk_tap_dance_action_t tap_dance_actions[] = {[0] = ACTION_TAP_DANCE_FN(enter_qk_boot)};
17
18// clang-format off
19const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
20
21 [_BASE] = LAYOUT(
22 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC, KC_BSPC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
23 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_MINS, KC_EQL, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_QUOT,
24 KC_LSFT, 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_RSFT,
25 KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MUTE, ENC_STR, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
26 KC_LCTL, KC_LALT, KC_LGUI, KC_ENT, MO(1), MO(1), KC_SPC, KC_RGUI, KC_RALT, KC_RCTL
27 ),
28
29 [_FN] = LAYOUT(
30 KC_PAUS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_ESC, KC_DEL, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_PSCR,
31 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_TRNS, KC_TRNS,
32 KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS, QK_RBT,
33 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ENC_STL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, TD(0),
34 KC_TRNS, KC_TRNS, KC_TRNS, KC_SPC, KC_TRNS, KC_TRNS, KC_ENT, KC_TRNS, KC_TRNS, KC_TRNS
35 ),
36
37 [_MOUSE] = LAYOUT(
38 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,
39 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,
40 DRGSCRL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, SNIPING, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
41 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN3, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
42 KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
43 ),
44};
45// clang-format on
46
47bool encoder_update_user(uint8_t index, bool clockwise) {
48 if (get_mods() & MOD_MASK_GUI) {
49 // When GUI is held trigger [ ] to move workspaces
50 tap_code(clockwise ? KC_RBRC : KC_LBRC);
51 return false;
52 }
53
54 if (get_mods() & MOD_MASK_CTRL) {
55 // When CTRL is hled trigger page up/down to move tabs (Firefox, VSCode)
56 tap_code(clockwise ? KC_PGDN : KC_PGUP);
57 return false;
58 }
59
60 if (get_mods() & MOD_MASK_ALT) {
61 // When ALT is held trigger up/down to move line up/down
62 tap_code(clockwise ? KC_DOWN : KC_UP);
63 return false;
64 }
65
66 // Defer to encoder_update_kb to trigger spleeb_encoder_mode_trigger
67 return true;
68}
69
70enum spleeb_enc_mode {
71 DEF_DPI,
72 SNP_DPI,
73 VOL,
74 SEL,
75};
76
77void spleeb_encoder_mode_trigger(uint8_t mode, bool clockwise) {
78 dprintf("spleeb_encoder_mode_trigger m: %u, c: %u\n", mode, clockwise);
79 switch (mode) {
80 case DEF_DPI:
81 spleeb_cycle_pointer_default_dpi(clockwise);
82 break;
83 case SNP_DPI:
84 spleeb_cycle_pointer_sniping_dpi(clockwise);
85 break;
86 case VOL:
87 tap_code(clockwise ? KC_VOLU : KC_VOLD);
88 break;
89 case SEL: {
90 bool is_shift = get_mods() & MOD_MASK_SHIFT;
91 uint16_t dir = clockwise ? KC_RIGHT : KC_LEFT;
92 if (is_shift) {
93 tap_code(dir);
94 } else {
95 tap_code16(LSFT(LCTL(dir)));
96 }
97 break;
98 }
99
100 default:
101 break;
102 }
103}
104
105const char *spleeb_encoder_mode_string(uint8_t mode) {
106 switch (mode) {
107 case DEF_DPI:
108 return "df dpi";
109 case SNP_DPI:
110 return "sn dpi";
111 case VOL:
112 return "volume";
113 case SEL:
114 return "select";
115 }
116
117 return get_u8_str(mode, ' ');
118}
119
120void pointing_device_init_user(void) {
121 set_auto_mouse_layer(_MOUSE);
122}
123
124const spleeb_enc_mode_t spleeb_encoder_mode_map[NUM_ENCODERS][SPLEEB_ENCODER_MODE_COUNT] = {
125 [0] = {SPLEEB_ENC_MODE(VOL), SPLEEB_ENC_MODE(SEL)},
126 [1] = {SPLEEB_ENC_MODE(DEF_DPI), SPLEEB_ENC_MODE(SNP_DPI), SPLEEB_ENC_MODE(SEL)},
127};
diff --git a/keyboards/spleeb/keymaps/chrishoage/rules.mk b/keyboards/spleeb/keymaps/chrishoage/rules.mk
new file mode 100644
index 0000000000..117c55fd8b
--- /dev/null
+++ b/keyboards/spleeb/keymaps/chrishoage/rules.mk
@@ -0,0 +1,11 @@
1TAP_DANCE_ENABLE = yes
2BOOTMAGIC_ENABLE = yes
3MOUSEKEY_ENABLE = yes
4EXTRAKEY_ENABLE = yes
5ENCODER_ENABLE = yes
6
7POINTING_DEVICE_ENABLE = yes
8POINTING_DEVICE_DRIVER = cirque_pinnacle_i2c
9
10OLED_ENABLE = yes
11OLED_DRIVER = SSD1306
diff --git a/keyboards/spleeb/keymaps/default/keymap.c b/keyboards/spleeb/keymaps/default/keymap.c
new file mode 100644
index 0000000000..dca49efd34
--- /dev/null
+++ b/keyboards/spleeb/keymaps/default/keymap.c
@@ -0,0 +1,33 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include QMK_KEYBOARD_H
5
6// clang-format off
7const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
8
9 [0] = LAYOUT(
10 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC, KC_BSPC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
11 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_MINS, KC_EQL, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_QUOT,
12 KC_LSFT, 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_RSFT,
13 KC_Z, KC_X, KC_C, KC_V, KC_B, KC_NO, KC_NO, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
14 KC_LCTL, KC_LALT, KC_LGUI, KC_ENT, MO(1), MO(1), KC_SPC, KC_RGUI, KC_RALT, KC_RCTL
15 ),
16
17 [1] = LAYOUT(
18 KC_PAUS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_ESC, KC_DEL, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_PSCR,
19 KC_LCAP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_TRNS, KC_TRNS,
20 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS, KC_TRNS,
21 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
22 KC_TRNS, KC_TRNS, KC_TRNS, KC_SPC, KC_TRNS, KC_TRNS, KC_ENT, KC_TRNS, KC_TRNS, KC_TRNS
23 ),
24
25 [2] = LAYOUT(
26 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,
27 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,
28 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,
29 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
30 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
31 ),
32};
33// clang-format on
diff --git a/keyboards/spleeb/lib/glcdfont.c b/keyboards/spleeb/lib/glcdfont.c
new file mode 100644
index 0000000000..5a7fcdaee2
--- /dev/null
+++ b/keyboards/spleeb/lib/glcdfont.c
@@ -0,0 +1,233 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "progmem.h"
5
6// clang-format off
7static const unsigned char PROGMEM font[] = {
8 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
10 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
11 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
12 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
13 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
14 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
15 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
16 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
17 0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
18 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
19 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
20 0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
21 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
22 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
23 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
24 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
25 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
26 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
27 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
28 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
29 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
30 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
31 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
32 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
33 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
34 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
35 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
36 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
37 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
38 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
39 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
42 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
43 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
44 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
45 0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
46 0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
47 0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
48 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
49 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
50 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
51 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
52 0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
53 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
54 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
55 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
56 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
57 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
58 0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
59 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
60 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
61 0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
62 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
63 0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
64 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
65 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
66 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
67 0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
68 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
69 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
70 0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
71 0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
72 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
73 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
74 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
75 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
76 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
77 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
78 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
79 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
80 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
81 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
82 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
83 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
84 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
85 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
86 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
87 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
88 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
89 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
90 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
91 0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
92 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
93 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
94 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
95 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
96 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
97 0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
98 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
99 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
100 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
101 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
102 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
103 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
104 0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
105 0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
106 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
107 0x38, 0x44, 0x44, 0x44, 0x20, 0x00,
108 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
109 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
110 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
111 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,
112 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
113 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
114 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
115 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
116 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
117 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
118 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
119 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
120 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
121 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
122 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
123 0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
124 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
125 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
126 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
127 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
128 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
129 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
130 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
131 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
132 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
133 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
134 0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
135 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
158 0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00,
159 0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E,
160 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00,
161 0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B,
162 0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00,
163 0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE,
164 0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00,
165 0x00, 0x00, 0x00, 0x04, 0xFA, 0xA1,
166 0xFA, 0x04, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
190 0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00,
191 0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F,
192 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00,
193 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20,
194 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00,
195 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F,
196 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00,
197 0x00, 0x00, 0x00, 0xFC, 0x87, 0x95,
198 0xB5, 0x87, 0xFC, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0x81,
201 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
202 0xFF, 0xFF, 0xFF, 0x9B, 0xAD, 0xAD,
203 0xAD, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF,
204 0xFF, 0xFF, 0xFF, 0xDD, 0xBD, 0xB5,
205 0xB5, 0xC9, 0xFF, 0xFF, 0xFF, 0xFF,
206 0xFF, 0xFF, 0xFF, 0xE1, 0xEF, 0xEF,
207 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF,
208 0xFF, 0xFF, 0xFF, 0x91, 0xB5, 0xB5,
209 0xB5, 0x85, 0xFF, 0xFF, 0xFF, 0xFF,
210 0xFF, 0xFF, 0xFF, 0x81, 0xB5, 0xB5,
211 0xB5, 0x85, 0xFF, 0xFF, 0xFF, 0xFF,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x08, 0x74, 0x42,
222 0x74, 0x08, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x00, 0x10, 0x18, 0x0C, 0x06,
224 0x0C, 0x18, 0x10, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x04, 0x04, 0x08, 0x10,
226 0x24, 0x24, 0x24, 0x24, 0x00, 0x00,
227 0x00, 0x00, 0xE7, 0xA5, 0xFF, 0x24,
228 0x24, 0xFF, 0xA5, 0xE7, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232};
233// clang-format on
diff --git a/keyboards/spleeb/mcuconf.h b/keyboards/spleeb/mcuconf.h
new file mode 100644
index 0000000000..30b20fdcbd
--- /dev/null
+++ b/keyboards/spleeb/mcuconf.h
@@ -0,0 +1,9 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include_next <mcuconf.h>
7
8#undef RP_I2C_USE_I2C0
9#define RP_I2C_USE_I2C0 TRUE
diff --git a/keyboards/spleeb/readme.md b/keyboards/spleeb/readme.md
new file mode 100644
index 0000000000..0b42352e29
--- /dev/null
+++ b/keyboards/spleeb/readme.md
@@ -0,0 +1,109 @@
1# spleeb
2
3![spleeb](https://i.imgur.com/2rmZa6Mh.jpg)
4
5A 5x7 split keyboard that has support for rotary encoders, an oled and a Ciruqe touchpad
6
7* Keyboard Maintainer: [Chris Hoage](https://github.com/chrishoage)
8* Hardware Supported: Spleeb PCB with a rp2040 MCU (Blok, Elite Pi, etc)
9* Hardware Availability: [https://github.com/chrishoage/spleeb](https://github.com/chrishoage/spleeb)
10
11Make example for this keyboard (after setting up your build environment):
12
13 make spleeb:default
14
15Flashing example for this keyboard:
16
17 make spleeb:default:flash
18
19See 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).
20
21## Encoder Mode Map
22
23Spleeb firmware has support for an encoder mode map similar to the native encoder map in QMK. The difference is the encoder mode map allows one to change behavior or the encoders independently of the layers. In your keymap.c file you can include something the following:
24
25```c
26enum spleeb_enc_mode {
27 DEF_DPI,
28 SNP_DPI,
29 VOL,
30 SEL,
31};
32
33void spleeb_encoder_mode_trigger(uint8_t mode, bool clockwise) {
34 dprintf("spleeb_encoder_mode_trigger m: %u, c: %u\n", mode, clockwise);
35 switch (mode) {
36 case DEF_DPI:
37 spleeb_cycle_pointer_default_dpi(clockwise);
38 break;
39 case SNP_DPI:
40 spleeb_cycle_pointer_sniping_dpi(clockwise);
41 break;
42 case VOL:
43 tap_code(clockwise ? KC_VOLU : KC_VOLD);
44 break;
45 case SEL:
46 bool is_shift = get_mods() & MOD_MASK_SHIFT;
47 uint16_t dir = clockwise ? KC_RIGHT : KC_LEFT;
48 if (is_shift) {
49 tap_code(dir);
50 } else {
51 tap_code16(LSFT(LCTL(dir)));
52 }
53
54 default:
55 break;
56 }
57}
58
59const char *spleeb_encoder_mode_string(uint8_t mode) {
60 switch (mode) {
61 case DEF_DPI:
62 return "df dpi";
63 case SNP_DPI:
64 return "sn dpi";
65 case VOL:
66 return "volume";
67 case SEL:
68 return "select";
69 }
70
71 return get_u8_str(mode, ' ');
72}
73
74void pointing_device_init_user(void) {
75 set_auto_mouse_layer(_MOUSE);
76}
77
78const spleeb_enc_mode_t spleeb_encoder_mode_map[NUM_ENCODERS][SPLEEB_ENCODER_MODE_COUNT] = {
79 [0] = {SPLEEB_ENC_MODE(VOL), SPLEEB_ENC_MODE(SEL)},
80 [1] = {SPLEEB_ENC_MODE(DEF_DPI), SPLEEB_ENC_MODE(SNP_DPI), SPLEEB_ENC_MODE(SEL)},
81};
82```
83
84This will enable 4 encoder modes. On the left side there will be modes for volume control and text selection. On the right side there will be three modes to allow controlling the DPI of the Cirque trackpad and also text selection.
85
86## Custom Keycodes
87
88This firmware defines the following custom keycodes for use in keymap.c. Depending on your defines the pointing or encoder specific keymaps will not be included.
89
90```c
91#define DF_MOD POINTER_DEFAULT_DPI_FORWARD
92#define DF_RMOD POINTER_DEFAULT_DPI_REVERSE
93#define SP_MOD POINTER_SNIPING_DPI_FORWARD
94#define SP_RMOD POINTER_SNIPING_DPI_REVERSE
95#define SNIPING SNIPING_MODE
96#define SNP_TOG SNIPING_MODE_TOGGLE
97#define DRGSCRL DRAGSCROLL_MODE
98#define DRG_TOG DRAGSCROLL_MODE_TOGGLE
99#define ENC_STL ENC_MODE_STEP_LEFT
100#define ENC_STR ENC_MODE_STEP_RIGHT
101```
102
103## Bootloader
104
105Enter the bootloader in 3 ways:
106
107* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
108* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
109* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/spleeb/rules.mk b/keyboards/spleeb/rules.mk
new file mode 100644
index 0000000000..161ec22b16
--- /dev/null
+++ b/keyboards/spleeb/rules.mk
@@ -0,0 +1 @@
SERIAL_DRIVER = vendor
diff --git a/keyboards/spleeb/spleeb.c b/keyboards/spleeb/spleeb.c
new file mode 100644
index 0000000000..658f30df75
--- /dev/null
+++ b/keyboards/spleeb/spleeb.c
@@ -0,0 +1,544 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "spleeb.h"
5#include "transactions.h"
6
7#ifdef CONSOLE_ENABLE
8# include "print.h"
9#endif // CONSOLE_ENABLE
10
11#if defined(POINTING_DEVICE_ENABLE) || defined(SPLEEB_ENCODER_MODE_MAP_ENABLE)
12typedef union {
13 uint16_t raw;
14 struct {
15 uint8_t pointer_default_dpi : 4; // 16 steps available.
16 uint8_t pointer_sniping_dpi : 2; // 4 steps available.
17 uint8_t enc_modes[NUM_ENCODERS];
18 bool is_dragscroll_enabled : 1;
19 bool is_sniping_enabled : 1;
20 } __attribute__((packed));
21} spleeb_config_t;
22
23static spleeb_config_t g_spleeb_config = {0};
24
25/**
26 * \brief Set the value of `config` from EEPROM.
27 *
28 * Note that `is_dragscroll_enabled` and `is_sniping_enabled` are purposefully
29 * ignored since we do not want to persist this state to memory. In practice,
30 * this state is always written to maximize write-performances. Therefore, we
31 * explicitly set them to `false` in this function.
32 */
33static void read_spleeb_config_from_eeprom(spleeb_config_t* config) {
34 config->raw = eeconfig_read_kb() & 0xffff;
35 config->is_dragscroll_enabled = false;
36 config->is_sniping_enabled = false;
37}
38
39/**
40 * \brief Save the value of `config` to eeprom.
41 *
42 * Note that all values are written verbatim, including whether drag-scroll
43 * and/or sniper mode are enabled. `read_spleeb_config_from_eeprom(…)`
44 * resets these 2 values to `false` since it does not make sense to persist
45 * these across reboots of the board.
46 */
47static void write_spleeb_config_to_eeprom(spleeb_config_t* config) {
48 eeconfig_update_kb(config->raw);
49}
50
51void eeconfig_init_kb(void) {
52 g_spleeb_config.raw = 0;
53 g_spleeb_config.pointer_default_dpi = 4;
54
55# ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
56 for (size_t i = 0; i < NUM_ENCODERS; i++) {
57 if (spleeb_encoder_mode_map[i][0].initalized) {
58 spleeb_enc_mode_t* first_enc_mode = &spleeb_encoder_mode_map[i][0];
59 g_spleeb_config.enc_modes[i] = first_enc_mode->mode;
60 }
61 }
62# endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
63
64 write_spleeb_config_to_eeprom(&g_spleeb_config);
65 eeconfig_init_user();
66}
67
68void matrix_init_kb(void) {
69 read_spleeb_config_from_eeprom(&g_spleeb_config);
70 matrix_init_user();
71}
72
73void spleeb_config_sync_handler(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
74 if (initiator2target_buffer_size == sizeof(g_spleeb_config)) {
75 memcpy(&g_spleeb_config, initiator2target_buffer, sizeof(g_spleeb_config));
76 }
77}
78
79void keyboard_post_init_kb(void) {
80 transaction_register_rpc(RPC_ID_KB_CONFIG_SYNC, spleeb_config_sync_handler);
81 keyboard_post_init_user();
82}
83
84void housekeeping_task_kb(void) {
85 if (is_keyboard_master()) {
86 // Keep track of the last state, so that we can tell if we need to propagate to slave.
87 static spleeb_config_t last_spleeb_config = {0};
88 static uint32_t last_sync = 0;
89 bool needs_sync = false;
90
91 // Check if the state values are different.
92 if (memcmp(&g_spleeb_config, &last_spleeb_config, sizeof(g_spleeb_config))) {
93 needs_sync = true;
94 memcpy(&last_spleeb_config, &g_spleeb_config, sizeof(g_spleeb_config));
95 }
96 // Send to slave every 500ms regardless of state change.
97 if (timer_elapsed32(last_sync) > 500) {
98 needs_sync = true;
99 }
100
101 // Perform the sync if requested.
102 if (needs_sync) {
103 if (transaction_rpc_send(RPC_ID_KB_CONFIG_SYNC, sizeof(g_spleeb_config), &g_spleeb_config)) {
104 last_sync = timer_read32();
105 }
106 }
107 }
108 // No need to invoke the user-specific callback, as it's been called
109 // already.
110}
111#endif // defined(POINTING_DEVICE_ENABLE) || defined(SPLEEB_ENCODER_MODE_MAP_ENABLE)
112
113#ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
114
115/**
116 * \brief Handle the encoder mode action when triggered by encoder_update_kb
117 *
118 * Weakly defined fuction intended to be overridden in a users keymap
119 */
120__attribute__((weak)) void spleeb_encoder_mode_trigger(uint8_t mode, bool clockwise) {}
121
122typedef struct {
123 uint8_t index;
124 spleeb_enc_mode_t* enc_mode;
125} spleeb_found_enc_mode_t;
126
127static spleeb_found_enc_mode_t spleeb_get_found_encoder_mode(spleeb_config_t* config, uint8_t index) {
128 spleeb_found_enc_mode_t found_enc_mode;
129
130 for (size_t i = 0; i < SPLEEB_ENCODER_MODE_COUNT; i++) {
131 spleeb_enc_mode_t* cur_enc_mode = &spleeb_encoder_mode_map[index][i];
132 if (cur_enc_mode->mode == config->enc_modes[index]) {
133 found_enc_mode.index = i;
134 found_enc_mode.enc_mode = cur_enc_mode;
135 break;
136 }
137 }
138
139 return found_enc_mode;
140}
141
142/**
143 * \brief Step through the defined encoder modes for the encoder at the given
144 * index
145 *
146 * Step though the modes defined in spleeb_encoder_mode_map at the users keymap.
147 * Use a null terminator at the first character on the name property for the
148 * enc_mode struct to determine if we've reached the end of the defined encoder
149 * modes. When this happens loop back to the beginning.
150 */
151static void spleeb_step_encoder_mode(spleeb_config_t* config, uint8_t index) {
152 spleeb_found_enc_mode_t cur_enc_mode = spleeb_get_found_encoder_mode(config, index);
153 spleeb_enc_mode_t* next_enc_mode = &spleeb_encoder_mode_map[index][(cur_enc_mode.index + 1) % SPLEEB_ENCODER_MODE_COUNT];
154
155 if (!next_enc_mode->initalized) {
156 next_enc_mode = &spleeb_encoder_mode_map[index][0];
157 }
158
159 if (next_enc_mode->initalized) {
160 config->enc_modes[index] = next_enc_mode->mode;
161 write_spleeb_config_to_eeprom(config);
162 }
163}
164
165bool encoder_update_kb(uint8_t index, bool clockwise) {
166 if (!encoder_update_user(index, clockwise)) {
167 return false;
168 }
169
170 spleeb_encoder_mode_trigger(g_spleeb_config.enc_modes[index], clockwise);
171
172 return true;
173}
174#endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
175
176#ifdef POINTING_DEVICE_ENABLE
177
178/** \brief Return the current value of the pointer's default DPI. */
179static uint16_t get_pointer_default_dpi(spleeb_config_t* config) {
180 return (uint16_t)config->pointer_default_dpi * SPLEEB_DEFAULT_DPI_CONFIG_STEP + SPLEEB_MINIMUM_DEFAULT_DPI;
181}
182
183/** \brief Return the current value of the pointer's sniper-mode DPI. */
184static uint16_t get_pointer_sniping_dpi(spleeb_config_t* config) {
185 return (uint16_t)config->pointer_sniping_dpi * SPLEEB_SNIPING_DPI_CONFIG_STEP + SPLEEB_MINIMUM_SNIPING_DPI;
186}
187
188/** \brief Return the current value of the pointer's default DPI. */
189static uint16_t get_pointer_current_dpi(spleeb_config_t* config) {
190 if (config->is_sniping_enabled) {
191 return get_pointer_sniping_dpi(config);
192 } else {
193 return get_pointer_default_dpi(config);
194 }
195}
196
197/** \brief Set the appropriate DPI for the input config. */
198static void maybe_update_pointing_device_cpi(spleeb_config_t* config) {
199 if (config->is_sniping_enabled) {
200 pointing_device_set_cpi(get_pointer_sniping_dpi(config));
201 } else {
202 pointing_device_set_cpi(get_pointer_default_dpi(config));
203 }
204}
205
206/**
207 * \brief Update the pointer's default DPI to the next or previous step.
208 *
209 * Increases the DPI value if `forward` is `true`, decreases it otherwise.
210 * The increment/decrement steps are equal to SPLEEB_DEFAULT_DPI_CONFIG_STEP.
211 */
212static void step_pointer_default_dpi(spleeb_config_t* config, bool forward) {
213 config->pointer_default_dpi += forward ? 1 : -1;
214 maybe_update_pointing_device_cpi(config);
215}
216
217/**
218 * \brief Update the pointer's sniper-mode DPI to the next or previous step.
219 *
220 * Increases the DPI value if `forward` is `true`, decreases it otherwise.
221 * The increment/decrement steps are equal to SPLEEB_SNIPING_DPI_CONFIG_STEP.
222 */
223static void step_pointer_sniping_dpi(spleeb_config_t* config, bool forward) {
224 config->pointer_sniping_dpi += forward ? 1 : -1;
225 maybe_update_pointing_device_cpi(config);
226}
227
228uint16_t spleeb_get_pointer_default_dpi(void) {
229 return get_pointer_default_dpi(&g_spleeb_config);
230}
231
232uint16_t spleeb_get_pointer_sniping_dpi(void) {
233 return get_pointer_sniping_dpi(&g_spleeb_config);
234}
235
236void spleeb_cycle_pointer_default_dpi_noeeprom(bool forward) {
237 step_pointer_default_dpi(&g_spleeb_config, forward);
238}
239
240void spleeb_cycle_pointer_default_dpi(bool forward) {
241 step_pointer_default_dpi(&g_spleeb_config, forward);
242 write_spleeb_config_to_eeprom(&g_spleeb_config);
243}
244
245void spleeb_cycle_pointer_sniping_dpi_noeeprom(bool forward) {
246 step_pointer_sniping_dpi(&g_spleeb_config, forward);
247}
248
249void spleeb_cycle_pointer_sniping_dpi(bool forward) {
250 step_pointer_sniping_dpi(&g_spleeb_config, forward);
251 write_spleeb_config_to_eeprom(&g_spleeb_config);
252}
253
254bool spleeb_get_pointer_sniping_enabled(void) {
255 return g_spleeb_config.is_sniping_enabled;
256}
257
258void spleeb_set_pointer_sniping_enabled(bool enable) {
259 g_spleeb_config.is_sniping_enabled = enable;
260 maybe_update_pointing_device_cpi(&g_spleeb_config);
261}
262
263bool spleeb_get_pointer_dragscroll_enabled(void) {
264 return g_spleeb_config.is_dragscroll_enabled;
265}
266
267void spleeb_set_pointer_dragscroll_enabled(bool enable) {
268 g_spleeb_config.is_dragscroll_enabled = enable;
269 cirque_pinnacle_enable_cursor_glide(enable);
270 maybe_update_pointing_device_cpi(&g_spleeb_config);
271}
272#endif // POINTING_DEVICE_ENABLE
273
274#ifdef POINTING_DEVICE_ENABLE
275void pointing_device_init_kb(void) {
276 maybe_update_pointing_device_cpi(&g_spleeb_config);
277
278 // only glide on drag scroll
279 cirque_pinnacle_enable_cursor_glide(false);
280
281 set_auto_mouse_enable(true);
282 pointing_device_init_user();
283}
284
285/**
286 * \brief Augment the pointing device behavior.
287 *
288 * Drag-scroll implementation borrowed from https://github.com/qmk/qmk_firmware/pull/18218
289 */
290static void pointing_device_task_spleeb(report_mouse_t* mouse_report) {
291 static int16_t scroll_x = 0;
292 static int16_t scroll_y = 0;
293 if (g_spleeb_config.is_dragscroll_enabled) {
294 scroll_x -= mouse_report->x;
295 scroll_y += mouse_report->y;
296 mouse_report->h = scroll_x / SPLEEB_DRAGSCROLL_DIVISOR;
297 mouse_report->v = scroll_y / SPLEEB_DRAGSCROLL_DIVISOR;
298 mouse_report->x = 0;
299 mouse_report->y = 0;
300 scroll_x -= (int16_t)mouse_report->h * SPLEEB_DRAGSCROLL_DIVISOR;
301 scroll_y -= (int16_t)mouse_report->v * SPLEEB_DRAGSCROLL_DIVISOR;
302 }
303}
304
305report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
306 if (is_keyboard_master()) {
307 pointing_device_task_spleeb(&mouse_report);
308
309 mouse_report = pointing_device_task_user(mouse_report);
310 }
311
312 return mouse_report;
313}
314
315/**
316 * \brief Outputs the Spleeb configuration to console.
317 *
318 * Prints the in-memory configuration structure to console, for debugging.
319 * Includes:
320 * - raw value
321 * - drag-scroll: on/off
322 * - sniping: on/off
323 * - default DPI: internal table index/actual DPI
324 * - sniping DPI: internal table index/actual DPI
325 */
326static void debug_spleeb_config_to_console(spleeb_config_t* config) {
327# ifdef CONSOLE_ENABLE
328 pd_dprintf("(spleeb) process_record_kb: config = {\n"
329 "\traw = 0x%u,\n"
330 "\t{\n"
331 "\t\tis_dragscroll_enabled=%u\n"
332 "\t\tis_sniping_enabled=%u\n"
333 "\t\tdefault_dpi=0x%X (%u)\n"
334 "\t\tsniping_dpi=0x%X (%u)\n"
335 "\t}\n"
336 "}\n",
337 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));
338# endif // CONSOLE_ENABLE
339}
340#endif // POINTING_DEVICE_ENABLE
341
342bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
343 if (!process_record_user(keycode, record)) {
344#ifdef POINTING_DEVICE_ENABLE
345
346 debug_spleeb_config_to_console(&g_spleeb_config);
347#endif // POINTING_DEVICE_ENABLE
348 return false;
349 }
350#ifdef POINTING_DEVICE_ENABLE
351 switch (keycode) {
352 case POINTER_DEFAULT_DPI_FORWARD:
353 if (record->event.pressed) {
354 spleeb_cycle_pointer_default_dpi(true);
355 }
356 break;
357 case POINTER_DEFAULT_DPI_REVERSE:
358 if (record->event.pressed) {
359 spleeb_cycle_pointer_default_dpi(false);
360 }
361 break;
362 case POINTER_SNIPING_DPI_FORWARD:
363 if (record->event.pressed) {
364 spleeb_cycle_pointer_sniping_dpi(true);
365 }
366 break;
367 case POINTER_SNIPING_DPI_REVERSE:
368 if (record->event.pressed) {
369 spleeb_cycle_pointer_sniping_dpi(false);
370 }
371 break;
372 case SNIPING_MODE:
373 spleeb_set_pointer_sniping_enabled(record->event.pressed);
374 break;
375 case SNIPING_MODE_TOGGLE:
376 if (record->event.pressed) {
377 spleeb_set_pointer_sniping_enabled(!spleeb_get_pointer_sniping_enabled());
378 }
379 break;
380 case DRAGSCROLL_MODE:
381 spleeb_set_pointer_dragscroll_enabled(record->event.pressed);
382 break;
383 case DRAGSCROLL_MODE_TOGGLE:
384 if (record->event.pressed) {
385 spleeb_set_pointer_dragscroll_enabled(!spleeb_get_pointer_dragscroll_enabled());
386 }
387 break;
388 }
389#endif // POINTING_DEVICE_ENABLE
390
391#ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
392 switch (keycode) {
393 case ENC_MODE_STEP_LEFT:
394 if (record->event.pressed) {
395 spleeb_step_encoder_mode(&g_spleeb_config, 0);
396 }
397 break;
398 case ENC_MODE_STEP_RIGHT:
399 if (record->event.pressed) {
400 spleeb_step_encoder_mode(&g_spleeb_config, 1);
401 }
402 break;
403 }
404#endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
405
406#ifdef POINTING_DEVICE_ENABLE
407 if ((keycode >= POINTER_DEFAULT_DPI_FORWARD && keycode <= ENC_MODE_STEP_RIGHT) || IS_MOUSEKEY(keycode)) {
408 debug_spleeb_config_to_console(&g_spleeb_config);
409 }
410#endif // POINTING_DEVICE_ENABLE
411
412 return true;
413}
414
415#ifdef POINTING_DEVICE_ENABLE
416
417bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) {
418 switch (keycode) {
419 case DRAGSCROLL_MODE:
420 case SNIPING_MODE:
421 return true;
422 default:
423 return false;
424 }
425
426 return is_mouse_record_user(keycode, record);
427}
428
429#endif // POINTING_DEVICE_ENABLE
430
431#ifdef OLED_ENABLE
432
433static void render_layer(void) {
434 oled_write_P(PSTR("LAYER: "), false);
435
436 switch (get_highest_layer(layer_state)) {
437 case 0:
438 oled_write_ln_P(PSTR("\xC0\xC1"), false);
439 break;
440 case 1:
441 oled_write_ln_P(PSTR("\xC2\xC3"), false);
442 break;
443 case 2:
444 oled_write_ln_P(PSTR("\xC4\xC5"), false);
445 break;
446 case 3:
447 oled_write_ln_P(PSTR("\xC6\xC7"), false);
448 break;
449 case 4:
450 oled_write_ln_P(PSTR("\xC8\xC9"), false);
451 break;
452 case 5:
453 oled_write_ln_P(PSTR("\xCA\xCB"), false);
454 break;
455 default:
456 oled_write_ln_P(get_u8_str(get_highest_layer(layer_state) + 0x30, ' '), true);
457 }
458
459 oled_write_ln_P("", false);
460}
461
462static void render_mods(void) {
463 uint8_t modifiers = get_mods();
464
465 oled_write_ln_P(PSTR("MODS:"), false);
466 oled_write_ln_P("", false);
467 oled_write_P(PSTR("\325\326"), (modifiers & MOD_MASK_SHIFT));
468 oled_write_P(PSTR("\327\330"), (modifiers & MOD_MASK_CTRL));
469 oled_write_P(PSTR("\331\332"), (modifiers & MOD_MASK_ALT));
470 oled_write_ln_P(PSTR("\333\334"), (modifiers & MOD_MASK_GUI));
471 oled_write_ln_P("", false);
472}
473
474static void render_lock(void) {
475 led_t led_state = host_keyboard_led_state();
476
477 oled_write_P(PSTR("LOCK: "), false);
478 oled_write_P(PSTR("\235\236"), led_state.caps_lock);
479 oled_write_ln_P(PSTR("\275\276"), led_state.num_lock);
480}
481
482static void render_pointer(void) {
483# ifdef POINTING_DEVICE_ENABLE
484 oled_write_ln_P(PSTR("POINTER:"), false);
485 oled_write_ln_P("", false);
486 oled_write_P(PSTR("dpi:"), false);
487 oled_write_ln_P(get_u16_str(get_pointer_current_dpi(&g_spleeb_config), ' '), false);
488 oled_write_ln_P("", false);
489# endif // POINTING_DEVICE_ENABLE
490}
491
492# ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
493static uint8_t spleeb_get_encoder_mode(spleeb_config_t* config, uint8_t index) {
494 spleeb_found_enc_mode_t found_enc_mode = spleeb_get_found_encoder_mode(config, index);
495 return found_enc_mode.enc_mode->mode;
496}
497
498/**
499 * \brief Map an encoder mode to a string to be displayed on the OLED
500 *
501 * Weakly defined fuction intended to be overridden in a users keymap. My be
502 * omitted if no OLED is used.
503 */
504__attribute__((weak)) const char* spleeb_encoder_mode_string(uint8_t mode) {
505 return get_u8_str(mode, ' ');
506}
507# endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
508
509static void render_encoder(void) {
510# ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
511 oled_write_ln_P(PSTR("ENCODER:"), false);
512 oled_write_ln_P("", false);
513 oled_write_P(PSTR("R: "), false);
514 oled_write_ln_P(spleeb_encoder_mode_string(spleeb_get_encoder_mode(&g_spleeb_config, 1)), false);
515 oled_write_P(PSTR("L: "), false);
516 oled_write_ln_P(spleeb_encoder_mode_string(spleeb_get_encoder_mode(&g_spleeb_config, 0)), false);
517# endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
518}
519
520static void render_status(void) {
521 render_layer();
522 render_mods();
523 render_lock();
524 render_pointer();
525 render_encoder();
526}
527
528oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
529 return OLED_ROTATION_90;
530}
531
532bool oled_task_kb(void) {
533 if (is_keyboard_master()) {
534 return false;
535 }
536
537 if (!oled_task_user()) {
538 return false;
539 }
540
541 render_status();
542 return false;
543}
544#endif // OLED_ENABLE
diff --git a/keyboards/spleeb/spleeb.h b/keyboards/spleeb/spleeb.h
new file mode 100644
index 0000000000..67d01cdf35
--- /dev/null
+++ b/keyboards/spleeb/spleeb.h
@@ -0,0 +1,149 @@
1// Copyright 2022 Chris Hoage (@chrishoage)
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "quantum.h"
7
8#if defined(SPLEEB_ENCODER_MODE_MAP_ENABLE) && !defined(ENCODER_ENABLE)
9# error "Encoder must be enabled to use encoder mode map"
10#endif
11
12#if defined(SPLEEB_ENCODER_MODE_MAP_ENABLE) && defined(ENCODER_MAP_ENABLE)
13# error "Encoder mode map can not be used with encoder map"
14#endif
15
16enum spleeb_keycodes {
17 POINTER_DEFAULT_DPI_FORWARD = QK_KB,
18 POINTER_DEFAULT_DPI_REVERSE,
19 POINTER_SNIPING_DPI_FORWARD,
20 POINTER_SNIPING_DPI_REVERSE,
21 SNIPING_MODE,
22 SNIPING_MODE_TOGGLE,
23 DRAGSCROLL_MODE,
24 DRAGSCROLL_MODE_TOGGLE,
25 ENC_MODE_STEP_LEFT,
26 ENC_MODE_STEP_RIGHT,
27};
28
29#define DF_MOD POINTER_DEFAULT_DPI_FORWARD
30#define DF_RMOD POINTER_DEFAULT_DPI_REVERSE
31#define SP_MOD POINTER_SNIPING_DPI_FORWARD
32#define SP_RMOD POINTER_SNIPING_DPI_REVERSE
33#define SNIPING SNIPING_MODE
34#define SNP_TOG SNIPING_MODE_TOGGLE
35#define DRGSCRL DRAGSCROLL_MODE
36#define DRG_TOG DRAGSCROLL_MODE_TOGGLE
37#define ENC_STL ENC_MODE_STEP_LEFT
38#define ENC_STR ENC_MODE_STEP_RIGHT
39
40#ifdef POINTING_DEVICE_ENABLE
41# ifndef SPLEEB_MINIMUM_DEFAULT_DPI
42# define SPLEEB_MINIMUM_DEFAULT_DPI 300
43# endif // SPLEEB_MINIMUM_DEFAULT_DPI
44
45# ifndef SPLEEB_DEFAULT_DPI_CONFIG_STEP
46# define SPLEEB_DEFAULT_DPI_CONFIG_STEP 100
47# endif // SPLEEB_DEFAULT_DPI_CONFIG_STEP
48
49# ifndef SPLEEB_MINIMUM_SNIPING_DPI
50# define SPLEEB_MINIMUM_SNIPING_DPI 100
51# endif // SPLEEB_MINIMUM_SNIPING_DPI
52
53# ifndef SPLEEB_SNIPING_DPI_CONFIG_STEP
54# define SPLEEB_SNIPING_DPI_CONFIG_STEP 100
55# endif // SPLEEB_SNIPING_DPI_CONFIG_STEP
56
57# ifndef SPLEEB_DRAGSCROLL_DIVISOR
58# define SPLEEB_DRAGSCROLL_DIVISOR 64
59# endif // !SPLEEB_DRAGSCROLL_DIVISOR
60#endif // POINTING_DEVICE_ENABLE
61
62#ifdef SPLEEB_ENCODER_MODE_MAP_ENABLE
63# ifndef SPLEEB_ENCODER_MODE_COUNT
64# define SPLEEB_ENCODER_MODE_COUNT 4
65# endif
66
67typedef struct {
68 uint8_t mode;
69 // Discriminate between array members which are (un)initialized
70 bool initalized;
71} const spleeb_enc_mode_t;
72
73const spleeb_enc_mode_t spleeb_encoder_mode_map[NUM_ENCODERS][SPLEEB_ENCODER_MODE_COUNT];
74
75// SPLEEB_ENC_MODE initializes the spleeb_enc_mode_t struct such that
76// uninitialized mode_map members can be discriminated against when looking up
77// mapped encoder modes.
78# define SPLEEB_ENC_MODE(mode) \
79 { mode, true }
80#endif // SPLEEB_ENCODER_MODE_MAP_ENABLE
81
82#ifdef POINTING_DEVICE_ENABLE
83
84/** \brief Return the current DPI value for the pointer's default mode. */
85uint16_t spleeb_get_pointer_default_dpi(void);
86
87/**
88 * \brief Update the pointer's default DPI to the next or previous step.
89 *
90 * Increases the DPI value if `forward` is `true`, decreases it otherwise.
91 * The increment/decrement steps are equal to SPLEEB_DEFAULT_DPI_CONFIG_STEP.
92 *
93 * The new value is persisted in EEPROM.
94 */
95void spleeb_cycle_pointer_default_dpi(bool forward);
96
97/**
98 * \brief Same as `spleeb_cycle_pointer_default_dpi`, but do not write to
99 * EEPROM.
100 *
101 * This means that reseting the board will revert the value to the last
102 * persisted one.
103 */
104void spleeb_cycle_pointer_default_dpi_noeeprom(bool forward);
105
106/** \brief Return the current DPI value for the pointer's sniper-mode. */
107uint16_t spleeb_get_pointer_sniping_dpi(void);
108
109/**
110 * \brief Update the pointer's sniper-mode DPI to the next or previous step.
111 *
112 * Increases the DPI value if `forward` is `true`, decreases it otherwise.
113 * The increment/decrement steps are equal to SPLEEB_SNIPING_DPI_CONFIG_STEP.
114 *
115 * The new value is persisted in EEPROM.
116 */
117void spleeb_cycle_pointer_sniping_dpi(bool forward);
118
119/**
120 * \brief Same as `spleeb_cycle_pointer_sniping_dpi`, but do not write to
121 * EEPROM.
122 *
123 * This means that reseting the board will revert the value to the last
124 * persisted one.
125 */
126void spleeb_cycle_pointer_sniping_dpi_noeeprom(bool forward);
127
128/** \brief Whether sniper-mode is enabled. */
129bool spleeb_get_pointer_sniping_enabled(void);
130
131/**
132 * \brief Enable/disable sniper mode.
133 *
134 * When sniper mode is enabled the dpi is reduced to slow down the pointer for
135 * more accurate movements.
136 */
137void spleeb_set_pointer_sniping_enabled(bool enable);
138
139/** \brief Whether drag-scroll is enabled. */
140bool spleeb_get_pointer_dragscroll_enabled(void);
141
142/**
143 * \brief Enable/disable drag-scroll mode.
144 *
145 * When drag-scroll mode is enabled, horizontal and vertical pointer movements
146 * are translated into horizontal and vertical scroll movements.
147 */
148void spleeb_set_pointer_dragscroll_enabled(bool enable);
149#endif // POINTING_DEVICE_ENABLE