@ -0,0 +1,116 @@ | |||
/* Copyright 2023 Leorize <leorize+oss@disroot.org> | |||
* Copyright 2011 Ben Buxton <bb@cactii.net> | |||
* | |||
* 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 <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "opt_encoder.h" | |||
#include <stdbool.h> | |||
#include <stdint.h> | |||
/* An extremely simple implementation of the encoder: | |||
* | |||
* For read out, the mechanism mimics that of a Schmitt trigger, with | |||
* statically defined high/low thresholds used instead of computing | |||
* one at runtime. | |||
* | |||
* The advantage of this approach is computing less in the decoder | |||
* implementation and allow the state to be measured before the wheel | |||
* moved. | |||
* | |||
* Compared to opt_encoder_simple.c, the use of an intermediary state | |||
* reduces sensitivity and de-sensitize against tiny movements caused | |||
* when lifting finger off the wheel. | |||
* | |||
* For turning decoded values into rotation, an algorithm inspired by | |||
* http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html | |||
* is employed. | |||
*/ | |||
#if !defined(ENCODER_LOW_THRES_A) || !defined(ENCODER_HIGH_THRES_A) | |||
# error "The thresholds for phototransistors A is not defined in config.h" | |||
#endif | |||
#if !defined(ENCODER_LOW_THRES_B) || !defined(ENCODER_HIGH_THRES_B) | |||
# error "The thresholds for phototransistors B is not defined in config.h" | |||
#endif | |||
/* | |||
* Sample values, captured for a Ploopy Mini Trackball | |||
* | |||
* The following min-max values was captured by aggregating data recorded | |||
* when debug_encoder is enabled: | |||
* | |||
* A: min: 0, max: 214 | |||
* B: min: 0, max: 204 | |||
* | |||
* The threshold specified is then defined at the 1/4 and the 3/4 points. | |||
* | |||
* As these values might vary between units, you're encouraged to | |||
* measure your own. | |||
*/ | |||
#if 0 | |||
# define ENCODER_LOW_THRES_A 53 | |||
# define ENCODER_HIGH_THRES_A 161 | |||
# define ENCODER_LOW_THRES_B 52 | |||
# define ENCODER_HIGH_THRES_B 153 | |||
#endif | |||
/* Utilities for composing the encoder state */ | |||
#define MAKE_STATE(HI_A, HI_B) (((uint8_t)((HI_A) & 0x1) << 1) | ((uint8_t)((HI_B) & 0x1))) | |||
#define STATE_A(st) ((st & 0x2) >> 1) | |||
#define STATE_B(st) (st & 0x1) | |||
typedef enum { | |||
START, | |||
DOWN_BEGIN, | |||
UP_BEGIN, | |||
START_MID, | |||
DOWN_BEGIN_MID, | |||
UP_BEGIN_MID, | |||
STATE_MASK = 0xf, /* 0b1111 */ | |||
EMIT_UP = 0x10, | |||
EMIT_UP_MID = EMIT_UP & START_MID, | |||
EMIT_DOWN = 0x80, | |||
EMIT_DOWN_MID = EMIT_DOWN & START_MID, | |||
EMIT_MASK = 0xf0 | |||
} encoder_state_t; | |||
static encoder_state_t state; | |||
static uint8_t encState; | |||
static const uint8_t transitions[] = { | |||
// clang-format off | |||
// START -> 00, 01, 10, 11 | |||
START, DOWN_BEGIN, UP_BEGIN, START_MID, | |||
// DOWN_BEGIN -> 00, 01, 10, 11 | |||
START, DOWN_BEGIN, START, EMIT_DOWN_MID, | |||
// UP_BEGIN -> 00, 01, 10, 11 | |||
START, START, UP_BEGIN, EMIT_UP_MID, | |||
// START_MID -> 00, 01, 10, 11 | |||
START, UP_BEGIN_MID, DOWN_BEGIN_MID, START_MID, | |||
// DOWN_BEGIN_MID -> 00, 01, 10, 11 | |||
EMIT_DOWN, START_MID, DOWN_BEGIN_MID, START_MID, | |||
// UP_BEGIN_MID -> 00, 01, 10, 11 | |||
EMIT_UP, UP_BEGIN_MID, START_MID, START_MID, | |||
// clang-format on | |||
}; | |||
void opt_encoder_init(void) { | |||
state = START; | |||
encState = 0; | |||
} | |||
int8_t opt_encoder_handler(uint16_t encA, uint16_t encB) { | |||
encState = MAKE_STATE((STATE_A(encState) & (encA > ENCODER_LOW_THRES_A)) | (encA > ENCODER_HIGH_THRES_A), (STATE_B(encState) & (encB > ENCODER_LOW_THRES_B)) | (encB > ENCODER_HIGH_THRES_B)); | |||
state = transitions[((state & STATE_MASK) << 2) + encState]; | |||
return state & EMIT_MASK; | |||
} |
@ -1,176 +0,0 @@ | |||
/* Copyright 2023 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* | |||
* 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 "madromys.h" | |||
#ifndef PLOOPY_DPI_OPTIONS | |||
# define PLOOPY_DPI_OPTIONS \ | |||
{ 600, 900, 1200, 1600 } | |||
# ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 1 | |||
# endif | |||
#endif | |||
#ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 0 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_DPI | |||
# define PLOOPY_DRAGSCROLL_DPI 100 // Fixed-DPI Drag Scroll | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_FIXED | |||
# define PLOOPY_DRAGSCROLL_FIXED 1 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_MULTIPLIER | |||
# define PLOOPY_DRAGSCROLL_MULTIPLIER 0.75 // Variable-DPI Drag Scroll | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_SEMAPHORE | |||
# define PLOOPY_DRAGSCROLL_SEMAPHORE 4 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_MOMENTARY | |||
# define PLOOPY_DRAGSCROLL_MOMENTARY 1 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_INVERT | |||
# define PLOOPY_DRAGSCROLL_INVERT 1 | |||
#endif | |||
keyboard_config_t keyboard_config; | |||
uint16_t dpi_array[] = PLOOPY_DPI_OPTIONS; | |||
#define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t)) | |||
// TODO: Implement libinput profiles | |||
// https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html | |||
// Compile time accel selection | |||
// Valid options are ACC_NONE, ACC_LINEAR, ACC_CUSTOM, ACC_QUADRATIC | |||
// Trackball State | |||
bool is_drag_scroll = false; | |||
// drag scroll divisor state | |||
int8_t drag_scroll_x_semaphore = 0; | |||
int8_t drag_scroll_y_semaphore = 0; | |||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { | |||
if (is_drag_scroll) { | |||
int16_t mouse_report_x_temp = mouse_report.x; | |||
int16_t mouse_report_y_temp = mouse_report.y; | |||
int16_t mouse_report_x_calc = 0; | |||
int16_t mouse_report_y_calc = 0; | |||
int16_t valx = (mouse_report_x_temp > 0) ? -1 : 1; | |||
int16_t valy = (mouse_report_y_temp > 0) ? -1 : 1; | |||
while (mouse_report_x_temp != 0) { | |||
mouse_report_x_temp += valx; | |||
drag_scroll_x_semaphore -= valx; | |||
if (abs(drag_scroll_x_semaphore) >= PLOOPY_DRAGSCROLL_SEMAPHORE) { | |||
mouse_report_x_calc -= valx; | |||
drag_scroll_x_semaphore = 0; | |||
} | |||
} | |||
while (mouse_report_y_temp != 0) { | |||
mouse_report_y_temp += valy; | |||
drag_scroll_y_semaphore -= valy; | |||
if (abs(drag_scroll_y_semaphore) >= PLOOPY_DRAGSCROLL_SEMAPHORE) { | |||
mouse_report_y_calc -= valy; | |||
drag_scroll_y_semaphore = 0; | |||
} | |||
} | |||
mouse_report.h = mouse_report_x_calc; | |||
#ifdef PLOOPY_DRAGSCROLL_INVERT | |||
// Invert vertical scroll direction | |||
mouse_report.v = -mouse_report_y_calc; | |||
#else | |||
mouse_report.v = mouse_report_y_calc; | |||
#endif | |||
mouse_report.x = 0; | |||
mouse_report.y = 0; | |||
} | |||
return pointing_device_task_user(mouse_report); | |||
} | |||
bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | |||
if (!process_record_user(keycode, record)) { | |||
return false; | |||
} | |||
if (keycode == DPI_CONFIG && record->event.pressed) { | |||
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
if (keycode == DRAG_SCROLL) { | |||
#ifndef PLOOPY_DRAGSCROLL_MOMENTARY | |||
if (record->event.pressed) | |||
#endif | |||
{ | |||
is_drag_scroll ^= 1; | |||
} | |||
#ifdef PLOOPY_DRAGSCROLL_FIXED | |||
pointing_device_set_cpi(is_drag_scroll ? PLOOPY_DRAGSCROLL_DPI : dpi_array[keyboard_config.dpi_config]); | |||
#else | |||
pointing_device_set_cpi(is_drag_scroll ? (dpi_array[keyboard_config.dpi_config] * PLOOPY_DRAGSCROLL_MULTIPLIER) : dpi_array[keyboard_config.dpi_config]); | |||
#endif | |||
} | |||
return true; | |||
} | |||
// Hardware Setup | |||
void keyboard_pre_init_kb(void) { | |||
// debug_enable = true; | |||
// debug_matrix = true; | |||
// debug_mouse = true; | |||
// debug_encoder = true; | |||
/* Ground all output pins connected to ground. This provides additional | |||
* pathways to ground. If you're messing with this, know this: driving ANY | |||
* of these pins high will cause a short. On the MCU. Ka-blooey. | |||
*/ | |||
const pin_t unused_pins[] = { GP1, GP3, GP4, GP6, GP8, GP10, GP14, GP16, | |||
GP18, GP20, GP22, GP24, GP25, GP26, GP27, GP28, GP29 }; | |||
for (uint8_t i = 0; i < (sizeof(unused_pins) / sizeof(pin_t)); i++) { | |||
setPinOutput(unused_pins[i]); | |||
writePinLow(unused_pins[i]); | |||
} | |||
keyboard_pre_init_user(); | |||
} | |||
void pointing_device_init_kb(void) { pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); } | |||
void eeconfig_init_kb(void) { | |||
keyboard_config.dpi_config = PLOOPY_DPI_DEFAULT; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
eeconfig_init_user(); | |||
} | |||
void matrix_init_kb(void) { | |||
// is safe to just read DPI setting since matrix init | |||
// comes before pointing device init. | |||
keyboard_config.raw = eeconfig_read_kb(); | |||
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | |||
eeconfig_init_kb(); | |||
} | |||
matrix_init_user(); | |||
} |
@ -1,37 +0,0 @@ | |||
/* Copyright 2023 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* | |||
* 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 | |||
#include "quantum.h" | |||
typedef union { | |||
uint32_t raw; | |||
struct { | |||
uint8_t dpi_config; | |||
}; | |||
} keyboard_config_t; | |||
_Static_assert(sizeof(keyboard_config_t) == sizeof(uint32_t), "keyboard_config_t size mismatch compared to EEPROM area"); | |||
extern keyboard_config_t keyboard_config; | |||
extern uint16_t dpi_array[]; | |||
enum ploopy_keycodes { | |||
DPI_CONFIG = QK_KB_0, | |||
DRAG_SCROLL, | |||
}; |
@ -1,27 +0,0 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2020 Ploopy Corporation | |||
* | |||
* 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 QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT(/* Base */ | |||
C(KC_C), KC_BTN1, KC_BTN3, LT(1, KC_BTN2), C(KC_V), KC_BTN4, KC_BTN5, DPI_CONFIG), | |||
[1] = LAYOUT(/* Base */ | |||
_______, DRAG_SCROLL, _______, _______, _______, _______, _______, QK_BOOT), | |||
}; |
@ -1,3 +0,0 @@ | |||
# The Drag Scroll keymap for PloopyCo Mouse | |||
This is a sample keymap showing off what you can do with the custom callback drivers. |
@ -1,49 +0,0 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2020 Ploopy Corporation | |||
* | |||
* 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 | |||
#include "quantum.h" | |||
#include "analog.h" | |||
#include "opt_encoder.h" | |||
// Sensor defs | |||
#define OPT_ENC1 F0 | |||
#define OPT_ENC2 F4 | |||
#define OPT_ENC1_MUX 0 | |||
#define OPT_ENC2_MUX 4 | |||
void process_wheel(void); | |||
typedef union { | |||
uint32_t raw; | |||
struct { | |||
uint8_t dpi_config; | |||
}; | |||
} keyboard_config_t; | |||
extern keyboard_config_t keyboard_config; | |||
extern uint16_t dpi_array[]; | |||
enum ploopy_keycodes { | |||
DPI_CONFIG = QK_KB_0, | |||
DRAG_SCROLL, | |||
}; | |||
bool encoder_update_user(uint8_t index, bool clockwise); | |||
bool encoder_update_kb(uint8_t index, bool clockwise); |
@ -1,21 +1,4 @@ | |||
# Processor frequency | |||
F_CPU = 8000000 | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = no # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
NKRO_ENABLE = no # Enable N-Key Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
AUDIO_ENABLE = no # Audio output | |||
POINTING_DEVICE_ENABLE = yes | |||
POINTING_DEVICE_DRIVER = pmw3360 | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
ANALOG_DRIVER_REQUIRED = yes | |||
SRC += opt_encoder.c |
@ -0,0 +1,12 @@ | |||
OPT_ENCODER_TYPE ?= default | |||
VALID_OPT_ENCODER_TYPES := default simple tiny custom | |||
ifeq ($(filter $(OPT_ENCODER_TYPE),$(VALID_OPT_ENCODER_TYPES)),) | |||
$(call CATASTROPHIC_ERROR,Invalid OPT_ENCODER_TYPE,OPT_ENCODER_TYPE="$(OPT_ENCODER_TYPE)" is not a valid pointing device type) | |||
else | |||
ifneq ($(strip $(OPT_ENCODER_TYPE)), custom) | |||
VPATH += keyboards/ploopyco/common | |||
SRC += opt_encoder_$(strip $(OPT_ENCODER_TYPE)).c | |||
ANALOG_DRIVER_REQUIRED = yes | |||
endif | |||
endif |
@ -0,0 +1,45 @@ | |||
# Ploopyco | |||
* [Mouse](mouse/) | |||
* [Trackball](trackball/) | |||
* [Trackball Mini](trackball_mini/) | |||
* [Trackball Nano](trackball_nano/) | |||
* [Trackball Thumb](trackball_thumb/) | |||
* [Adept/Madromys](manromys/) | |||
# Customizing your PloopyCo Device | |||
There are a number of behavioral settings that you can use to help customize your experience | |||
| | | | | |||
|---------------------------------|-------------------|-----------------------------------------------------------| | |||
| `PLOOPY_IGNORE_SCROLL_CLICK` | *__not_defined__* | Ignores scroll wheel if it is pressed down. | | |||
| `PLOOPY_SCROLL_DEBOUNCE` | `5` | Number of milliseconds between scroll events. | | |||
| `PLOOPY_SCROLL_BUTTON_DEBOUNCE` | `100` | Time to ignore scroll events after pressing scroll wheel. | | |||
## DPI | |||
You can change the DPI/CPI or speed of the trackball by calling `pointing_device_set_cpi` at any time. Additionally, there is a `DPI_CONFIG` macro that will cycle through an array of options for the DPI. This is set to 1200, 1600, and 2400, but can be changed. 1600 is also set to the default. | |||
To configure/set your own array, there are two defines to use, `PLOOPY_DPI_OPTIONS` to set the array, and `PLOOPY_DPI_DEFAULT`. | |||
```c | |||
#define PLOOPY_DPI_OPTIONS { 1200, 1600, 2400 } | |||
#define PLOOPY_DPI_DEFAULT 1 | |||
``` | |||
The `PLOOPY_DPI_OPTIONS` array sets the values that you want to be able to cycle through, and the order they are in. The "default" define lets the firmware know which of these options is the default and should be loaded by default. | |||
The `DPI_CONFIG` macro will cycle through the values in the array, each time you hit it. And it stores this value in persistent memory, so it will load it the next time the device powers up. | |||
## Drag Scroll | |||
Drag Sroll is a custom keycode for the Ploopy devices that allow you to hold or tap a button and have the mouse movement translate into scrolling instead. | |||
Nothing needs to be enabled to use this functionality. Just add the `DRAG_SCROLL` to your keymap. | |||
### Drag Scroll Configuration | |||
* `#define PLOOPY_DRAGSCROLL_MOMENTARY` - Makes the key into a momentary key, rather than a toggle. | |||
* `#define PLOOPY_DRAGSCROLL_DIVISOR_H 8.0` - Sets the horizontal movement divisor to use when drag scroll is enabled. | |||
* `#define PLOOPY_DRAGSCROLL_DIVISOR_V 8.0` - Sets the vertical movement divisor to use when drag scroll is enabled. | |||
* `#define PLOOPY_DRAGSCROLL_INVERT` - This reverses the direction that the scroll is performed. |
@ -1,30 +0,0 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2020 Ploopy Corporation | |||
* | |||
* 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 QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT( /* Base */ | |||
KC_BTN1, KC_BTN3, KC_BTN2, | |||
KC_BTN4, LT(1, KC_BTN5) | |||
), | |||
[1] = LAYOUT( | |||
DRAG_SCROLL, _______, _______, | |||
_______, _______ | |||
) | |||
}; |
@ -1,3 +0,0 @@ | |||
# The Drag Scroll keymap for Ploopyco Trackball | |||
This is a sample keymap showing off what you can do with the custom callback drivers. |
@ -1,23 +1,6 @@ | |||
# Processor frequency | |||
F_CPU = 8000000 | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = no # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
NKRO_ENABLE = no # Enable N-Key Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
AUDIO_ENABLE = no # Audio output | |||
POINTING_DEVICE_ENABLE = yes | |||
POINTING_DEVICE_DRIVER = pmw3360 | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
ANALOG_DRIVER_REQUIRED = yes | |||
SRC += opt_encoder.c | |||
DEFAULT_FOLDER = ploopyco/trackball/rev1_005 |
@ -1,243 +0,0 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2020 Ploopy Corporation | |||
* | |||
* 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 "trackball.h" | |||
#ifndef OPT_DEBOUNCE | |||
# define OPT_DEBOUNCE 5 // (ms) Time between scroll events | |||
#endif | |||
#ifndef SCROLL_BUTT_DEBOUNCE | |||
# define SCROLL_BUTT_DEBOUNCE 100 // (ms) Time between scroll events | |||
#endif | |||
#ifndef OPT_THRES | |||
# define OPT_THRES 150 // (0-1024) Threshold for actication | |||
#endif | |||
#ifndef OPT_SCALE | |||
# define OPT_SCALE 1 // Multiplier for wheel | |||
#endif | |||
#ifndef PLOOPY_DPI_OPTIONS | |||
# define PLOOPY_DPI_OPTIONS \ | |||
{ 1200, 1600, 2400 } | |||
# ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 1 | |||
# endif | |||
#endif | |||
#ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 0 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_DPI | |||
# define PLOOPY_DRAGSCROLL_DPI 100 // Fixed-DPI Drag Scroll | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_MULTIPLIER | |||
# define PLOOPY_DRAGSCROLL_MULTIPLIER 0.75 // Variable-DPI Drag Scroll | |||
#endif | |||
keyboard_config_t keyboard_config; | |||
uint16_t dpi_array[] = PLOOPY_DPI_OPTIONS; | |||
#define DPI_OPTION_SIZE ARRAY_SIZE(dpi_array) | |||
// TODO: Implement libinput profiles | |||
// https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html | |||
// Compile time accel selection | |||
// Valid options are ACC_NONE, ACC_LINEAR, ACC_CUSTOM, ACC_QUADRATIC | |||
// Trackball State | |||
bool is_scroll_clicked = false; | |||
bool BurstState = false; // init burst state for Trackball module | |||
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state | |||
uint16_t lastScroll = 0; // Previous confirmed wheel event | |||
uint16_t lastMidClick = 0; // Stops scrollwheel from being read if it was pressed | |||
uint8_t OptLowPin = OPT_ENC1; | |||
bool debug_encoder = false; | |||
bool is_drag_scroll = false; | |||
bool encoder_update_kb(uint8_t index, bool clockwise) { | |||
if (!encoder_update_user(index, clockwise)) { | |||
return false; | |||
} | |||
#ifdef MOUSEKEY_ENABLE | |||
tap_code(clockwise ? KC_WH_U : KC_WH_D); | |||
#else | |||
report_mouse_t mouse_report = pointing_device_get_report(); | |||
mouse_report.v = clockwise ? 1 : -1; | |||
pointing_device_set_report(mouse_report); | |||
pointing_device_send(); | |||
#endif | |||
return true; | |||
} | |||
void encoder_driver_init(void) { | |||
setPinInput(OPT_ENC1); | |||
setPinInput(OPT_ENC2); | |||
opt_encoder_init(); | |||
} | |||
void encoder_driver_task(void) { | |||
// TODO: Replace this with interrupt driven code, polling is S L O W | |||
// Lovingly ripped from the Ploopy Source | |||
// If the mouse wheel was just released, do not scroll. | |||
if (timer_elapsed(lastMidClick) < SCROLL_BUTT_DEBOUNCE) { | |||
return; | |||
} | |||
// Limit the number of scrolls per unit time. | |||
if (timer_elapsed(lastScroll) < OPT_DEBOUNCE) { | |||
return; | |||
} | |||
// Don't scroll if the middle button is depressed. | |||
if (is_scroll_clicked) { | |||
#ifndef IGNORE_SCROLL_CLICK | |||
return; | |||
#endif | |||
} | |||
lastScroll = timer_read(); | |||
uint16_t p1 = adc_read(OPT_ENC1_MUX); | |||
uint16_t p2 = adc_read(OPT_ENC2_MUX); | |||
if (debug_encoder) dprintf("OPT1: %d, OPT2: %d\n", p1, p2); | |||
int dir = opt_encoder_handler(p1, p2); | |||
if (dir == 0) return; | |||
encoder_queue_event(0, dir == 1); | |||
} | |||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { | |||
if (is_drag_scroll) { | |||
#ifdef PLOOPY_DRAGSCROLL_H_INVERT | |||
// Invert horizontal scroll direction | |||
mouse_report.h = -mouse_report.x; | |||
#else | |||
mouse_report.h = mouse_report.x; | |||
#endif | |||
#ifdef PLOOPY_DRAGSCROLL_INVERT | |||
// Invert vertical scroll direction | |||
mouse_report.v = -mouse_report.y; | |||
#else | |||
mouse_report.v = mouse_report.y; | |||
#endif | |||
mouse_report.x = 0; | |||
mouse_report.y = 0; | |||
} | |||
return pointing_device_task_user(mouse_report); | |||
} | |||
bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | |||
if (true) { | |||
xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); | |||
} | |||
// Update Timer to prevent accidental scrolls | |||
if ((record->event.key.col == 1) && (record->event.key.row == 0)) { | |||
lastMidClick = timer_read(); | |||
is_scroll_clicked = record->event.pressed; | |||
} | |||
if (!process_record_user(keycode, record)) { | |||
return false; | |||
} | |||
if (keycode == DPI_CONFIG && record->event.pressed) { | |||
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
if (keycode == DRAG_SCROLL) { | |||
#ifndef PLOOPY_DRAGSCROLL_MOMENTARY | |||
if (record->event.pressed) | |||
#endif | |||
{ | |||
is_drag_scroll ^= 1; | |||
} | |||
#ifdef PLOOPY_DRAGSCROLL_FIXED | |||
pointing_device_set_cpi(is_drag_scroll ? PLOOPY_DRAGSCROLL_DPI : dpi_array[keyboard_config.dpi_config]); | |||
#else | |||
pointing_device_set_cpi(is_drag_scroll ? (dpi_array[keyboard_config.dpi_config] * PLOOPY_DRAGSCROLL_MULTIPLIER) : dpi_array[keyboard_config.dpi_config]); | |||
#endif | |||
} | |||
/* If Mousekeys is disabled, then use handle the mouse button | |||
* keycodes. This makes things simpler, and allows usage of | |||
* the keycodes in a consistent manner. But only do this if | |||
* Mousekeys is not enable, so it's not handled twice. | |||
*/ | |||
return true; | |||
} | |||
// Hardware Setup | |||
void keyboard_pre_init_kb(void) { | |||
// debug_enable = true; | |||
// debug_matrix = true; | |||
// debug_mouse = true; | |||
// debug_encoder = true; | |||
/* Ground all output pins connected to ground. This provides additional | |||
* pathways to ground. If you're messing with this, know this: driving ANY | |||
* of these pins high will cause a short. On the MCU. Ka-blooey. | |||
*/ | |||
#ifdef UNUSABLE_PINS | |||
const pin_t unused_pins[] = UNUSABLE_PINS; | |||
for (uint8_t i = 0; i < ARRAY_SIZE(unused_pins); i++) { | |||
setPinOutput(unused_pins[i]); | |||
writePinLow(unused_pins[i]); | |||
} | |||
#endif | |||
// This is the debug LED. | |||
#if defined(DEBUG_LED_PIN) | |||
setPinOutput(DEBUG_LED_PIN); | |||
writePin(DEBUG_LED_PIN, debug_enable); | |||
#endif | |||
keyboard_pre_init_user(); | |||
} | |||
void pointing_device_init_kb(void) { | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
void eeconfig_init_kb(void) { | |||
keyboard_config.dpi_config = PLOOPY_DPI_DEFAULT; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
eeconfig_init_user(); | |||
} | |||
void matrix_init_kb(void) { | |||
// is safe to just read DPI setting since matrix init | |||
// comes before pointing device init. | |||
keyboard_config.raw = eeconfig_read_kb(); | |||
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | |||
eeconfig_init_kb(); | |||
} | |||
matrix_init_user(); | |||
} | |||
void keyboard_post_init_kb(void) { | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
keyboard_post_init_user(); | |||
} |
@ -1,66 +0,0 @@ | |||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2020 Ploopy Corporation | |||
* | |||
* 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 QMK_KEYBOARD_H | |||
// used for tracking the state | |||
bool is_drag_scroll = false; | |||
enum custom_keycodes { | |||
DRAG_SCROLL = SAFE_RANGE, | |||
}; | |||
bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
switch (keycode) { | |||
case DRAG_SCROLL: | |||
if (record->event.pressed) { | |||
// this toggles the state each time you tap it | |||
is_drag_scroll ^= 1; | |||
} | |||
break; | |||
} | |||
return true; | |||
} | |||
// The real magic is here. | |||
// This function is called to translate the processed sensor movement | |||
// from the mouse sensor and translates it into x and y movement for | |||
// the mouse report. Normally. So if "drag scroll" is toggled on, | |||
// moving the ball scrolls instead. You could remove the x or y here | |||
// to only scroll in one direction, if you wanted, as well. In fact, | |||
// there is no reason that you need to send this to the mouse report. | |||
// You could have it register a key, instead. | |||
void process_mouse_user(report_mouse_t* mouse_report, int8_t x, int8_t y) { | |||
if (is_drag_scroll) { | |||
mouse_report->h = x; | |||
mouse_report->v = y; | |||
} else { | |||
mouse_report->x = x; | |||
mouse_report->y = y; | |||
} | |||
} | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT( /* Base */ | |||
KC_BTN1, KC_BTN3, KC_BTN2, | |||
KC_BTN4, LT(1, KC_BTN5) | |||
), | |||
[1] = LAYOUT( | |||
DRAG_SCROLL, _______, _______, | |||
_______, _______ | |||
) | |||
}; |
@ -1,5 +0,0 @@ | |||
# The Drag Scroll keymap for the Ploopy Trackball Mini | |||
This is a sample keymap showing off what you can do with the custom callback drivers. | |||
This particular example enables "drag scrolling". The movement of the ball is used to scroll up and down. |
@ -1,20 +1,3 @@ | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = yes # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
NKRO_ENABLE = no # Enable N-Key Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
AUDIO_ENABLE = no # Audio output | |||
POINTING_DEVICE_ENABLE = yes | |||
POINTING_DEVICE_DRIVER = adns5050 | |||
MOUSEKEY_ENABLE = yes # Mouse keys | |||
ANALOG_DRIVER_REQUIRED = yes | |||
SRC += opt_encoder.c | |||
DEFAULT_FOLDER = ploopyco/trackball_mini/rev1_001 |
@ -1,214 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2019 Hiroyuki Okada | |||
* | |||
* 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 "trackball_mini.h" | |||
#include "wait.h" | |||
#include "debug.h" | |||
#ifndef OPT_DEBOUNCE | |||
# define OPT_DEBOUNCE 5 // (ms) Time between scroll events | |||
#endif | |||
#ifndef SCROLL_BUTT_DEBOUNCE | |||
# define SCROLL_BUTT_DEBOUNCE 100 // (ms) Time between scroll events | |||
#endif | |||
#ifndef OPT_THRES | |||
# define OPT_THRES 150 // (0-1024) Threshold for actication | |||
#endif | |||
#ifndef OPT_SCALE | |||
# define OPT_SCALE 1 // Multiplier for wheel | |||
#endif | |||
#ifndef PLOOPY_DPI_OPTIONS | |||
# define PLOOPY_DPI_OPTIONS \ | |||
{ 375, 750, 1375 } | |||
# ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 1 | |||
# endif | |||
#endif | |||
#ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 0 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_DPI | |||
# define PLOOPY_DRAGSCROLL_DPI 375 // Fixed-DPI Drag Scroll | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_MULTIPLIER | |||
# define PLOOPY_DRAGSCROLL_MULTIPLIER 0.75 // Variable-DPI Drag Scroll | |||
#endif | |||
keyboard_config_t keyboard_config; | |||
uint16_t dpi_array[] = PLOOPY_DPI_OPTIONS; | |||
#define DPI_OPTION_SIZE ARRAY_SIZE(dpi_array) | |||
// TODO: Implement libinput profiles | |||
// https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html | |||
// Compile time accel selection | |||
// Valid options are ACC_NONE, ACC_LINEAR, ACC_CUSTOM, ACC_QUADRATIC | |||
// Trackball State | |||
bool is_scroll_clicked = false; | |||
bool BurstState = false; // init burst state for Trackball module | |||
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state | |||
uint16_t lastScroll = 0; // Previous confirmed wheel event | |||
uint16_t lastMidClick = 0; // Stops scrollwheel from being read if it was pressed | |||
uint8_t OptLowPin = OPT_ENC1; | |||
bool debug_encoder = false; | |||
bool is_drag_scroll = false; | |||
bool encoder_update_kb(uint8_t index, bool clockwise) { | |||
if (!encoder_update_user(index, clockwise)) { | |||
return false; | |||
} | |||
#ifdef MOUSEKEY_ENABLE | |||
tap_code(clockwise ? KC_WH_U : KC_WH_D); | |||
#else | |||
report_mouse_t mouse_report = pointing_device_get_report(); | |||
mouse_report.v = clockwise ? 1 : -1; | |||
pointing_device_set_report(mouse_report); | |||
pointing_device_send(); | |||
#endif | |||
return true; | |||
} | |||
void encoder_driver_init(void) { | |||
setPinInput(OPT_ENC1); | |||
setPinInput(OPT_ENC2); | |||
opt_encoder_init(); | |||
} | |||
void encoder_driver_task(void) { | |||
uint16_t p1 = adc_read(OPT_ENC1_MUX); | |||
uint16_t p2 = adc_read(OPT_ENC2_MUX); | |||
if (debug_encoder) dprintf("OPT1: %d, OPT2: %d\n", p1, p2); | |||
int8_t dir = opt_encoder_handler(p1, p2); | |||
// If the mouse wheel was just released, do not scroll. | |||
if (timer_elapsed(lastMidClick) < SCROLL_BUTT_DEBOUNCE) return; | |||
// Limit the number of scrolls per unit time. | |||
if (timer_elapsed(lastScroll) < OPT_DEBOUNCE) return; | |||
// Don't scroll if the middle button is depressed. | |||
if (is_scroll_clicked) { | |||
#ifndef IGNORE_SCROLL_CLICK | |||
return; | |||
#endif | |||
} | |||
if (dir == 0) return; | |||
encoder_queue_event(0, dir == 1); | |||
lastScroll = timer_read(); | |||
} | |||
void pointing_device_init_kb(void) { | |||
// set the DPI. | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { | |||
if (is_drag_scroll) { | |||
mouse_report.h = mouse_report.x; | |||
#ifdef PLOOPY_DRAGSCROLL_INVERT | |||
// Invert vertical scroll direction | |||
mouse_report.v = -mouse_report.y; | |||
#else | |||
mouse_report.v = mouse_report.y; | |||
#endif | |||
mouse_report.x = 0; | |||
mouse_report.y = 0; | |||
} | |||
return pointing_device_task_user(mouse_report); | |||
} | |||
bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | |||
xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); | |||
// Update Timer to prevent accidental scrolls | |||
if ((record->event.key.col == 1) && (record->event.key.row == 0)) { | |||
lastMidClick = timer_read(); | |||
is_scroll_clicked = record->event.pressed; | |||
} | |||
if (!process_record_user(keycode, record)) return false; | |||
if (keycode == DPI_CONFIG && record->event.pressed) { | |||
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
if (keycode == DRAG_SCROLL) { | |||
#ifndef PLOOPY_DRAGSCROLL_MOMENTARY | |||
if (record->event.pressed) | |||
#endif | |||
{ | |||
is_drag_scroll ^= 1; | |||
} | |||
pointing_device_set_cpi(is_drag_scroll ? PLOOPY_DRAGSCROLL_DPI : dpi_array[keyboard_config.dpi_config]); | |||
} | |||
return true; | |||
} | |||
// Hardware Setup | |||
void keyboard_pre_init_kb(void) { | |||
// debug_enable = true; | |||
// debug_matrix = true; | |||
// debug_mouse = true; | |||
// debug_encoder = true; | |||
/* Ground all output pins connected to ground. This provides additional | |||
* pathways to ground. If you're messing with this, know this: driving ANY | |||
* of these pins high will cause a short. On the MCU. Ka-blooey. | |||
*/ | |||
#ifdef UNUSABLE_PINS | |||
const pin_t unused_pins[] = UNUSABLE_PINS; | |||
for (uint8_t i = 0; i < ARRAY_SIZE(unused_pins); i++) { | |||
setPinOutput(unused_pins[i]); | |||
writePinLow(unused_pins[i]); | |||
} | |||
#endif | |||
keyboard_pre_init_user(); | |||
} | |||
void eeconfig_init_kb(void) { | |||
keyboard_config.dpi_config = PLOOPY_DPI_DEFAULT; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
eeconfig_init_user(); | |||
} | |||
void matrix_init_kb(void) { | |||
// is safe to just read DPI setting since matrix init | |||
// comes before pointing device init. | |||
keyboard_config.raw = eeconfig_read_kb(); | |||
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | |||
eeconfig_init_kb(); | |||
} | |||
matrix_init_user(); | |||
} |
@ -1,49 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2019 Hiroyuki Okada | |||
* | |||
* 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 | |||
#include "quantum.h" | |||
#include "analog.h" | |||
#include "opt_encoder.h" | |||
// Sensor defs | |||
#define OPT_ENC1 F0 | |||
#define OPT_ENC2 F4 | |||
#define OPT_ENC1_MUX 0 | |||
#define OPT_ENC2_MUX 4 | |||
void process_wheel(void); | |||
typedef union { | |||
uint32_t raw; | |||
struct { | |||
uint8_t dpi_config; | |||
}; | |||
} keyboard_config_t; | |||
extern keyboard_config_t keyboard_config; | |||
enum ploopy_keycodes { | |||
DPI_CONFIG = QK_KB_0, | |||
DRAG_SCROLL, | |||
}; | |||
bool encoder_update_user(uint8_t index, bool clockwise); | |||
bool encoder_update_kb(uint8_t index, bool clockwise); |
@ -1,167 +0,0 @@ | |||
/* Copyright 2022 Aidan Gauland | |||
* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2019 Hiroyuki Okada | |||
* | |||
* 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 QMK_KEYBOARD_H | |||
#include "print.h" | |||
#define NUM_LOCK_BITMASK 0b01 | |||
#define CAPS_LOCK_BITMASK 0b10 | |||
// World record for fastest index finger tapping is 1092 taps per minute, which | |||
// is 55ms for a single tap. | |||
// https://recordsetter.com/world-record/index-finger-taps-minute/46066 | |||
#define LED_CMD_TIMEOUT 25 | |||
#define DELTA_X_THRESHOLD 60 | |||
#define DELTA_Y_THRESHOLD 15 | |||
typedef enum { | |||
// You could theoretically define 0b00 and send it by having a macro send | |||
// the second tap after LED_CMD_TIMEOUT has elapsed. | |||
// CMD_EXTRA = 0b00, | |||
TG_SCROLL = 0b01, | |||
CYC_DPI = 0b10, | |||
CMD_RESET = 0b11 // CMD_ prefix to avoid clash with QMK macro | |||
} led_cmd_t; | |||
// State | |||
static bool scroll_enabled = false; | |||
static bool num_lock_state = false; | |||
static bool caps_lock_state = false; | |||
static bool in_cmd_window = false; | |||
static int8_t delta_x = 0; | |||
static int8_t delta_y = 0; | |||
typedef struct { | |||
led_cmd_t led_cmd; | |||
uint8_t num_lock_count; | |||
uint8_t caps_lock_count; | |||
} cmd_window_state_t; | |||
// Dummy | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {{{KC_NO}}}; | |||
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { | |||
if (scroll_enabled) { | |||
delta_x += mouse_report.x; | |||
delta_y += mouse_report.y; | |||
if (delta_x > DELTA_X_THRESHOLD) { | |||
mouse_report.h = 1; | |||
delta_x = 0; | |||
} else if (delta_x < -DELTA_X_THRESHOLD) { | |||
mouse_report.h = -1; | |||
delta_x = 0; | |||
} | |||
if (delta_y > DELTA_Y_THRESHOLD) { | |||
mouse_report.v = -1; | |||
delta_y = 0; | |||
} else if (delta_y < -DELTA_Y_THRESHOLD) { | |||
mouse_report.v = 1; | |||
delta_y = 0; | |||
} | |||
mouse_report.x = 0; | |||
mouse_report.y = 0; | |||
} | |||
return mouse_report; | |||
} | |||
void keyboard_post_init_user(void) { | |||
num_lock_state = host_keyboard_led_state().num_lock; | |||
caps_lock_state = host_keyboard_led_state().caps_lock; | |||
} | |||
uint32_t command_timeout(uint32_t trigger_time, void *cb_arg) { | |||
cmd_window_state_t *cmd_window_state = (cmd_window_state_t *)cb_arg; | |||
# ifdef CONSOLE_ENABLE | |||
uprintf("Received command 0b%02b (", cmd_window_state->led_cmd); | |||
# endif | |||
switch (cmd_window_state->led_cmd) { | |||
case TG_SCROLL: | |||
# ifdef CONSOLE_ENABLE | |||
uprint("TG_SCROLL)\n"); | |||
# endif | |||
scroll_enabled = !scroll_enabled; | |||
break; | |||
case CYC_DPI: | |||
# ifdef CONSOLE_ENABLE | |||
uprint("CYC_DPI)\n"); | |||
# endif | |||
cycle_dpi(); | |||
break; | |||
case CMD_RESET: | |||
# ifdef CONSOLE_ENABLE | |||
uprint("QK_BOOT)\n"); | |||
# endif | |||
reset_keyboard(); | |||
break; | |||
default: | |||
# ifdef CONSOLE_ENABLE | |||
uprint("unknown)\n"); | |||
# endif | |||
// Ignore unrecognised commands. | |||
break; | |||
} | |||
cmd_window_state->led_cmd = 0; | |||
cmd_window_state->num_lock_count = 0; | |||
cmd_window_state->caps_lock_count = 0; | |||
in_cmd_window = false; | |||
return 0; // Don't repeat | |||
} | |||
bool led_update_user(led_t led_state) { | |||
static cmd_window_state_t cmd_window_state = { | |||
.led_cmd = 0b00, | |||
.num_lock_count = 0, | |||
.caps_lock_count = 0 | |||
}; | |||
// Start timer to end command window if we are not already in the middle of | |||
// one. | |||
if (!in_cmd_window) { | |||
in_cmd_window = true; | |||
defer_exec(LED_CMD_TIMEOUT, command_timeout, &cmd_window_state); | |||
} | |||
// Set num lock and caps lock bits when each is toggled on and off within | |||
// the window. | |||
if (led_state.num_lock != num_lock_state) { | |||
cmd_window_state.num_lock_count++; | |||
if (cmd_window_state.num_lock_count == 2) { | |||
cmd_window_state.led_cmd |= NUM_LOCK_BITMASK; | |||
cmd_window_state.num_lock_count = 0; | |||
} | |||
} | |||
if (led_state.caps_lock != caps_lock_state) { | |||
cmd_window_state.caps_lock_count++; | |||
if (cmd_window_state.caps_lock_count == 2) { | |||
cmd_window_state.led_cmd |= CAPS_LOCK_BITMASK; | |||
cmd_window_state.caps_lock_count = 0; | |||
} | |||
} | |||
// Keep our copy of the LED states in sync with the host. | |||
num_lock_state = led_state.num_lock; | |||
caps_lock_state = led_state.caps_lock; | |||
return true; | |||
} |
@ -1,2 +0,0 @@ | |||
# The keymap that takes commands as LED-Key BitMasks (lkbm) | |||
Based on [maddie](../maddie), this keymap lets you send a 2-bit command by having a macro on your keyboard tap `KC_NUM_LOCK` and `KC_CAPS_LOCK` on and off within a very short window (25ms by default) to represent bits 1 and 2 respectively. The keymap uses this to allow toggling between sending mouse-movement events and scrolling events; cycling DPI presets, and resetting to the bootloader, so you can reflash without having to unscrew your Ploopy Nano. |
@ -1 +0,0 @@ | |||
DEFERRED_EXEC_ENABLE = yes |
@ -1,16 +1,3 @@ | |||
# Build Options | |||
# change yes to no to disable | |||
# | |||
BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite | |||
EXTRAKEY_ENABLE = yes # Audio control and System control | |||
CONSOLE_ENABLE = yes # Console for debug | |||
COMMAND_ENABLE = no # Commands for debug and configuration | |||
NKRO_ENABLE = no # Enable N-Key Rollover | |||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | |||
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow | |||
AUDIO_ENABLE = no # Audio output | |||
POINTING_DEVICE_ENABLE = yes | |||
POINTING_DEVICE_DRIVER = adns5050 | |||
MOUSEKEY_ENABLE = no # Mouse keys | |||
DEFAULT_FOLDER = ploopyco/trackball_nano/rev1_001 |
@ -1,115 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2019 Hiroyuki Okada | |||
* | |||
* 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 "trackball_nano.h" | |||
#include "wait.h" | |||
#ifndef OPT_DEBOUNCE | |||
# define OPT_DEBOUNCE 5 // (ms) Time between scroll events | |||
#endif | |||
#ifndef SCROLL_BUTT_DEBOUNCE | |||
# define SCROLL_BUTT_DEBOUNCE 100 // (ms) Time between scroll events | |||
#endif | |||
#ifndef OPT_THRES | |||
# define OPT_THRES 150 // (0-1024) Threshold for actication | |||
#endif | |||
#ifndef OPT_SCALE | |||
# define OPT_SCALE 1 // Multiplier for wheel | |||
#endif | |||
#ifndef PLOOPY_DPI_OPTIONS | |||
# define PLOOPY_DPI_OPTIONS \ | |||
{ 375, 750, 1375 } | |||
# ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 2 | |||
# endif | |||
#endif | |||
#ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 2 | |||
#endif | |||
keyboard_config_t keyboard_config; | |||
uint16_t dpi_array[] = PLOOPY_DPI_OPTIONS; | |||
#define DPI_OPTION_SIZE ARRAY_SIZE(dpi_array) | |||
void cycle_dpi(void) { | |||
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
#ifdef CONSOLE_ENABLE | |||
uprintf("DPI is now %d\n", dpi_array[keyboard_config.dpi_config]); | |||
#endif | |||
} | |||
// TODO: Implement libinput profiles | |||
// https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html | |||
// Compile time accel selection | |||
// Valid options are ACC_NONE, ACC_LINEAR, ACC_CUSTOM, ACC_QUADRATIC | |||
// Trackball State | |||
bool is_scroll_clicked = false; | |||
bool BurstState = false; // init burst state for Trackball module | |||
uint16_t MotionStart = 0; // Timer for accel, 0 is resting state | |||
void pointing_device_init_kb(void) { | |||
// set the DPI. | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
// Hardware Setup | |||
void keyboard_pre_init_kb(void) { | |||
// debug_enable = true; | |||
// debug_matrix = true; | |||
// debug_mouse = true; | |||
// debug_encoder = true; | |||
/* Ground all output pins connected to ground. This provides additional | |||
* pathways to ground. If you're messing with this, know this: driving ANY | |||
* of these pins high will cause a short. On the MCU. Ka-blooey. | |||
*/ | |||
#ifdef UNUSABLE_PINS | |||
const pin_t unused_pins[] = UNUSABLE_PINS; | |||
for (uint8_t i = 0; i < ARRAY_SIZE(unused_pins); i++) { | |||
setPinOutput(unused_pins[i]); | |||
writePinLow(unused_pins[i]); | |||
} | |||
#endif | |||
keyboard_pre_init_user(); | |||
} | |||
void eeconfig_init_kb(void) { | |||
keyboard_config.dpi_config = PLOOPY_DPI_DEFAULT; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
eeconfig_init_user(); | |||
} | |||
void matrix_init_kb(void) { | |||
// is safe to just read DPI setting since matrix init | |||
// comes before pointing device init. | |||
keyboard_config.raw = eeconfig_read_kb(); | |||
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | |||
eeconfig_init_kb(); | |||
} | |||
matrix_init_user(); | |||
} |
@ -1,37 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* Copyright 2019 Hiroyuki Okada | |||
* | |||
* 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 | |||
#include "quantum.h" | |||
typedef union { | |||
uint32_t raw; | |||
struct { | |||
uint8_t dpi_config; | |||
}; | |||
} keyboard_config_t; | |||
extern keyboard_config_t keyboard_config; | |||
enum ploopy_keycodes { | |||
DPI_CONFIG = QK_KB_0, | |||
}; | |||
void cycle_dpi(void); |
@ -1,30 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* | |||
* 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 QMK_KEYBOARD_H | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[0] = LAYOUT( /* Base */ | |||
KC_BTN4, KC_BTN1, KC_BTN3, KC_BTN2, KC_BTN5, | |||
MO(1) | |||
), | |||
[1] = LAYOUT( | |||
_______, _______, _______, _______, _______, | |||
DRAG_SCROLL | |||
) | |||
}; |
@ -1,3 +0,0 @@ | |||
# The Drag Scroll keymap for Ploopyco Thumb Trackball | |||
This is a sample keymap showing off what you can do with the custom callback drivers. |
@ -1 +1,2 @@ | |||
VIA_ENABLE = yes | |||
LTO_ENABLE = yes |
@ -1,225 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* | |||
* 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 "trackball_thumb.h" | |||
#include "encoder.h" | |||
#ifndef OPT_DEBOUNCE | |||
# define OPT_DEBOUNCE 5 // (ms) Time between scroll events | |||
#endif | |||
#ifndef SCROLL_BUTT_DEBOUNCE | |||
# define SCROLL_BUTT_DEBOUNCE 100 // (ms) Time between scroll events | |||
#endif | |||
#ifndef PLOOPY_DPI_OPTIONS | |||
# define PLOOPY_DPI_OPTIONS \ | |||
{ 600, 900, 1200, 1600 } | |||
# ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 1 | |||
# endif | |||
#endif | |||
#ifndef PLOOPY_DPI_DEFAULT | |||
# define PLOOPY_DPI_DEFAULT 0 | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_DPI | |||
# define PLOOPY_DRAGSCROLL_DPI 100 // Fixed-DPI Drag Scroll | |||
#endif | |||
#ifndef PLOOPY_DRAGSCROLL_MULTIPLIER | |||
# define PLOOPY_DRAGSCROLL_MULTIPLIER 0.75 // Variable-DPI Drag Scroll | |||
#endif | |||
keyboard_config_t keyboard_config; | |||
uint16_t dpi_array[] = PLOOPY_DPI_OPTIONS; | |||
#define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t)) | |||
// TODO: Implement libinput profiles | |||
// https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html | |||
// Compile time accel selection | |||
// Valid options are ACC_NONE, ACC_LINEAR, ACC_CUSTOM, ACC_QUADRATIC | |||
// Trackball State | |||
bool is_scroll_clicked = false; | |||
uint16_t last_scroll = 0; // Previous confirmed wheel event | |||
uint16_t last_mid_click = 0; // Stops scrollwheel from being read if it was pressed; | |||
bool debug_encoder = false; | |||
bool is_drag_scroll = false; | |||
bool encoder_update_kb(uint8_t index, bool clockwise) { | |||
if (!encoder_update_user(index, clockwise)) { | |||
return false; | |||
} | |||
#ifdef MOUSEKEY_ENABLE | |||
tap_code(clockwise ? KC_WH_U : KC_WH_D); | |||
#else | |||
report_mouse_t mouse_report = pointing_device_get_report(); | |||
mouse_report.v = clockwise ? 1 : -1; | |||
pointing_device_set_report(mouse_report); | |||
pointing_device_send(); | |||
#endif | |||
return true; | |||
} | |||
void encoder_driver_init(void) { opt_encoder_init(); } | |||
void encoder_driver_task(void) { | |||
// Lovingly ripped from the Ploopy Source | |||
// If the mouse wheel was just released, do not scroll. | |||
if (timer_elapsed(last_mid_click) < SCROLL_BUTT_DEBOUNCE) { | |||
return; | |||
} | |||
// Limit the number of scrolls per unit time. | |||
if (timer_elapsed(last_scroll) < OPT_DEBOUNCE) { | |||
return; | |||
} | |||
// Don't scroll if the middle button is depressed. | |||
if (is_scroll_clicked) { | |||
#ifndef IGNORE_SCROLL_CLICK | |||
return; | |||
#endif | |||
} | |||
last_scroll = timer_read(); | |||
uint16_t p1 = adc_read(OPT_ENC1_MUX); | |||
uint16_t p2 = adc_read(OPT_ENC2_MUX); | |||
if (debug_encoder) dprintf("OPT1: %d, OPT2: %d\n", p1, p2); | |||
int dir = opt_encoder_handler(p1, p2); | |||
if (dir == 0) return; | |||
encoder_queue_event(0, dir == 1); | |||
} | |||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { | |||
if (is_drag_scroll) { | |||
mouse_report.h = mouse_report.x; | |||
#ifdef PLOOPY_DRAGSCROLL_INVERT | |||
// Invert vertical scroll direction | |||
mouse_report.v = -mouse_report.y; | |||
#else | |||
mouse_report.v = mouse_report.y; | |||
#endif | |||
mouse_report.x = 0; | |||
mouse_report.y = 0; | |||
} | |||
return pointing_device_task_user(mouse_report); | |||
} | |||
bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | |||
// Update Timer to prevent accidental scrolls | |||
if ((record->event.key.col == 1) && (record->event.key.row == 0)) { | |||
last_mid_click = timer_read(); | |||
is_scroll_clicked = record->event.pressed; | |||
} | |||
if (!process_record_user(keycode, record)) { | |||
return false; | |||
} | |||
if (keycode == DPI_CONFIG && record->event.pressed) { | |||
keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); | |||
} | |||
if (keycode == DRAG_SCROLL) { | |||
#ifndef PLOOPY_DRAGSCROLL_MOMENTARY | |||
if (record->event.pressed) | |||
#endif | |||
{ | |||
is_drag_scroll ^= 1; | |||
} | |||
#ifdef PLOOPY_DRAGSCROLL_FIXED | |||
pointing_device_set_cpi(is_drag_scroll ? PLOOPY_DRAGSCROLL_DPI : dpi_array[keyboard_config.dpi_config]); | |||
#else | |||
pointing_device_set_cpi(is_drag_scroll ? (dpi_array[keyboard_config.dpi_config] * PLOOPY_DRAGSCROLL_MULTIPLIER) : dpi_array[keyboard_config.dpi_config]); | |||
#endif | |||
} | |||
/* If Mousekeys is disabled, then use handle the mouse button | |||
* keycodes. This makes things simpler, and allows usage of | |||
* the keycodes in a consistent manner. But only do this if | |||
* Mousekeys is not enable, so it's not handled twice. | |||
*/ | |||
#ifndef MOUSEKEY_ENABLE | |||
if (IS_MOUSEKEY_BUTTON(keycode)) { | |||
report_mouse_t currentReport = pointing_device_get_report(); | |||
if (record->event.pressed) { | |||
currentReport.buttons |= 1 << (keycode - KC_MS_BTN1); | |||
} else { | |||
currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1)); | |||
} | |||
pointing_device_set_report(currentReport); | |||
pointing_device_send(); | |||
} | |||
#endif | |||
return true; | |||
} | |||
// Hardware Setup | |||
void keyboard_pre_init_kb(void) { | |||
// debug_enable = true; | |||
// debug_matrix = true; | |||
// debug_mouse = true; | |||
// debug_encoder = true; | |||
setPinInput(OPT_ENC1); | |||
setPinInput(OPT_ENC2); | |||
/* Ground all output pins connected to ground. This provides additional | |||
* pathways to ground. If you're messing with this, know this: driving ANY | |||
* of these pins high will cause a short. On the MCU. Ka-blooey. | |||
*/ | |||
#ifdef UNUSABLE_PINS | |||
const pin_t unused_pins[] = UNUSABLE_PINS; | |||
for (uint8_t i = 0; i < (sizeof(unused_pins) / sizeof(pin_t)); i++) { | |||
setPinOutput(unused_pins[i]); | |||
writePinLow(unused_pins[i]); | |||
} | |||
#endif | |||
// This is the debug LED. | |||
#if defined(DEBUG_LED_PIN) | |||
setPinOutput(DEBUG_LED_PIN); | |||
writePin(DEBUG_LED_PIN, debug_enable); | |||
#endif | |||
keyboard_pre_init_user(); | |||
} | |||
void pointing_device_init_kb(void) { pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]); } | |||
void eeconfig_init_kb(void) { | |||
keyboard_config.dpi_config = PLOOPY_DPI_DEFAULT; | |||
eeconfig_update_kb(keyboard_config.raw); | |||
eeconfig_init_user(); | |||
} | |||
void matrix_init_kb(void) { | |||
// is safe to just read DPI setting since matrix init | |||
// comes before pointing device init. | |||
keyboard_config.raw = eeconfig_read_kb(); | |||
if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | |||
eeconfig_init_kb(); | |||
} | |||
matrix_init_user(); | |||
} |
@ -1,45 +0,0 @@ | |||
/* Copyright 2021 Colin Lam (Ploopy Corporation) | |||
* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> | |||
* Copyright 2019 Sunjun Kim | |||
* | |||
* 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 | |||
#include "quantum.h" | |||
#include "analog.h" | |||
#include "opt_encoder.h" | |||
// Sensor defs | |||
#define OPT_ENC1 F4 | |||
#define OPT_ENC2 F0 | |||
#define OPT_ENC1_MUX 4 | |||
#define OPT_ENC2_MUX 0 | |||
typedef union { | |||
uint32_t raw; | |||
struct { | |||
uint8_t dpi_config; | |||
}; | |||
} keyboard_config_t; | |||
_Static_assert(sizeof(keyboard_config_t) == sizeof(uint32_t), "keyboard_config_t size mismatch compared to EEPROM area"); | |||
extern keyboard_config_t keyboard_config; | |||
extern uint16_t dpi_array[]; | |||
enum ploopy_keycodes { | |||
DPI_CONFIG = QK_KB_0, | |||
DRAG_SCROLL, | |||
}; |