Skip to content

Commit

Permalink
Add Ploopy Madromys mouse (qmk#21989)
Browse files Browse the repository at this point in the history
Added PloopyCo madromys/adept mouse
Co-authored-by: Drashna Jaelre <drashna@live.com>
  • Loading branch information
ploopyco authored and evantravers committed Nov 17, 2023
1 parent 82e4bda commit c009077
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 0 deletions.
29 changes: 29 additions & 0 deletions keyboards/ploopyco/madromys/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* 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

// #define ROTATIONAL_TRANSFORM_ANGLE 0
#define POINTING_DEVICE_INVERT_Y

/* PMW3360 Settings */
#define PMW33XX_LIFTOFF_DISTANCE 0x00
#define PMW33XX_CS_PIN GP5
#define SPI_SCK_PIN GP2
#define SPI_MISO_PIN GP0
#define SPI_MOSI_PIN GP7
35 changes: 35 additions & 0 deletions keyboards/ploopyco/madromys/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"keyboard_name": "Ploopy Adept Trackball",
"url": "www.ploopy.co",
"maintainer": "ploopyco",
"manufacturer": "Ploopy Corporation",
"processor": "RP2040",
"bootloader": "rp2040",
"usb": {
"vid": "0x5043",
"pid": "0x5C47",
"max_power": 100
},
"features": {
"bootmagic": true,
"extrakey": true,
"mousekey": true,
"nkro": true,
"pointing_device": true,
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [0, 1], "label":"Top Left Left", "x":0, "y":0, "h":2},
{"matrix": [0, 2], "label":"Top Left", "x":1.25, "y":0, "h":1.25},
{"matrix": [0, 3], "label":"Top Right", "x":2.5, "y":0, "h":1.25},
{"matrix": [0, 4], "label":"Top Right Right", "x":3.75, "y":0, "h":2},
{"matrix": [0, 0], "label":"Bottom Left", "x":0, "y":2.25, "w":1.75, "h":2},
{"matrix": [0, 5], "label":"Bottom Right", "x":3, "y":2.25, "w":1.75, "h":2}
]
}
},
"dynamic_keymap": {
"layer_count": 8
},
}
22 changes: 22 additions & 0 deletions keyboards/ploopyco/madromys/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* 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 QMK_KEYBOARD_H

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT( KC_BTN4, KC_BTN5, DRAG_SCROLL, KC_BTN2, KC_BTN1, KC_BTN3 )
};
22 changes: 22 additions & 0 deletions keyboards/ploopyco/madromys/keymaps/via/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* 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 QMK_KEYBOARD_H

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT( KC_BTN4, KC_BTN5, DRAG_SCROLL, KC_BTN2, KC_BTN1, KC_BTN3 )
};
1 change: 1 addition & 0 deletions keyboards/ploopyco/madromys/keymaps/via/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the VIA keymap for Ploopyco Madromys Trackball, which can be used to customise the key layout. See [the VIA online app](https://usevia.app/) for how to do this.
1 change: 1 addition & 0 deletions keyboards/ploopyco/madromys/keymaps/via/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VIA_ENABLE = yes
176 changes: 176 additions & 0 deletions keyboards/ploopyco/madromys/madromys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* 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();
}
37 changes: 37 additions & 0 deletions keyboards/ploopyco/madromys/madromys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* 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,
};
43 changes: 43 additions & 0 deletions keyboards/ploopyco/madromys/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

# Ploopyco Madromys Trackball

It's a DIY, QMK-powered trackball!

* Keyboard Maintainer: [PloopyCo](https://github.com/ploopyco)
* Hardware Supported: RP2040
* Hardware Availability: [Store](https://ploopy.co), [GitHub](https://github.com/ploopyco)

Make example for this keyboard (after setting up your build environment):

qmk compile -kb ploopyco/madromys -km default

# Building Firmware

See 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).

# Triggering the Bootloader

[Do you see those two golden holes in the board](https://ploopy.co/wp-content/uploads/2023/11/boot.jpg)? Those are called **vias**. They act exactly like a switch does. Right now, that switch is OFF. However, if you take a paperclip or a pair of metal tweezers and touch those two vias, the two vias will form an electrical connection. Effectively, that switch turns ON.

Go ahead and connect the two vias, and then (while the vias are connected) plug in the Madromys board into your computer.

The computer should recognise that a mass storage device was just plugged in. Once this is done, you should be able to drag and drop files onto the Madromys board, as if the board was a USB drive. Feel free to remove the tweezers or paperclip at this point.

If you want to upload a new firmware file (a ".uf2" file, like "madromys_awesome_version.uf2" or something), just drag it into the folder, and it'll automatically install on the Madromys board and restart itself, in normal operating mode. You're done!

**TIP**: If your firmware is in some kind of strange state and uploading new firmware isn't fixing it, try uploading [a flash nuke](https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython#flash-resetting-uf2-3083182) to the Madromys board before flashing the new firmware. It wipes the memory of the Madromys board completely clean, which can help clear a few types of errors.

# Drag Scroll

Drag Scroll is a custom keycode for Ploopy devices that allows 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; it's enabled on Madromys by default.

### Drag Scroll Configuration

* `#define PLOOPY_DRAGSCROLL_MOMENTARY` - Makes the key into a momentary key, rather than a toggle.
* `#define PLOOPY_DRAGSCROLL_MULTIPLIER 0.75` - Sets the DPI multiplier to use when drag scroll is enabled.
* `#define PLOOPY_DRAGSCROLL_FIXED` - Normally, when activating Drag Scroll, it uses a fraction of the current DPI. You can define this to use a specific, set DPI rather than a fraction of the current DPI.
* `#define PLOOPY_DRAGSCROLL_DPI 100` - When the fixed DPI option is enabled, this sets the DPI to be used for Drag Scroll.
* `#define PLOOPY_DRAGSCROLL_INVERT` - This reverses the direction that the scroll is performed.
* `#define PLOOPY_DRAGSCROLL_SEMAPHORE` - This is a divisor on the drag scroll sensitivity. The default is 0, which means that the drag scroll is at maximum sensitivity. A value of 4 would mean that the drag scroll is 4 times less sensitive.
Loading

0 comments on commit c009077

Please sign in to comment.