aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/sensors/adns5050.c (renamed from keyboards/ploopyco/adns5050.c)10
-rw-r--r--drivers/sensors/adns5050.h (renamed from keyboards/ploopyco/adns5050.h)0
-rw-r--r--drivers/sensors/adns9800.c (renamed from keyboards/oddball/adns/adns.c)2
-rw-r--r--drivers/sensors/adns9800.h (renamed from keyboards/oddball/adns/adns.h)0
-rw-r--r--drivers/sensors/adns9800_srom_A6.h (renamed from keyboards/oddball/adns/adns9800_srom_A6.h)0
-rw-r--r--drivers/sensors/pimoroni_trackball.c (renamed from keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.c)55
-rw-r--r--drivers/sensors/pimoroni_trackball.h (renamed from users/drashna/pimoroni_trackball.h)0
-rw-r--r--drivers/sensors/pmw3360.c (renamed from keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c)42
-rw-r--r--drivers/sensors/pmw3360.h (renamed from keyboards/ploopyco/pmw3360.h)1
-rw-r--r--drivers/sensors/pmw3360_firmware.h (renamed from keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360_firmware.h)0
-rw-r--r--keyboards/draculad/keymaps/pimoroni/keymap.c2
-rw-r--r--keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.h35
-rw-r--r--keyboards/draculad/keymaps/pimoroni/rules.mk2
-rw-r--r--keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h2
-rw-r--r--keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h103
-rw-r--r--keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk2
-rw-r--r--keyboards/oddball/optical_sensor/optical_sensor.h2
-rw-r--r--keyboards/oddball/rules.mk2
-rw-r--r--keyboards/ploopyco/mouse/mouse.h2
-rw-r--r--keyboards/ploopyco/mouse/rules.mk2
-rw-r--r--keyboards/ploopyco/pmw3360.c218
-rw-r--r--keyboards/ploopyco/pmw3360_firmware.h300
-rw-r--r--keyboards/ploopyco/trackball/rules.mk2
-rw-r--r--keyboards/ploopyco/trackball/trackball.h2
-rw-r--r--keyboards/ploopyco/trackball_mini/rules.mk2
-rw-r--r--keyboards/ploopyco/trackball_mini/trackball_mini.h2
-rw-r--r--keyboards/ploopyco/trackball_nano/rules.mk2
-rw-r--r--keyboards/ploopyco/trackball_nano/trackball_nano.h2
-rw-r--r--layouts/community/ergodox/drashna/config.h1
-rw-r--r--users/drashna/drashna.h2
-rw-r--r--users/drashna/pimoroni_trackball.c151
-rw-r--r--users/drashna/rules.mk2
32 files changed, 60 insertions, 890 deletions
diff --git a/keyboards/ploopyco/adns5050.c b/drivers/sensors/adns5050.c
index fcf2f213e..3c4f5e258 100644
--- a/keyboards/ploopyco/adns5050.c
+++ b/drivers/sensors/adns5050.c
@@ -19,20 +19,16 @@
19 19
20 20
21#include "adns5050.h" 21#include "adns5050.h"
22#include "quantum.h"
23#include "wait.h" 22#include "wait.h"
24 23#include "debug.h"
25#ifdef CONSOLE_ENABLE 24#include "print.h"
26# include "print.h" 25#include "gpio.h"
27#endif
28 26
29#ifndef OPTIC_ROTATED 27#ifndef OPTIC_ROTATED
30# define OPTIC_ROTATED false 28# define OPTIC_ROTATED false
31#endif 29#endif
32 30
33// Definitions for the ADNS serial line. 31// Definitions for the ADNS serial line.
34// These really ought to be defined in your config.h, but defaults are
35// here if you're really lazy.
36#ifndef ADNS_SCLK_PIN 32#ifndef ADNS_SCLK_PIN
37# define ADNS_SCLK_PIN B7 33# define ADNS_SCLK_PIN B7
38#endif 34#endif
diff --git a/keyboards/ploopyco/adns5050.h b/drivers/sensors/adns5050.h
index ff8e8f78e..ff8e8f78e 100644
--- a/keyboards/ploopyco/adns5050.h
+++ b/drivers/sensors/adns5050.h
diff --git a/keyboards/oddball/adns/adns.c b/drivers/sensors/adns9800.c
index 9338808ff..36213179f 100644
--- a/keyboards/oddball/adns/adns.c
+++ b/drivers/sensors/adns9800.c
@@ -17,7 +17,7 @@
17#include "spi_master.h" 17#include "spi_master.h"
18#include "quantum.h" 18#include "quantum.h"
19#include "adns9800_srom_A6.h" 19#include "adns9800_srom_A6.h"
20#include "adns.h" 20#include "adns9800.h"
21 21
22// registers 22// registers
23#define REG_Product_ID 0x00 23#define REG_Product_ID 0x00
diff --git a/keyboards/oddball/adns/adns.h b/drivers/sensors/adns9800.h
index 2f50b8f1b..2f50b8f1b 100644
--- a/keyboards/oddball/adns/adns.h
+++ b/drivers/sensors/adns9800.h
diff --git a/keyboards/oddball/adns/adns9800_srom_A6.h b/drivers/sensors/adns9800_srom_A6.h
index f5b3abeb6..f5b3abeb6 100644
--- a/keyboards/oddball/adns/adns9800_srom_A6.h
+++ b/drivers/sensors/adns9800_srom_A6.h
diff --git a/keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.c b/drivers/sensors/pimoroni_trackball.c
index c4f4a0441..c0ac644f7 100644
--- a/keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.c
+++ b/drivers/sensors/pimoroni_trackball.c
@@ -26,8 +26,8 @@ static float precisionSpeed = 1;
26 26
27static uint16_t i2c_timeout_timer; 27static uint16_t i2c_timeout_timer;
28 28
29#ifndef I2C_TIMEOUT 29#ifndef PIMORONI_I2C_TIMEOUT
30# define I2C_TIMEOUT 100 30# define PIMORONI_I2C_TIMEOUT 100
31#endif 31#endif
32#ifndef I2C_WAITCHECK 32#ifndef I2C_WAITCHECK
33# define I2C_WAITCHECK 1000 33# define I2C_WAITCHECK 1000
@@ -38,7 +38,7 @@ static uint16_t i2c_timeout_timer;
38 38
39void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) { 39void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
40 uint8_t data[] = {0x00, red, green, blue, white}; 40 uint8_t data[] = {0x00, red, green, blue, white};
41 i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), I2C_TIMEOUT); 41 i2c_transmit(TRACKBALL_WRITE, data, sizeof(data), PIMORONI_I2C_TIMEOUT);
42} 42}
43 43
44int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) { 44int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) {
@@ -68,59 +68,19 @@ __attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* m
68 } 68 }
69} 69}
70 70
71bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
72 if (true) {
73 xprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed);
74 }
75
76
77 if (!process_record_user(keycode, record)) { return false; }
78
79/* If Mousekeys is disabled, then use handle the mouse button
80 * keycodes. This makes things simpler, and allows usage of
81 * the keycodes in a consistent manner. But only do this if
82 * Mousekeys is not enable, so it's not handled twice.
83 */
84#ifndef MOUSEKEY_ENABLE
85 if (IS_MOUSEKEY_BUTTON(keycode)) {
86 report_mouse_t currentReport = pointing_device_get_report();
87 if (record->event.pressed) {
88 currentReport.buttons |= 1 << (keycode - KC_MS_BTN1);
89 } else {
90 currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1));
91 }
92 pointing_device_set_report(currentReport);
93 pointing_device_send();
94 }
95#endif
96
97 return true;
98}
99
100void trackball_register_button(bool pressed, enum mouse_buttons button) {
101 report_mouse_t currentReport = pointing_device_get_report();
102 if (pressed) {
103 currentReport.buttons |= button;
104 } else {
105 currentReport.buttons &= ~button;
106 }
107 pointing_device_set_report(currentReport);
108}
109
110float trackball_get_precision(void) { return precisionSpeed; } 71float trackball_get_precision(void) { return precisionSpeed; }
111void trackball_set_precision(float precision) { precisionSpeed = precision; } 72void trackball_set_precision(float precision) { precisionSpeed = precision; }
112bool trackball_is_scrolling(void) { return scrolling; } 73bool trackball_is_scrolling(void) { return scrolling; }
113void trackball_set_scrolling(bool scroll) { scrolling = scroll; } 74void trackball_set_scrolling(bool scroll) { scrolling = scroll; }
114 75
115 76__attribute__((weak)) void pointing_device_init(void) { i2c_init(); trackball_set_rgbw(0x00, 0x00, 0x00, 0x00); }
116__attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x80, 0x00, 0x00, 0x00); }
117 77
118void pointing_device_task(void) { 78void pointing_device_task(void) {
119 static bool debounce; 79 static bool debounce;
120 static uint16_t debounce_timer; 80 static uint16_t debounce_timer;
121 uint8_t state[5] = {}; 81 uint8_t state[5] = {};
122 if (timer_elapsed(i2c_timeout_timer) > I2C_WAITCHECK) { 82 if (timer_elapsed(i2c_timeout_timer) > I2C_WAITCHECK) {
123 if (i2c_readReg(TRACKBALL_WRITE, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) { 83 if (i2c_readReg(TRACKBALL_READ, 0x04, state, 5, PIMORONI_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) {
124 if (!state[4] && !debounce) { 84 if (!state[4] && !debounce) {
125 if (scrolling) { 85 if (scrolling) {
126#ifdef PIMORONI_TRACKBALL_INVERT_X 86#ifdef PIMORONI_TRACKBALL_INVERT_X
@@ -159,7 +119,10 @@ void pointing_device_task(void) {
159 if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false; 119 if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false;
160 120
161 report_mouse_t mouse = pointing_device_get_report(); 121 report_mouse_t mouse = pointing_device_get_report();
162 // trackball_check_click(state[4] & (1 << 7), &mouse); 122
123#ifdef PIMORONI_TRACKBALL_CLICK
124 trackball_check_click(state[4] & (1 << 7), &mouse);
125#endif
163 126
164#ifndef PIMORONI_TRACKBALL_ROTATE 127#ifndef PIMORONI_TRACKBALL_ROTATE
165 update_member(&mouse.x, &x_offset); 128 update_member(&mouse.x, &x_offset);
diff --git a/users/drashna/pimoroni_trackball.h b/drivers/sensors/pimoroni_trackball.h
index a30fb0bb8..a30fb0bb8 100644
--- a/users/drashna/pimoroni_trackball.h
+++ b/drivers/sensors/pimoroni_trackball.h
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c b/drivers/sensors/pmw3360.c
index 59e349512..91ee87b95 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c
+++ b/drivers/sensors/pmw3360.c
@@ -16,8 +16,6 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#ifdef POINTING_DEVICE_ENABLE
20
21#include "wait.h" 19#include "wait.h"
22#include "debug.h" 20#include "debug.h"
23#include "print.h" 21#include "print.h"
@@ -29,17 +27,26 @@ bool _inBurst = false;
29#ifndef PMW_CPI 27#ifndef PMW_CPI
30# define PMW_CPI 1600 28# define PMW_CPI 1600
31#endif 29#endif
30#ifndef PMW_CLOCK_SPEED
31# define PMW_CLOCK_SPEED 70000000
32#endif
33#ifndef SPI_MODE
34# define SPI_MODE 3
35#endif
32#ifndef SPI_DIVISOR 36#ifndef SPI_DIVISOR
33# define SPI_DIVISOR 2 37# define SPI_DIVISOR (F_CPU / PMW_CLOCK_SPEED)
34#endif 38#endif
35#ifndef ROTATIONAL_TRANSFORM_ANGLE 39#ifndef ROTATIONAL_TRANSFORM_ANGLE
36# define ROTATIONAL_TRANSFORM_ANGLE 0x00 40# define ROTATIONAL_TRANSFORM_ANGLE 0x00
37#endif 41#endif
42#ifndef PMW_CS_PIN
43# define PMW_CS_PIN SPI_SS_PIN
44#endif
38 45
39void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); } 46void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); }
40 47
41bool spi_start_adv(void) { 48bool spi_start_adv(void) {
42 bool status = spi_start(SPI_SS_PIN, false, 3, SPI_DIVISOR); 49 bool status = spi_start(PMW_CS_PIN, false, SPI_MODE, SPI_DIVISOR);
43 wait_us(1); 50 wait_us(1);
44 return status; 51 return status;
45} 52}
@@ -57,7 +64,7 @@ spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) {
57 spi_start_adv(); 64 spi_start_adv();
58 // send address of the register, with MSBit = 1 to indicate it's a write 65 // send address of the register, with MSBit = 1 to indicate it's a write
59 spi_status_t status = spi_write(reg_addr | 0x80); 66 spi_status_t status = spi_write(reg_addr | 0x80);
60 status = spi_write(data); 67 status = spi_write(data);
61 68
62 // tSCLK-NCS for write operation 69 // tSCLK-NCS for write operation
63 wait_us(20); 70 wait_us(20);
@@ -86,14 +93,21 @@ uint8_t spi_read_adv(uint8_t reg_addr) {
86} 93}
87 94
88void pmw_set_cpi(uint16_t cpi) { 95void pmw_set_cpi(uint16_t cpi) {
89 int cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119 96 uint8_t cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119
90 97
91 spi_start_adv(); 98 spi_start_adv();
92 spi_write_adv(REG_Config1, cpival); 99 spi_write_adv(REG_Config1, cpival);
93 spi_stop(); 100 spi_stop();
94} 101}
95 102
103uint16_t pmw_get_cpi(void) {
104 uint8_t cpival = spi_read_adv(REG_Config1);
105 return (uint16_t)(cpival & 0xFF) * 100;
106}
107
96bool pmw_spi_init(void) { 108bool pmw_spi_init(void) {
109 setPinOutput(PMW_CS_PIN);
110
97 spi_init(); 111 spi_init();
98 _inBurst = false; 112 _inBurst = false;
99 113
@@ -101,7 +115,7 @@ bool pmw_spi_init(void) {
101 spi_start_adv(); 115 spi_start_adv();
102 spi_stop(); 116 spi_stop();
103 117
104 spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first 118 spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first
105 wait_ms(300); 119 wait_ms(300);
106 120
107 spi_start_adv(); 121 spi_start_adv();
@@ -127,14 +141,18 @@ bool pmw_spi_init(void) {
127 141
128 wait_ms(1); 142 wait_ms(1);
129 143
130 return pmw_check_signature();
131}
132
133void pmw_upload_firmware(void) {
134 spi_write_adv(REG_Config2, 0x00); 144 spi_write_adv(REG_Config2, 0x00);
135 145
136 spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); 146 spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30));
137 147
148 bool init_success = pmw_check_signature();
149
150 writePinLow(PMW_CS_PIN);
151
152 return init_success;
153}
154
155void pmw_upload_firmware(void) {
138 spi_write_adv(REG_SROM_Enable, 0x1d); 156 spi_write_adv(REG_SROM_Enable, 0x1d);
139 157
140 wait_ms(10); 158 wait_ms(10);
@@ -217,5 +235,3 @@ report_pmw_t pmw_read_burst(void) {
217 235
218 return data; 236 return data;
219} 237}
220
221#endif
diff --git a/keyboards/ploopyco/pmw3360.h b/drivers/sensors/pmw3360.h
index c1d5e3bad..d5b174179 100644
--- a/keyboards/ploopyco/pmw3360.h
+++ b/drivers/sensors/pmw3360.h
@@ -93,6 +93,7 @@ spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data);
93uint8_t spi_read_adv(uint8_t reg_addr); 93uint8_t spi_read_adv(uint8_t reg_addr);
94bool pmw_spi_init(void); 94bool pmw_spi_init(void);
95void pmw_set_cpi(uint16_t cpi); 95void pmw_set_cpi(uint16_t cpi);
96uint16_t pmw_get_cpi(void);
96void pmw_upload_firmware(void); 97void pmw_upload_firmware(void);
97bool pmw_check_signature(void); 98bool pmw_check_signature(void);
98report_pmw_t pmw_read_burst(void); 99report_pmw_t pmw_read_burst(void);
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360_firmware.h b/drivers/sensors/pmw3360_firmware.h
index cca5a6a4d..cca5a6a4d 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360_firmware.h
+++ b/drivers/sensors/pmw3360_firmware.h
diff --git a/keyboards/draculad/keymaps/pimoroni/keymap.c b/keyboards/draculad/keymaps/pimoroni/keymap.c
index 87cbe3cd3..762ae26c7 100644
--- a/keyboards/draculad/keymaps/pimoroni/keymap.c
+++ b/keyboards/draculad/keymaps/pimoroni/keymap.c
@@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include QMK_KEYBOARD_H 18#include QMK_KEYBOARD_H
19#include "pimoroni_trackball.h" 19#include "drivers/sensors/pimoroni_trackball.h"
20#include "pointing_device.h" 20#include "pointing_device.h"
21 21
22 22
diff --git a/keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.h b/keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.h
deleted file mode 100644
index cfcd5a47a..000000000
--- a/keyboards/draculad/keymaps/pimoroni/pimoroni_trackball.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "quantum.h"
20#include "pointing_device.h"
21
22#ifndef TRACKBALL_ADDRESS
23# define TRACKBALL_ADDRESS 0x0A
24#endif
25#define TRACKBALL_WRITE ((TRACKBALL_ADDRESS << 1) | I2C_WRITE)
26#define TRACKBALL_READ ((TRACKBALL_ADDRESS << 1) | I2C_READ)
27
28void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
29void trackball_check_click(bool pressed, report_mouse_t *mouse);
30void trackball_register_button(bool pressed, enum mouse_buttons button);
31
32float trackball_get_precision(void);
33void trackball_set_precision(float precision);
34bool trackball_is_scrolling(void);
35void trackball_set_scrolling(bool scroll); \ No newline at end of file
diff --git a/keyboards/draculad/keymaps/pimoroni/rules.mk b/keyboards/draculad/keymaps/pimoroni/rules.mk
index 547a02f26..d8dc92fbf 100644
--- a/keyboards/draculad/keymaps/pimoroni/rules.mk
+++ b/keyboards/draculad/keymaps/pimoroni/rules.mk
@@ -1,6 +1,6 @@
1# only uncomment on the side you have your trackball on 1# only uncomment on the side you have your trackball on
2POINTING_DEVICE_ENABLE = yes 2POINTING_DEVICE_ENABLE = yes
3SRC += pimoroni_trackball.c 3SRC += drivers/sensors/pimoroni_trackball.c
4QUANTUM_LIB_SRC += i2c_master.c 4QUANTUM_LIB_SRC += i2c_master.c
5OLED_DRIVER_ENABLE = yes 5OLED_DRIVER_ENABLE = yes
6MOUSEKEY_ENABLE = no 6MOUSEKEY_ENABLE = no
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h
index c8650f73d..ed408563f 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h
+++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h
@@ -19,7 +19,7 @@
19#include "dactyl_manuform.h" 19#include "dactyl_manuform.h"
20#include "quantum.h" 20#include "quantum.h"
21#include "spi_master.h" 21#include "spi_master.h"
22#include "pmw3360.h" 22#include "drivers/sensors/pmw3360.h"
23#include "pointing_device.h" 23#include "pointing_device.h"
24 24
25 25
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h
deleted file mode 100644
index c1d5e3bad..000000000
--- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h
+++ /dev/null
@@ -1,103 +0,0 @@
1/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
2 * Copyright 2019 Sunjun Kim
3 * Copyright 2020 Ploopy Corporation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include "spi_master.h"
22
23// Registers
24#define REG_Product_ID 0x00
25#define REG_Revision_ID 0x01
26#define REG_Motion 0x02
27#define REG_Delta_X_L 0x03
28#define REG_Delta_X_H 0x04
29#define REG_Delta_Y_L 0x05
30#define REG_Delta_Y_H 0x06
31#define REG_SQUAL 0x07
32#define REG_Raw_Data_Sum 0x08
33#define REG_Maximum_Raw_data 0x09
34#define REG_Minimum_Raw_data 0x0A
35#define REG_Shutter_Lower 0x0B
36#define REG_Shutter_Upper 0x0C
37#define REG_Control 0x0D
38#define REG_Config1 0x0F
39#define REG_Config2 0x10
40#define REG_Angle_Tune 0x11
41#define REG_Frame_Capture 0x12
42#define REG_SROM_Enable 0x13
43#define REG_Run_Downshift 0x14
44#define REG_Rest1_Rate_Lower 0x15
45#define REG_Rest1_Rate_Upper 0x16
46#define REG_Rest1_Downshift 0x17
47#define REG_Rest2_Rate_Lower 0x18
48#define REG_Rest2_Rate_Upper 0x19
49#define REG_Rest2_Downshift 0x1A
50#define REG_Rest3_Rate_Lower 0x1B
51#define REG_Rest3_Rate_Upper 0x1C
52#define REG_Observation 0x24
53#define REG_Data_Out_Lower 0x25
54#define REG_Data_Out_Upper 0x26
55#define REG_Raw_Data_Dump 0x29
56#define REG_SROM_ID 0x2A
57#define REG_Min_SQ_Run 0x2B
58#define REG_Raw_Data_Threshold 0x2C
59#define REG_Config5 0x2F
60#define REG_Power_Up_Reset 0x3A
61#define REG_Shutdown 0x3B
62#define REG_Inverse_Product_ID 0x3F
63#define REG_LiftCutoff_Tune3 0x41
64#define REG_Angle_Snap 0x42
65#define REG_LiftCutoff_Tune1 0x4A
66#define REG_Motion_Burst 0x50
67#define REG_LiftCutoff_Tune_Timeout 0x58
68#define REG_LiftCutoff_Tune_Min_Length 0x5A
69#define REG_SROM_Load_Burst 0x62
70#define REG_Lift_Config 0x63
71#define REG_Raw_Data_Burst 0x64
72#define REG_LiftCutoff_Tune2 0x65
73
74#ifdef CONSOLE_ENABLE
75void print_byte(uint8_t byte);
76#endif
77
78typedef struct {
79 int8_t motion;
80 bool isMotion; // True if a motion is detected.
81 bool isOnSurface; // True when a chip is on a surface
82 int16_t dx; // displacement on x directions. Unit: Count. (CPI * Count = Inch value)
83 int8_t mdx;
84 int16_t dy; // displacement on y directions.
85 int8_t mdy;
86} report_pmw_t;
87
88
89
90bool spi_start_adv(void);
91void spi_stop_adv(void);
92spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data);
93uint8_t spi_read_adv(uint8_t reg_addr);
94bool pmw_spi_init(void);
95void pmw_set_cpi(uint16_t cpi);
96void pmw_upload_firmware(void);
97bool pmw_check_signature(void);
98report_pmw_t pmw_read_burst(void);
99
100
101#define degToRad(angleInDegrees) ((angleInDegrees)*M_PI / 180.0)
102#define radToDeg(angleInRadians) ((angleInRadians)*180.0 / M_PI)
103#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)))
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk
index 3fb9ab2a8..9f4a5ea02 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk
+++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk
@@ -27,5 +27,5 @@ MOUSE_SHARED_EP = no
27SPLIT_KEYBOARD = yes 27SPLIT_KEYBOARD = yes
28SPLIT_TRANSPORT = custom 28SPLIT_TRANSPORT = custom
29 29
30SRC += pmw3360.c 30SRC += drivers/sensors/pmw3360.c
31QUANTUM_LIB_SRC += pointer_transport.c serial.c i2c_master.c i2c_slave.c spi_master.c 31QUANTUM_LIB_SRC += pointer_transport.c serial.c i2c_master.c i2c_slave.c spi_master.c
diff --git a/keyboards/oddball/optical_sensor/optical_sensor.h b/keyboards/oddball/optical_sensor/optical_sensor.h
index a152d02cf..00955209e 100644
--- a/keyboards/oddball/optical_sensor/optical_sensor.h
+++ b/keyboards/oddball/optical_sensor/optical_sensor.h
@@ -17,7 +17,7 @@
17/* common interface for opitcal sensors */ 17/* common interface for opitcal sensors */
18 18
19#if defined ADNS_9800 19#if defined ADNS_9800
20 #include "../adns/adns.h" 20 #include "drivers/sensors/adns9800.h"
21 #define config_optical_sensor_t config_adns_t 21 #define config_optical_sensor_t config_adns_t
22 #define report_optical_sensor_t report_adns_t 22 #define report_optical_sensor_t report_adns_t
23 #define optical_sensor_init adns_init 23 #define optical_sensor_init adns_init
diff --git a/keyboards/oddball/rules.mk b/keyboards/oddball/rules.mk
index e9e540c3c..8fc86b570 100644
--- a/keyboards/oddball/rules.mk
+++ b/keyboards/oddball/rules.mk
@@ -25,5 +25,5 @@ POINTING_DEVICE_ENABLE = yes
25DEFAULT_FOLDER = oddball/v1 25DEFAULT_FOLDER = oddball/v1
26 26
27SRC += spi_master.c 27SRC += spi_master.c
28SRC += adns/adns.c 28SRC += drivers/sensors/adns9800.c
29SRC += pmw/pmw.c 29SRC += pmw/pmw.c
diff --git a/keyboards/ploopyco/mouse/mouse.h b/keyboards/ploopyco/mouse/mouse.h
index 5d49d2f2d..d11aa5e9a 100644
--- a/keyboards/ploopyco/mouse/mouse.h
+++ b/keyboards/ploopyco/mouse/mouse.h
@@ -20,7 +20,7 @@
20 20
21#include "quantum.h" 21#include "quantum.h"
22#include "spi_master.h" 22#include "spi_master.h"
23#include "pmw3360.h" 23#include "drivers/sensors/pmw3360.h"
24#include "analog.h" 24#include "analog.h"
25#include "opt_encoder.h" 25#include "opt_encoder.h"
26#include "pointing_device.h" 26#include "pointing_device.h"
diff --git a/keyboards/ploopyco/mouse/rules.mk b/keyboards/ploopyco/mouse/rules.mk
index f998672f1..17aac9801 100644
--- a/keyboards/ploopyco/mouse/rules.mk
+++ b/keyboards/ploopyco/mouse/rules.mk
@@ -27,4 +27,4 @@ POINTING_DEVICE_ENABLE = yes
27MOUSEKEY_ENABLE = yes # Mouse keys 27MOUSEKEY_ENABLE = yes # Mouse keys
28 28
29QUANTUM_LIB_SRC += analog.c spi_master.c 29QUANTUM_LIB_SRC += analog.c spi_master.c
30SRC += pmw3360.c opt_encoder.c 30SRC += drivers/sensors/pmw3360.c opt_encoder.c
diff --git a/keyboards/ploopyco/pmw3360.c b/keyboards/ploopyco/pmw3360.c
deleted file mode 100644
index 5f9f72a9e..000000000
--- a/keyboards/ploopyco/pmw3360.c
+++ /dev/null
@@ -1,218 +0,0 @@
1/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
2 * Copyright 2019 Sunjun Kim
3 * Copyright 2020 Ploopy Corporation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "wait.h"
20#include "debug.h"
21#include "print.h"
22#include "pmw3360.h"
23#include "pmw3360_firmware.h"
24
25bool _inBurst = false;
26
27#ifndef PMW_CPI
28# define PMW_CPI 1600
29#endif
30#ifndef SPI_DIVISOR
31# define SPI_DIVISOR 2
32#endif
33#ifndef ROTATIONAL_TRANSFORM_ANGLE
34# define ROTATIONAL_TRANSFORM_ANGLE 0x00
35#endif
36
37void print_byte(uint8_t byte) { dprintf("%c%c%c%c%c%c%c%c|", (byte & 0x80 ? '1' : '0'), (byte & 0x40 ? '1' : '0'), (byte & 0x20 ? '1' : '0'), (byte & 0x10 ? '1' : '0'), (byte & 0x08 ? '1' : '0'), (byte & 0x04 ? '1' : '0'), (byte & 0x02 ? '1' : '0'), (byte & 0x01 ? '1' : '0')); }
38
39
40bool spi_start_adv(void) {
41 bool status = spi_start(SPI_SS_PIN, false, 3, SPI_DIVISOR);
42 wait_us(1);
43 return status;
44}
45
46void spi_stop_adv(void) {
47 wait_us(1);
48 spi_stop();
49}
50
51spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) {
52 if (reg_addr != REG_Motion_Burst) {
53 _inBurst = false;
54 }
55
56 spi_start_adv();
57 // send address of the register, with MSBit = 1 to indicate it's a write
58 spi_status_t status = spi_write(reg_addr | 0x80);
59 status = spi_write(data);
60
61 // tSCLK-NCS for write operation
62 wait_us(20);
63
64 // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
65 wait_us(100);
66 spi_stop();
67 return status;
68}
69
70uint8_t spi_read_adv(uint8_t reg_addr) {
71 spi_start_adv();
72 // send adress of the register, with MSBit = 0 to indicate it's a read
73 spi_write(reg_addr & 0x7f);
74
75 uint8_t data = spi_read();
76
77 // tSCLK-NCS for read operation is 120ns
78 wait_us(1);
79
80 // tSRW/tSRR (=20us) minus tSCLK-NCS
81 wait_us(19);
82
83 spi_stop();
84 return data;
85}
86
87void pmw_set_cpi(uint16_t cpi) {
88 int cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119
89
90 spi_start_adv();
91 spi_write_adv(REG_Config1, cpival);
92 spi_stop();
93}
94
95bool pmw_spi_init(void) {
96 spi_init();
97 _inBurst = false;
98
99 spi_stop();
100 spi_start_adv();
101 spi_stop();
102
103 spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first
104 wait_ms(300);
105
106 spi_start_adv();
107 wait_us(40);
108 spi_stop_adv();
109 wait_us(40);
110
111 spi_write_adv(REG_Power_Up_Reset, 0x5a);
112 wait_ms(50);
113
114 spi_read_adv(REG_Motion);
115 spi_read_adv(REG_Delta_X_L);
116 spi_read_adv(REG_Delta_X_H);
117 spi_read_adv(REG_Delta_Y_L);
118 spi_read_adv(REG_Delta_Y_H);
119
120 pmw_upload_firmware();
121
122 spi_stop_adv();
123
124 wait_ms(10);
125 pmw_set_cpi(PMW_CPI);
126
127 wait_ms(1);
128
129 return pmw_check_signature();
130}
131
132void pmw_upload_firmware(void) {
133 spi_write_adv(REG_Config2, 0x00);
134
135 spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30));
136
137 spi_write_adv(REG_SROM_Enable, 0x1d);
138
139 wait_ms(10);
140
141 spi_write_adv(REG_SROM_Enable, 0x18);
142
143 spi_start_adv();
144 spi_write(REG_SROM_Load_Burst | 0x80);
145 wait_us(15);
146
147 unsigned char c;
148 for (int i = 0; i < firmware_length; i++) {
149 c = (unsigned char)pgm_read_byte(firmware_data + i);
150 spi_write(c);
151 wait_us(15);
152 }
153 wait_us(200);
154
155 spi_read_adv(REG_SROM_ID);
156
157 spi_write_adv(REG_Config2, 0x00);
158
159 spi_stop();
160 wait_ms(10);
161}
162
163bool pmw_check_signature(void) {
164 uint8_t pid = spi_read_adv(REG_Product_ID);
165 uint8_t iv_pid = spi_read_adv(REG_Inverse_Product_ID);
166 uint8_t SROM_ver = spi_read_adv(REG_SROM_ID);
167 return (pid == 0x42 && iv_pid == 0xBD && SROM_ver == 0x04); // signature for SROM 0x04
168}
169
170report_pmw_t pmw_read_burst(void) {
171 if (!_inBurst) {
172 dprintf("burst on");
173 spi_write_adv(REG_Motion_Burst, 0x00);
174 _inBurst = true;
175 }
176
177 spi_start_adv();
178 spi_write(REG_Motion_Burst);
179 wait_us(35); // waits for tSRAD
180
181 report_pmw_t data;
182 data.motion = 0;
183 data.dx = 0;
184 data.mdx = 0;
185 data.dy = 0;
186 data.mdx = 0;
187
188 data.motion = spi_read();
189 spi_write(0x00); // skip Observation
190 data.dx = spi_read();
191 data.mdx = spi_read();
192 data.dy = spi_read();
193 data.mdy = spi_read();
194
195 spi_stop();
196
197 print_byte(data.motion);
198 print_byte(data.dx);
199 print_byte(data.mdx);
200 print_byte(data.dy);
201 print_byte(data.mdy);
202 dprintf("\n");
203
204 data.isMotion = (data.motion & 0x80) != 0;
205 data.isOnSurface = (data.motion & 0x08) == 0;
206 data.dx |= (data.mdx << 8);
207 data.dx = data.dx * -1;
208 data.dy |= (data.mdy << 8);
209 data.dy = data.dy * -1;
210
211 spi_stop();
212
213 if (data.motion & 0b111) { // panic recovery, sometimes burst mode works weird.
214 _inBurst = false;
215 }
216
217 return data;
218}
diff --git a/keyboards/ploopyco/pmw3360_firmware.h b/keyboards/ploopyco/pmw3360_firmware.h
deleted file mode 100644
index cca5a6a4d..000000000
--- a/keyboards/ploopyco/pmw3360_firmware.h
+++ /dev/null
@@ -1,300 +0,0 @@
1/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
2 * Copyright 2019 Sunjun Kim
3 * Copyright 2020 Ploopy Corporation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21// clang-format off
22// Firmware Blob foor PMW3360
23const uint16_t firmware_length = 4094;
24// clang-format off
25const uint8_t firmware_data[] PROGMEM = { // SROM 0x04
260x01, 0x04, 0x8e, 0x96, 0x6e, 0x77, 0x3e, 0xfe, 0x7e, 0x5f, 0x1d, 0xb8, 0xf2, 0x66, 0x4e,
270xff, 0x5d, 0x19, 0xb0, 0xc2, 0x04, 0x69, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0xb0,
280xc3, 0xe5, 0x29, 0xb1, 0xe0, 0x23, 0xa5, 0xa9, 0xb1, 0xc1, 0x00, 0x82, 0x67, 0x4c, 0x1a,
290x97, 0x8d, 0x79, 0x51, 0x20, 0xc7, 0x06, 0x8e, 0x7c, 0x7c, 0x7a, 0x76, 0x4f, 0xfd, 0x59,
300x30, 0xe2, 0x46, 0x0e, 0x9e, 0xbe, 0xdf, 0x1d, 0x99, 0x91, 0xa0, 0xa5, 0xa1, 0xa9, 0xd0,
310x22, 0xc6, 0xef, 0x5c, 0x1b, 0x95, 0x89, 0x90, 0xa2, 0xa7, 0xcc, 0xfb, 0x55, 0x28, 0xb3,
320xe4, 0x4a, 0xf7, 0x6c, 0x3b, 0xf4, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x05,
330x88, 0x92, 0xa6, 0xce, 0x1e, 0xbe, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x07,
340x11, 0x5d, 0x98, 0x0b, 0x9d, 0x94, 0x97, 0xee, 0x4e, 0x45, 0x33, 0x6b, 0x44, 0xc7, 0x29,
350x56, 0x27, 0x30, 0xc6, 0xa7, 0xd5, 0xf2, 0x56, 0xdf, 0xb4, 0x38, 0x62, 0xcb, 0xa0, 0xb6,
360xe3, 0x0f, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6f, 0x76, 0x89, 0xb5, 0x77, 0x41, 0x27, 0x82,
370x66, 0x65, 0x82, 0xcc, 0xd5, 0xe6, 0x20, 0xd5, 0x27, 0x17, 0xc5, 0xf8, 0x03, 0x23, 0x7c,
380x5f, 0x64, 0xa5, 0x1d, 0xc1, 0xd6, 0x36, 0xcb, 0x4c, 0xd4, 0xdb, 0x66, 0xd7, 0x8b, 0xb1,
390x99, 0x7e, 0x6f, 0x4c, 0x36, 0x40, 0x06, 0xd6, 0xeb, 0xd7, 0xa2, 0xe4, 0xf4, 0x95, 0x51,
400x5a, 0x54, 0x96, 0xd5, 0x53, 0x44, 0xd7, 0x8c, 0xe0, 0xb9, 0x40, 0x68, 0xd2, 0x18, 0xe9,
410xdd, 0x9a, 0x23, 0x92, 0x48, 0xee, 0x7f, 0x43, 0xaf, 0xea, 0x77, 0x38, 0x84, 0x8c, 0x0a,
420x72, 0xaf, 0x69, 0xf8, 0xdd, 0xf1, 0x24, 0x83, 0xa3, 0xf8, 0x4a, 0xbf, 0xf5, 0x94, 0x13,
430xdb, 0xbb, 0xd8, 0xb4, 0xb3, 0xa0, 0xfb, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71,
440xa2, 0xd3, 0x13, 0xe7, 0xfa, 0xe7, 0xce, 0x0f, 0x63, 0x15, 0x0b, 0x6b, 0x94, 0xbb, 0x37,
450x83, 0x26, 0x05, 0x9d, 0xfb, 0x46, 0x92, 0xfc, 0x0a, 0x15, 0xd1, 0x0d, 0x73, 0x92, 0xd6,
460x8c, 0x1b, 0x8c, 0xb8, 0x55, 0x8a, 0xce, 0xbd, 0xfe, 0x8e, 0xfc, 0xed, 0x09, 0x12, 0x83,
470x91, 0x82, 0x51, 0x31, 0x23, 0xfb, 0xb4, 0x0c, 0x76, 0xad, 0x7c, 0xd9, 0xb4, 0x4b, 0xb2,
480x67, 0x14, 0x09, 0x9c, 0x7f, 0x0c, 0x18, 0xba, 0x3b, 0xd6, 0x8e, 0x14, 0x2a, 0xe4, 0x1b,
490x52, 0x9f, 0x2b, 0x7d, 0xe1, 0xfb, 0x6a, 0x33, 0x02, 0xfa, 0xac, 0x5a, 0xf2, 0x3e, 0x88,
500x7e, 0xae, 0xd1, 0xf3, 0x78, 0xe8, 0x05, 0xd1, 0xe3, 0xdc, 0x21, 0xf6, 0xe1, 0x9a, 0xbd,
510x17, 0x0e, 0xd9, 0x46, 0x9b, 0x88, 0x03, 0xea, 0xf6, 0x66, 0xbe, 0x0e, 0x1b, 0x50, 0x49,
520x96, 0x40, 0x97, 0xf1, 0xf1, 0xe4, 0x80, 0xa6, 0x6e, 0xe8, 0x77, 0x34, 0xbf, 0x29, 0x40,
530x44, 0xc2, 0xff, 0x4e, 0x98, 0xd3, 0x9c, 0xa3, 0x32, 0x2b, 0x76, 0x51, 0x04, 0x09, 0xe7,
540xa9, 0xd1, 0xa6, 0x32, 0xb1, 0x23, 0x53, 0xe2, 0x47, 0xab, 0xd6, 0xf5, 0x69, 0x5c, 0x3e,
550x5f, 0xfa, 0xae, 0x45, 0x20, 0xe5, 0xd2, 0x44, 0xff, 0x39, 0x32, 0x6d, 0xfd, 0x27, 0x57,
560x5c, 0xfd, 0xf0, 0xde, 0xc1, 0xb5, 0x99, 0xe5, 0xf5, 0x1c, 0x77, 0x01, 0x75, 0xc5, 0x6d,
570x58, 0x92, 0xf2, 0xb2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7a, 0x30, 0xff, 0xb7, 0xf0, 0xef,
580x77, 0xc1, 0x8a, 0x5d, 0xdc, 0xc0, 0xd1, 0x29, 0x30, 0x1e, 0x77, 0x38, 0x7a, 0x94, 0xf1,
590xb8, 0x7a, 0x7e, 0xef, 0xa4, 0xd1, 0xac, 0x31, 0x4a, 0xf2, 0x5d, 0x64, 0x3d, 0xb2, 0xe2,
600xf0, 0x08, 0x99, 0xfc, 0x70, 0xee, 0x24, 0xa7, 0x7e, 0xee, 0x1e, 0x20, 0x69, 0x7d, 0x44,
610xbf, 0x87, 0x42, 0xdf, 0x88, 0x3b, 0x0c, 0xda, 0x42, 0xc9, 0x04, 0xf9, 0x45, 0x50, 0xfc,
620x83, 0x8f, 0x11, 0x6a, 0x72, 0xbc, 0x99, 0x95, 0xf0, 0xac, 0x3d, 0xa7, 0x3b, 0xcd, 0x1c,
630xe2, 0x88, 0x79, 0x37, 0x11, 0x5f, 0x39, 0x89, 0x95, 0x0a, 0x16, 0x84, 0x7a, 0xf6, 0x8a,
640xa4, 0x28, 0xe4, 0xed, 0x83, 0x80, 0x3b, 0xb1, 0x23, 0xa5, 0x03, 0x10, 0xf4, 0x66, 0xea,
650xbb, 0x0c, 0x0f, 0xc5, 0xec, 0x6c, 0x69, 0xc5, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0x99,
660x88, 0x76, 0x08, 0xa0, 0xa8, 0x95, 0x7c, 0xd8, 0x38, 0x6d, 0xcd, 0x59, 0x02, 0x51, 0x4b,
670xf1, 0xb5, 0x2b, 0x50, 0xe3, 0xb6, 0xbd, 0xd0, 0x72, 0xcf, 0x9e, 0xfd, 0x6e, 0xbb, 0x44,
680xc8, 0x24, 0x8a, 0x77, 0x18, 0x8a, 0x13, 0x06, 0xef, 0x97, 0x7d, 0xfa, 0x81, 0xf0, 0x31,
690xe6, 0xfa, 0x77, 0xed, 0x31, 0x06, 0x31, 0x5b, 0x54, 0x8a, 0x9f, 0x30, 0x68, 0xdb, 0xe2,
700x40, 0xf8, 0x4e, 0x73, 0xfa, 0xab, 0x74, 0x8b, 0x10, 0x58, 0x13, 0xdc, 0xd2, 0xe6, 0x78,
710xd1, 0x32, 0x2e, 0x8a, 0x9f, 0x2c, 0x58, 0x06, 0x48, 0x27, 0xc5, 0xa9, 0x5e, 0x81, 0x47,
720x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xa4, 0x3e, 0x88, 0x9c, 0xda, 0x33, 0x0a, 0xce, 0xbc,
730x8b, 0x8e, 0xcf, 0x9f, 0xd3, 0x71, 0x80, 0x43, 0xcf, 0x6b, 0xa9, 0x51, 0x83, 0x76, 0x30,
740x82, 0xc5, 0x6a, 0x85, 0x39, 0x11, 0x50, 0x1a, 0x82, 0xdc, 0x1e, 0x1c, 0xd5, 0x7d, 0xa9,
750x71, 0x99, 0x33, 0x47, 0x19, 0x97, 0xb3, 0x5a, 0xb1, 0xdf, 0xed, 0xa4, 0xf2, 0xe6, 0x26,
760x84, 0xa2, 0x28, 0x9a, 0x9e, 0xdf, 0xa6, 0x6a, 0xf4, 0xd6, 0xfc, 0x2e, 0x5b, 0x9d, 0x1a,
770x2a, 0x27, 0x68, 0xfb, 0xc1, 0x83, 0x21, 0x4b, 0x90, 0xe0, 0x36, 0xdd, 0x5b, 0x31, 0x42,
780x55, 0xa0, 0x13, 0xf7, 0xd0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xc5, 0xf3, 0x21,
790xf8, 0x37, 0x2f, 0x40, 0xf3, 0xd4, 0xaf, 0x16, 0x08, 0x36, 0x02, 0xfc, 0x77, 0xc5, 0x8b,
800x04, 0x90, 0x56, 0xb9, 0xc9, 0x67, 0x9a, 0x99, 0xe8, 0x00, 0xd3, 0x86, 0xff, 0x97, 0x2d,
810x08, 0xe9, 0xb7, 0xb3, 0x91, 0xbc, 0xdf, 0x45, 0xc6, 0xed, 0x0f, 0x8c, 0x4c, 0x1e, 0xe6,
820x5b, 0x6e, 0x38, 0x30, 0xe4, 0xaa, 0xe3, 0x95, 0xde, 0xb9, 0xe4, 0x9a, 0xf5, 0xb2, 0x55,
830x9a, 0x87, 0x9b, 0xf6, 0x6a, 0xb2, 0xf2, 0x77, 0x9a, 0x31, 0xf4, 0x7a, 0x31, 0xd1, 0x1d,
840x04, 0xc0, 0x7c, 0x32, 0xa2, 0x9e, 0x9a, 0xf5, 0x62, 0xf8, 0x27, 0x8d, 0xbf, 0x51, 0xff,
850xd3, 0xdf, 0x64, 0x37, 0x3f, 0x2a, 0x6f, 0x76, 0x3a, 0x7d, 0x77, 0x06, 0x9e, 0x77, 0x7f,
860x5e, 0xeb, 0x32, 0x51, 0xf9, 0x16, 0x66, 0x9a, 0x09, 0xf3, 0xb0, 0x08, 0xa4, 0x70, 0x96,
870x46, 0x30, 0xff, 0xda, 0x4f, 0xe9, 0x1b, 0xed, 0x8d, 0xf8, 0x74, 0x1f, 0x31, 0x92, 0xb3,
880x73, 0x17, 0x36, 0xdb, 0x91, 0x30, 0xd6, 0x88, 0x55, 0x6b, 0x34, 0x77, 0x87, 0x7a, 0xe7,
890xee, 0x06, 0xc6, 0x1c, 0x8c, 0x19, 0x0c, 0x48, 0x46, 0x23, 0x5e, 0x9c, 0x07, 0x5c, 0xbf,
900xb4, 0x7e, 0xd6, 0x4f, 0x74, 0x9c, 0xe2, 0xc5, 0x50, 0x8b, 0xc5, 0x8b, 0x15, 0x90, 0x60,
910x62, 0x57, 0x29, 0xd0, 0x13, 0x43, 0xa1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xc7, 0x4d, 0x19,
920x86, 0xcc, 0x2f, 0x2a, 0x75, 0x5a, 0xfc, 0xeb, 0x97, 0x2a, 0x70, 0xe3, 0x78, 0xd8, 0x91,
930xb0, 0x4f, 0x99, 0x07, 0xa3, 0x95, 0xea, 0x24, 0x21, 0xd5, 0xde, 0x51, 0x20, 0x93, 0x27,
940x0a, 0x30, 0x73, 0xa8, 0xff, 0x8a, 0x97, 0xe9, 0xa7, 0x6a, 0x8e, 0x0d, 0xe8, 0xf0, 0xdf,
950xec, 0xea, 0xb4, 0x6c, 0x1d, 0x39, 0x2a, 0x62, 0x2d, 0x3d, 0x5a, 0x8b, 0x65, 0xf8, 0x90,
960x05, 0x2e, 0x7e, 0x91, 0x2c, 0x78, 0xef, 0x8e, 0x7a, 0xc1, 0x2f, 0xac, 0x78, 0xee, 0xaf,
970x28, 0x45, 0x06, 0x4c, 0x26, 0xaf, 0x3b, 0xa2, 0xdb, 0xa3, 0x93, 0x06, 0xb5, 0x3c, 0xa5,
980xd8, 0xee, 0x8f, 0xaf, 0x25, 0xcc, 0x3f, 0x85, 0x68, 0x48, 0xa9, 0x62, 0xcc, 0x97, 0x8f,
990x7f, 0x2a, 0xea, 0xe0, 0x15, 0x0a, 0xad, 0x62, 0x07, 0xbd, 0x45, 0xf8, 0x41, 0xd8, 0x36,
1000xcb, 0x4c, 0xdb, 0x6e, 0xe6, 0x3a, 0xe7, 0xda, 0x15, 0xe9, 0x29, 0x1e, 0x12, 0x10, 0xa0,
1010x14, 0x2c, 0x0e, 0x3d, 0xf4, 0xbf, 0x39, 0x41, 0x92, 0x75, 0x0b, 0x25, 0x7b, 0xa3, 0xce,
1020x39, 0x9c, 0x15, 0x64, 0xc8, 0xfa, 0x3d, 0xef, 0x73, 0x27, 0xfe, 0x26, 0x2e, 0xce, 0xda,
1030x6e, 0xfd, 0x71, 0x8e, 0xdd, 0xfe, 0x76, 0xee, 0xdc, 0x12, 0x5c, 0x02, 0xc5, 0x3a, 0x4e,
1040x4e, 0x4f, 0xbf, 0xca, 0x40, 0x15, 0xc7, 0x6e, 0x8d, 0x41, 0xf1, 0x10, 0xe0, 0x4f, 0x7e,
1050x97, 0x7f, 0x1c, 0xae, 0x47, 0x8e, 0x6b, 0xb1, 0x25, 0x31, 0xb0, 0x73, 0xc7, 0x1b, 0x97,
1060x79, 0xf9, 0x80, 0xd3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1e, 0xe4, 0xd0, 0x80, 0x21, 0xd6,
1070xee, 0x6b, 0x6c, 0x4f, 0xbf, 0xf5, 0xb7, 0xd9, 0x09, 0x87, 0x2f, 0xa9, 0x14, 0xbe, 0x27,
1080xd9, 0x72, 0x50, 0x01, 0xd4, 0x13, 0x73, 0xa6, 0xa7, 0x51, 0x02, 0x75, 0x25, 0xe1, 0xb3,
1090x45, 0x34, 0x7d, 0xa8, 0x8e, 0xeb, 0xf3, 0x16, 0x49, 0xcb, 0x4f, 0x8c, 0xa1, 0xb9, 0x36,
1100x85, 0x39, 0x75, 0x5d, 0x08, 0x00, 0xae, 0xeb, 0xf6, 0xea, 0xd7, 0x13, 0x3a, 0x21, 0x5a,
1110x5f, 0x30, 0x84, 0x52, 0x26, 0x95, 0xc9, 0x14, 0xf2, 0x57, 0x55, 0x6b, 0xb1, 0x10, 0xc2,
1120xe1, 0xbd, 0x3b, 0x51, 0xc0, 0xb7, 0x55, 0x4c, 0x71, 0x12, 0x26, 0xc7, 0x0d, 0xf9, 0x51,
1130xa4, 0x38, 0x02, 0x05, 0x7f, 0xb8, 0xf1, 0x72, 0x4b, 0xbf, 0x71, 0x89, 0x14, 0xf3, 0x77,
1140x38, 0xd9, 0x71, 0x24, 0xf3, 0x00, 0x11, 0xa1, 0xd8, 0xd4, 0x69, 0x27, 0x08, 0x37, 0x35,
1150xc9, 0x11, 0x9d, 0x90, 0x1c, 0x0e, 0xe7, 0x1c, 0xff, 0x2d, 0x1e, 0xe8, 0x92, 0xe1, 0x18,
1160x10, 0x95, 0x7c, 0xe0, 0x80, 0xf4, 0x96, 0x43, 0x21, 0xf9, 0x75, 0x21, 0x64, 0x38, 0xdd,
1170x9f, 0x1e, 0x95, 0x16, 0xda, 0x56, 0x1d, 0x4f, 0x9a, 0x53, 0xb2, 0xe2, 0xe4, 0x18, 0xcb,
1180x6b, 0x1a, 0x65, 0xeb, 0x56, 0xc6, 0x3b, 0xe5, 0xfe, 0xd8, 0x26, 0x3f, 0x3a, 0x84, 0x59,
1190x72, 0x66, 0xa2, 0xf3, 0x75, 0xff, 0xfb, 0x60, 0xb3, 0x22, 0xad, 0x3f, 0x2d, 0x6b, 0xf9,
1200xeb, 0xea, 0x05, 0x7c, 0xd8, 0x8f, 0x6d, 0x2c, 0x98, 0x9e, 0x2b, 0x93, 0xf1, 0x5e, 0x46,
1210xf0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xd7, 0x7f, 0xf9, 0xf0, 0xe5, 0x7d, 0xdb, 0x1d, 0x75,
1220x19, 0xf3, 0xc4, 0x58, 0x9b, 0x17, 0x88, 0xa8, 0x92, 0xe0, 0xbe, 0xbd, 0x8b, 0x1d, 0x8d,
1230x9f, 0x56, 0x76, 0xad, 0xaf, 0x29, 0xe2, 0xd9, 0xd5, 0x52, 0xf6, 0xb5, 0x56, 0x35, 0x57,
1240x3a, 0xc8, 0xe1, 0x56, 0x43, 0x19, 0x94, 0xd3, 0x04, 0x9b, 0x6d, 0x35, 0xd8, 0x0b, 0x5f,
1250x4d, 0x19, 0x8e, 0xec, 0xfa, 0x64, 0x91, 0x0a, 0x72, 0x20, 0x2b, 0xbc, 0x1a, 0x4a, 0xfe,
1260x8b, 0xfd, 0xbb, 0xed, 0x1b, 0x23, 0xea, 0xad, 0x72, 0x82, 0xa1, 0x29, 0x99, 0x71, 0xbd,
1270xf0, 0x95, 0xc1, 0x03, 0xdd, 0x7b, 0xc2, 0xb2, 0x3c, 0x28, 0x54, 0xd3, 0x68, 0xa4, 0x72,
1280xc8, 0x66, 0x96, 0xe0, 0xd1, 0xd8, 0x7f, 0xf8, 0xd1, 0x26, 0x2b, 0xf7, 0xad, 0xba, 0x55,
1290xca, 0x15, 0xb9, 0x32, 0xc3, 0xe5, 0x88, 0x97, 0x8e, 0x5c, 0xfb, 0x92, 0x25, 0x8b, 0xbf,
1300xa2, 0x45, 0x55, 0x7a, 0xa7, 0x6f, 0x8b, 0x57, 0x5b, 0xcf, 0x0e, 0xcb, 0x1d, 0xfb, 0x20,
1310x82, 0x77, 0xa8, 0x8c, 0xcc, 0x16, 0xce, 0x1d, 0xfa, 0xde, 0xcc, 0x0b, 0x62, 0xfe, 0xcc,
1320xe1, 0xb7, 0xf0, 0xc3, 0x81, 0x64, 0x73, 0x40, 0xa0, 0xc2, 0x4d, 0x89, 0x11, 0x75, 0x33,
1330x55, 0x33, 0x8d, 0xe8, 0x4a, 0xfd, 0xea, 0x6e, 0x30, 0x0b, 0xd7, 0x31, 0x2c, 0xde, 0x47,
1340xe3, 0xbf, 0xf8, 0x55, 0x42, 0xe2, 0x7f, 0x59, 0xe5, 0x17, 0xef, 0x99, 0x34, 0x69, 0x91,
1350xb1, 0x23, 0x8e, 0x20, 0x87, 0x2d, 0xa8, 0xfe, 0xd5, 0x8a, 0xf3, 0x84, 0x3a, 0xf0, 0x37,
1360xe4, 0x09, 0x00, 0x54, 0xee, 0x67, 0x49, 0x93, 0xe4, 0x81, 0x70, 0xe3, 0x90, 0x4d, 0xef,
1370xfe, 0x41, 0xb7, 0x99, 0x7b, 0xc1, 0x83, 0xba, 0x62, 0x12, 0x6f, 0x7d, 0xde, 0x6b, 0xaf,
1380xda, 0x16, 0xf9, 0x55, 0x51, 0xee, 0xa6, 0x0c, 0x2b, 0x02, 0xa3, 0xfd, 0x8d, 0xfb, 0x30,
1390x17, 0xe4, 0x6f, 0xdf, 0x36, 0x71, 0xc4, 0xca, 0x87, 0x25, 0x48, 0xb0, 0x47, 0xec, 0xea,
1400xb4, 0xbf, 0xa5, 0x4d, 0x9b, 0x9f, 0x02, 0x93, 0xc4, 0xe3, 0xe4, 0xe8, 0x42, 0x2d, 0x68,
1410x81, 0x15, 0x0a, 0xeb, 0x84, 0x5b, 0xd6, 0xa8, 0x74, 0xfb, 0x7d, 0x1d, 0xcb, 0x2c, 0xda,
1420x46, 0x2a, 0x76, 0x62, 0xce, 0xbc, 0x5c, 0x9e, 0x8b, 0xe7, 0xcf, 0xbe, 0x78, 0xf5, 0x7c,
1430xeb, 0xb3, 0x3a, 0x9c, 0xaa, 0x6f, 0xcc, 0x72, 0xd1, 0x59, 0xf2, 0x11, 0x23, 0xd6, 0x3f,
1440x48, 0xd1, 0xb7, 0xce, 0xb0, 0xbf, 0xcb, 0xea, 0x80, 0xde, 0x57, 0xd4, 0x5e, 0x97, 0x2f,
1450x75, 0xd1, 0x50, 0x8e, 0x80, 0x2c, 0x66, 0x79, 0xbf, 0x72, 0x4b, 0xbd, 0x8a, 0x81, 0x6c,
1460xd3, 0xe1, 0x01, 0xdc, 0xd2, 0x15, 0x26, 0xc5, 0x36, 0xda, 0x2c, 0x1a, 0xc0, 0x27, 0x94,
1470xed, 0xb7, 0x9b, 0x85, 0x0b, 0x5e, 0x80, 0x97, 0xc5, 0xec, 0x4f, 0xec, 0x88, 0x5d, 0x50,
1480x07, 0x35, 0x47, 0xdc, 0x0b, 0x3b, 0x3d, 0xdd, 0x60, 0xaf, 0xa8, 0x5d, 0x81, 0x38, 0x24,
1490x25, 0x5d, 0x5c, 0x15, 0xd1, 0xde, 0xb3, 0xab, 0xec, 0x05, 0x69, 0xef, 0x83, 0xed, 0x57,
1500x54, 0xb8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xda, 0x9f, 0x2d, 0x7f, 0x36, 0xbb, 0x44,
1510x5a, 0x34, 0xe8, 0x7f, 0xbf, 0x03, 0xeb, 0x00, 0x7f, 0x59, 0x68, 0x22, 0x79, 0xcf, 0x73,
1520x6c, 0x2c, 0x29, 0xa7, 0xa1, 0x5f, 0x38, 0xa1, 0x1d, 0xf0, 0x20, 0x53, 0xe0, 0x1a, 0x63,
1530x14, 0x58, 0x71, 0x10, 0xaa, 0x08, 0x0c, 0x3e, 0x16, 0x1a, 0x60, 0x22, 0x82, 0x7f, 0xba,
1540xa4, 0x43, 0xa0, 0xd0, 0xac, 0x1b, 0xd5, 0x6b, 0x64, 0xb5, 0x14, 0x93, 0x31, 0x9e, 0x53,
1550x50, 0xd0, 0x57, 0x66, 0xee, 0x5a, 0x4f, 0xfb, 0x03, 0x2a, 0x69, 0x58, 0x76, 0xf1, 0x83,
1560xf7, 0x4e, 0xba, 0x8c, 0x42, 0x06, 0x60, 0x5d, 0x6d, 0xce, 0x60, 0x88, 0xae, 0xa4, 0xc3,
1570xf1, 0x03, 0xa5, 0x4b, 0x98, 0xa1, 0xff, 0x67, 0xe1, 0xac, 0xa2, 0xb8, 0x62, 0xd7, 0x6f,
1580xa0, 0x31, 0xb4, 0xd2, 0x77, 0xaf, 0x21, 0x10, 0x06, 0xc6, 0x9a, 0xff, 0x1d, 0x09, 0x17,
1590x0e, 0x5f, 0xf1, 0xaa, 0x54, 0x34, 0x4b, 0x45, 0x8a, 0x87, 0x63, 0xa6, 0xdc, 0xf9, 0x24,
1600x30, 0x67, 0xc6, 0xb2, 0xd6, 0x61, 0x33, 0x69, 0xee, 0x50, 0x61, 0x57, 0x28, 0xe7, 0x7e,
1610xee, 0xec, 0x3a, 0x5a, 0x73, 0x4e, 0xa8, 0x8d, 0xe4, 0x18, 0xea, 0xec, 0x41, 0x64, 0xc8,
1620xe2, 0xe8, 0x66, 0xb6, 0x2d, 0xb6, 0xfb, 0x6a, 0x6c, 0x16, 0xb3, 0xdd, 0x46, 0x43, 0xb9,
1630x73, 0x00, 0x6a, 0x71, 0xed, 0x4e, 0x9d, 0x25, 0x1a, 0xc3, 0x3c, 0x4a, 0x95, 0x15, 0x99,
1640x35, 0x81, 0x14, 0x02, 0xd6, 0x98, 0x9b, 0xec, 0xd8, 0x23, 0x3b, 0x84, 0x29, 0xaf, 0x0c,
1650x99, 0x83, 0xa6, 0x9a, 0x34, 0x4f, 0xfa, 0xe8, 0xd0, 0x3c, 0x4b, 0xd0, 0xfb, 0xb6, 0x68,
1660xb8, 0x9e, 0x8f, 0xcd, 0xf7, 0x60, 0x2d, 0x7a, 0x22, 0xe5, 0x7d, 0xab, 0x65, 0x1b, 0x95,
1670xa7, 0xa8, 0x7f, 0xb6, 0x77, 0x47, 0x7b, 0x5f, 0x8b, 0x12, 0x72, 0xd0, 0xd4, 0x91, 0xef,
1680xde, 0x19, 0x50, 0x3c, 0xa7, 0x8b, 0xc4, 0xa9, 0xb3, 0x23, 0xcb, 0x76, 0xe6, 0x81, 0xf0,
1690xc1, 0x04, 0x8f, 0xa3, 0xb8, 0x54, 0x5b, 0x97, 0xac, 0x19, 0xff, 0x3f, 0x55, 0x27, 0x2f,
1700xe0, 0x1d, 0x42, 0x9b, 0x57, 0xfc, 0x4b, 0x4e, 0x0f, 0xce, 0x98, 0xa9, 0x43, 0x57, 0x03,
1710xbd, 0xe7, 0xc8, 0x94, 0xdf, 0x6e, 0x36, 0x73, 0x32, 0xb4, 0xef, 0x2e, 0x85, 0x7a, 0x6e,
1720xfc, 0x6c, 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xf3, 0xe4, 0x9f, 0x3e, 0xdc, 0x68, 0xf3,
1730xb5, 0xf3, 0x19, 0x80, 0x92, 0x06, 0x99, 0xa2, 0xe8, 0x6f, 0xff, 0x2e, 0x7f, 0xae, 0x42,
1740xa4, 0x5f, 0xfb, 0xd4, 0x0e, 0x81, 0x2b, 0xc3, 0x04, 0xff, 0x2b, 0xb3, 0x74, 0x4e, 0x36,
1750x5b, 0x9c, 0x15, 0x00, 0xc6, 0x47, 0x2b, 0xe8, 0x8b, 0x3d, 0xf1, 0x9c, 0x03, 0x9a, 0x58,
1760x7f, 0x9b, 0x9c, 0xbf, 0x85, 0x49, 0x79, 0x35, 0x2e, 0x56, 0x7b, 0x41, 0x14, 0x39, 0x47,
1770x83, 0x26, 0xaa, 0x07, 0x89, 0x98, 0x11, 0x1b, 0x86, 0xe7, 0x73, 0x7a, 0xd8, 0x7d, 0x78,
1780x61, 0x53, 0xe9, 0x79, 0xf5, 0x36, 0x8d, 0x44, 0x92, 0x84, 0xf9, 0x13, 0x50, 0x58, 0x3b,
1790xa4, 0x6a, 0x36, 0x65, 0x49, 0x8e, 0x3c, 0x0e, 0xf1, 0x6f, 0xd2, 0x84, 0xc4, 0x7e, 0x8e,
1800x3f, 0x39, 0xae, 0x7c, 0x84, 0xf1, 0x63, 0x37, 0x8e, 0x3c, 0xcc, 0x3e, 0x44, 0x81, 0x45,
1810xf1, 0x4b, 0xb9, 0xed, 0x6b, 0x36, 0x5d, 0xbb, 0x20, 0x60, 0x1a, 0x0f, 0xa3, 0xaa, 0x55,
1820x77, 0x3a, 0xa9, 0xae, 0x37, 0x4d, 0xba, 0xb8, 0x86, 0x6b, 0xbc, 0x08, 0x50, 0xf6, 0xcc,
1830xa4, 0xbd, 0x1d, 0x40, 0x72, 0xa5, 0x86, 0xfa, 0xe2, 0x10, 0xae, 0x3d, 0x58, 0x4b, 0x97,
1840xf3, 0x43, 0x74, 0xa9, 0x9e, 0xeb, 0x21, 0xb7, 0x01, 0xa4, 0x86, 0x93, 0x97, 0xee, 0x2f,
1850x4f, 0x3b, 0x86, 0xa1, 0x41, 0x6f, 0x41, 0x26, 0x90, 0x78, 0x5c, 0x7f, 0x30, 0x38, 0x4b,
1860x3f, 0xaa, 0xec, 0xed, 0x5c, 0x6f, 0x0e, 0xad, 0x43, 0x87, 0xfd, 0x93, 0x35, 0xe6, 0x01,
1870xef, 0x41, 0x26, 0x90, 0x99, 0x9e, 0xfb, 0x19, 0x5b, 0xad, 0xd2, 0x91, 0x8a, 0xe0, 0x46,
1880xaf, 0x65, 0xfa, 0x4f, 0x84, 0xc1, 0xa1, 0x2d, 0xcf, 0x45, 0x8b, 0xd3, 0x85, 0x50, 0x55,
1890x7c, 0xf9, 0x67, 0x88, 0xd4, 0x4e, 0xe9, 0xd7, 0x6b, 0x61, 0x54, 0xa1, 0xa4, 0xa6, 0xa2,
1900xc2, 0xbf, 0x30, 0x9c, 0x40, 0x9f, 0x5f, 0xd7, 0x69, 0x2b, 0x24, 0x82, 0x5e, 0xd9, 0xd6,
1910xa7, 0x12, 0x54, 0x1a, 0xf7, 0x55, 0x9f, 0x76, 0x50, 0xa9, 0x95, 0x84, 0xe6, 0x6b, 0x6d,
1920xb5, 0x96, 0x54, 0xd6, 0xcd, 0xb3, 0xa1, 0x9b, 0x46, 0xa7, 0x94, 0x4d, 0xc4, 0x94, 0xb4,
1930x98, 0xe3, 0xe1, 0xe2, 0x34, 0xd5, 0x33, 0x16, 0x07, 0x54, 0xcd, 0xb7, 0x77, 0x53, 0xdb,
1940x4f, 0x4d, 0x46, 0x9d, 0xe9, 0xd4, 0x9c, 0x8a, 0x36, 0xb6, 0xb8, 0x38, 0x26, 0x6c, 0x0e,
1950xff, 0x9c, 0x1b, 0x43, 0x8b, 0x80, 0xcc, 0xb9, 0x3d, 0xda, 0xc7, 0xf1, 0x8a, 0xf2, 0x6d,
1960xb8, 0xd7, 0x74, 0x2f, 0x7e, 0x1e, 0xb7, 0xd3, 0x4a, 0xb4, 0xac, 0xfc, 0x79, 0x48, 0x6c,
1970xbc, 0x96, 0xb6, 0x94, 0x46, 0x57, 0x2d, 0xb0, 0xa3, 0xfc, 0x1e, 0xb9, 0x52, 0x60, 0x85,
1980x2d, 0x41, 0xd0, 0x43, 0x01, 0x1e, 0x1c, 0xd5, 0x7d, 0xfc, 0xf3, 0x96, 0x0d, 0xc7, 0xcb,
1990x2a, 0x29, 0x9a, 0x93, 0xdd, 0x88, 0x2d, 0x37, 0x5d, 0xaa, 0xfb, 0x49, 0x68, 0xa0, 0x9c,
2000x50, 0x86, 0x7f, 0x68, 0x56, 0x57, 0xf9, 0x79, 0x18, 0x39, 0xd4, 0xe0, 0x01, 0x84, 0x33,
2010x61, 0xca, 0xa5, 0xd2, 0xd6, 0xe4, 0xc9, 0x8a, 0x4a, 0x23, 0x44, 0x4e, 0xbc, 0xf0, 0xdc,
2020x24, 0xa1, 0xa0, 0xc4, 0xe2, 0x07, 0x3c, 0x10, 0xc4, 0xb5, 0x25, 0x4b, 0x65, 0x63, 0xf4,
2030x80, 0xe7, 0xcf, 0x61, 0xb1, 0x71, 0x82, 0x21, 0x87, 0x2c, 0xf5, 0x91, 0x00, 0x32, 0x0c,
2040xec, 0xa9, 0xb5, 0x9a, 0x74, 0x85, 0xe3, 0x36, 0x8f, 0x76, 0x4f, 0x9c, 0x6d, 0xce, 0xbc,
2050xad, 0x0a, 0x4b, 0xed, 0x76, 0x04, 0xcb, 0xc3, 0xb9, 0x33, 0x9e, 0x01, 0x93, 0x96, 0x69,
2060x7d, 0xc5, 0xa2, 0x45, 0x79, 0x9b, 0x04, 0x5c, 0x84, 0x09, 0xed, 0x88, 0x43, 0xc7, 0xab,
2070x93, 0x14, 0x26, 0xa1, 0x40, 0xb5, 0xce, 0x4e, 0xbf, 0x2a, 0x42, 0x85, 0x3e, 0x2c, 0x3b,
2080x54, 0xe8, 0x12, 0x1f, 0x0e, 0x97, 0x59, 0xb2, 0x27, 0x89, 0xfa, 0xf2, 0xdf, 0x8e, 0x68,
2090x59, 0xdc, 0x06, 0xbc, 0xb6, 0x85, 0x0d, 0x06, 0x22, 0xec, 0xb1, 0xcb, 0xe5, 0x04, 0xe6,
2100x3d, 0xb3, 0xb0, 0x41, 0x73, 0x08, 0x3f, 0x3c, 0x58, 0x86, 0x63, 0xeb, 0x50, 0xee, 0x1d,
2110x2c, 0x37, 0x74, 0xa9, 0xd3, 0x18, 0xa3, 0x47, 0x6e, 0x93, 0x54, 0xad, 0x0a, 0x5d, 0xb8,
2120x2a, 0x55, 0x5d, 0x78, 0xf6, 0xee, 0xbe, 0x8e, 0x3c, 0x76, 0x69, 0xb9, 0x40, 0xc2, 0x34,
2130xec, 0x2a, 0xb9, 0xed, 0x7e, 0x20, 0xe4, 0x8d, 0x00, 0x38, 0xc7, 0xe6, 0x8f, 0x44, 0xa8,
2140x86, 0xce, 0xeb, 0x2a, 0xe9, 0x90, 0xf1, 0x4c, 0xdf, 0x32, 0xfb, 0x73, 0x1b, 0x6d, 0x92,
2150x1e, 0x95, 0xfe, 0xb4, 0xdb, 0x65, 0xdf, 0x4d, 0x23, 0x54, 0x89, 0x48, 0xbf, 0x4a, 0x2e,
2160x70, 0xd6, 0xd7, 0x62, 0xb4, 0x33, 0x29, 0xb1, 0x3a, 0x33, 0x4c, 0x23, 0x6d, 0xa6, 0x76,
2170xa5, 0x21, 0x63, 0x48, 0xe6, 0x90, 0x5d, 0xed, 0x90, 0x95, 0x0b, 0x7a, 0x84, 0xbe, 0xb8,
2180x0d, 0x5e, 0x63, 0x0c, 0x62, 0x26, 0x4c, 0x14, 0x5a, 0xb3, 0xac, 0x23, 0xa4, 0x74, 0xa7,
2190x6f, 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xa0, 0x28, 0xb7, 0xee, 0x19, 0x38, 0xf1, 0x64,
2200x80, 0x82, 0x43, 0xe1, 0x41, 0x27, 0x1f, 0x1f, 0x90, 0x54, 0x7a, 0xd5, 0x23, 0x2e, 0xd1,
2210x3d, 0xcb, 0x28, 0xba, 0x58, 0x7f, 0xdc, 0x7c, 0x91, 0x24, 0xe9, 0x28, 0x51, 0x83, 0x6e,
2220xc5, 0x56, 0x21, 0x42, 0xed, 0xa0, 0x56, 0x22, 0xa1, 0x40, 0x80, 0x6b, 0xa8, 0xf7, 0x94,
2230xca, 0x13, 0x6b, 0x0c, 0x39, 0xd9, 0xfd, 0xe9, 0xf3, 0x6f, 0xa6, 0x9e, 0xfc, 0x70, 0x8a,
2240xb3, 0xbc, 0x59, 0x3c, 0x1e, 0x1d, 0x6c, 0xf9, 0x7c, 0xaf, 0xf9, 0x88, 0x71, 0x95, 0xeb,
2250x57, 0x00, 0xbd, 0x9f, 0x8c, 0x4f, 0xe1, 0x24, 0x83, 0xc5, 0x22, 0xea, 0xfd, 0xd3, 0x0c,
2260xe2, 0x17, 0x18, 0x7c, 0x6a, 0x4c, 0xde, 0x77, 0xb4, 0x53, 0x9b, 0x4c, 0x81, 0xcd, 0x23,
2270x60, 0xaa, 0x0e, 0x25, 0x73, 0x9c, 0x02, 0x79, 0x32, 0x30, 0xdf, 0x74, 0xdf, 0x75, 0x19,
2280xf4, 0xa5, 0x14, 0x5c, 0xf7, 0x7a, 0xa8, 0xa5, 0x91, 0x84, 0x7c, 0x60, 0x03, 0x06, 0x3b,
2290xcd, 0x50, 0xb6, 0x27, 0x9c, 0xfe, 0xb1, 0xdd, 0xcc, 0xd3, 0xb0, 0x59, 0x24, 0xb2, 0xca,
2300xe2, 0x1c, 0x81, 0x22, 0x9d, 0x07, 0x8f, 0x8e, 0xb9, 0xbe, 0x4e, 0xfa, 0xfc, 0x39, 0x65,
2310xba, 0xbf, 0x9d, 0x12, 0x37, 0x5e, 0x97, 0x7e, 0xf3, 0x89, 0xf5, 0x5d, 0xf5, 0xe3, 0x09,
2320x8c, 0x62, 0xb5, 0x20, 0x9d, 0x0c, 0x53, 0x8a, 0x68, 0x1b, 0xd2, 0x8f, 0x75, 0x17, 0x5d,
2330xd4, 0xe5, 0xda, 0x75, 0x62, 0x19, 0x14, 0x6a, 0x26, 0x2d, 0xeb, 0xf8, 0xaf, 0x37, 0xf0,
2340x6c, 0xa4, 0x55, 0xb1, 0xbc, 0xe2, 0x33, 0xc0, 0x9a, 0xca, 0xb0, 0x11, 0x49, 0x4f, 0x68,
2350x9b, 0x3b, 0x6b, 0x3c, 0xcc, 0x13, 0xf6, 0xc7, 0x85, 0x61, 0x68, 0x42, 0xae, 0xbb, 0xdd,
2360xcd, 0x45, 0x16, 0x29, 0x1d, 0xea, 0xdb, 0xc8, 0x03, 0x94, 0x3c, 0xee, 0x4f, 0x82, 0x11,
2370xc3, 0xec, 0x28, 0xbd, 0x97, 0x05, 0x99, 0xde, 0xd7, 0xbb, 0x5e, 0x22, 0x1f, 0xd4, 0xeb,
2380x64, 0xd9, 0x92, 0xd9, 0x85, 0xb7, 0x6a, 0x05, 0x6a, 0xe4, 0x24, 0x41, 0xf1, 0xcd, 0xf0,
2390xd8, 0x3f, 0xf8, 0x9e, 0x0e, 0xcd, 0x0b, 0x7a, 0x70, 0x6b, 0x5a, 0x75, 0x0a, 0x6a, 0x33,
2400x88, 0xec, 0x17, 0x75, 0x08, 0x70, 0x10, 0x2f, 0x24, 0xcf, 0xc4, 0xe9, 0x42, 0x00, 0x61,
2410x94, 0xca, 0x1f, 0x3a, 0x76, 0x06, 0xfa, 0xd2, 0x48, 0x81, 0xf0, 0x77, 0x60, 0x03, 0x45,
2420xd9, 0x61, 0xf4, 0xa4, 0x6f, 0x3d, 0xd9, 0x30, 0xc3, 0x04, 0x6b, 0x54, 0x2a, 0xb7, 0xec,
2430x3b, 0xf4, 0x4b, 0xf5, 0x68, 0x52, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5,
2440xa9, 0xb1, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xa5, 0xa9, 0xb1,
2450xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0xeb, 0x54, 0x0b,
2460x75, 0x68, 0x52, 0x07, 0x8c, 0x9a, 0x97, 0x8d, 0x79, 0x70, 0x62, 0x46, 0xef, 0x5c, 0x1b,
2470x95, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x67, 0x4c, 0x1a, 0xb6,
2480xcf, 0xfd, 0x78, 0x53, 0x24, 0xab, 0xb5, 0xc9, 0xf1, 0x60, 0x23, 0xa5, 0xc8, 0x12, 0x87,
2490x6d, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xc7, 0x0c, 0x9a, 0x97, 0xac,
2500xda, 0x36, 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x47,
2510xed, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8c, 0x7b, 0x55, 0x09, 0x90, 0xa2, 0xc6, 0xef,
2520x3d, 0xf8, 0x53, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xdf,
2530x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x59, 0x30, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x53, 0x05, 0x69,
2540x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0xb0, 0xe2, 0x27, 0xcc, 0xfb, 0x74,
2550x4b, 0x14, 0x8b, 0x94, 0x8b, 0x75, 0x68, 0x33, 0xc5, 0x08, 0x92, 0x87, 0x8c, 0x9a, 0xb6,
2560xcf, 0x1c, 0xba, 0xd7, 0x0d, 0x98, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0x89, 0x71, 0x60,
2570x23, 0xc4, 0x0a, 0x96, 0x8f, 0x9c, 0xba, 0xf6, 0x6e, 0x3f, 0xfc, 0x5b, 0x15, 0xa8, 0xd2,
2580x26, 0xaf, 0xbd, 0xf8, 0x72, 0x66, 0x2f, 0xdc, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa,
2590xb7, 0xcd, 0xf9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6f, 0x3d, 0xd9, 0x30, 0xe2, 0x27, 0xcc,
2600xfb, 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x70, 0x43, 0x04, 0x6b, 0x35, 0xc9, 0xf1,
2610x60, 0x23, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xe6, 0x2f, 0xbd,
2620xf8, 0x72, 0x66, 0x4e, 0x1e, 0xbe, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x1d, 0x99, 0x91, 0xa0,
2630xa3, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93, 0xa4, 0xab, 0xd4, 0x0b, 0x75, 0x49, 0x10, 0xa2,
2640xc6, 0xef, 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xb5, 0xe8, 0x33, 0xe4, 0x4a, 0x16, 0xae, 0xde,
2650x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xb3, 0xc5, 0x08, 0x73, 0x45, 0xe9, 0x31, 0xc1, 0xe1, 0x21,
2660xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x86, 0x6f, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, 0x93, 0xa4, 0xca,
2670x16, 0xae, 0xde, 0x1f, 0x9d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x72, 0x47, 0x0c,
2680x9a, 0xb6, 0xcf, 0xfd, 0x59, 0x11, 0xa0, 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87,
2690x6d, 0x39, 0xf0, 0x43, 0x04, 0x8a, 0x96, 0xae, 0xde, 0x3e, 0xdf, 0x1d, 0x99, 0x91, 0xa0,
2700xc2, 0x06, 0x6f, 0x3d, 0xf8, 0x72, 0x47, 0x0c, 0x9a, 0x97, 0x8d, 0x98, 0x93, 0x85, 0x88,
2710x73, 0x45, 0xe9, 0x31, 0xe0, 0x23, 0xa5, 0xa9, 0xd0, 0x03, 0x84, 0x8a, 0x96, 0xae, 0xde,
2720x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xd2, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x82,
2730x67, 0x2d, 0xd8, 0x13, 0xa4, 0xab, 0xd4, 0x0b, 0x94, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20,
2740xa3, 0xa5, 0xc8, 0xf3, 0x45, 0xe9, 0x50, 0x22, 0xc6, 0xef, 0x5c, 0x3a, 0xd7, 0x0d, 0x98,
2750x93, 0x85, 0x88, 0x73, 0x64, 0x4a, 0xf7, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0x0a, 0x96,
2760xae, 0xde, 0x3e, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x78, 0x72,
2770x66, 0x2f, 0xbd, 0xd9, 0x30, 0xc3, 0xe5, 0x48, 0x12, 0x87, 0x8c, 0x7b, 0x55, 0x28, 0xd2,
2780x07, 0x8c, 0x9a, 0x97, 0xac, 0xda, 0x17, 0x8d, 0x79, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x54,
2790x0b, 0x94, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, 0x26, 0xaf,
2800xdc, 0x1b, 0xb4, 0xea, 0x37, 0xec, 0x3b, 0xf4, 0x6a, 0x37, 0xcd, 0x18, 0x93, 0x85, 0x69,
2810x31, 0xc1, 0xe1, 0x40, 0xe3, 0x25, 0xc8, 0x12, 0x87, 0x8c, 0x9a, 0xb6, 0xcf, 0xfd, 0x59,
2820x11, 0xa0, 0xc2, 0x06, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x37,
2830xec, 0x5a, 0x36, 0xee, 0x3f, 0xfc, 0x7a, 0x76, 0x4f, 0x1c, 0x9b, 0x95, 0x89, 0x71, 0x41,
2840x00, 0x63, 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x0f, 0x9c, 0xba, 0xd7, 0x0d, 0x98, 0x93, 0x85,
2850x69, 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x9e, 0xbe, 0xdf, 0x3c, 0xfa, 0x57, 0x2c, 0xda,
2860x36, 0xee, 0x3f, 0xfc, 0x5b, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d,
2870x38, 0xf2, 0x47, 0xed, 0x58, 0x13, 0xa4, 0xca, 0xf7, 0x4d, 0xf9, 0x51, 0x01, 0x80, 0x63,
2880x44, 0xeb, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xa9, 0xb1,
2890xe0, 0x42, 0x06, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0x0a, 0x96, 0x8f, 0x7d,
2900x78, 0x72, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0xbc, 0xfa, 0x57, 0x0d,
2910x79, 0x51, 0x01, 0x61, 0x21, 0xa1, 0xc0, 0xe3, 0x25, 0xa9, 0xb1, 0xc1, 0xe1, 0x40, 0x02,
2920x67, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xd6, 0x0f, 0x9c, 0x9b,
2930xb4, 0xcb, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x35, 0xc9, 0xf1,
2940x60, 0x42, 0x06, 0x8e, 0x7f, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xfc, 0x7a, 0x76, 0x6e, 0x5e,
2950x3e, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xc0, 0xe3, 0x44,
2960xeb, 0x54, 0x2a, 0xb7, 0xcd, 0xf9, 0x70, 0x62, 0x27, 0xad, 0xd8, 0x32, 0xc7, 0x0c, 0x7b,
2970x74, 0x4b, 0x14, 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x6d, 0x39, 0xd1, 0x20,
2980xc2, 0xe7, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0xb2, 0xc7, 0x0c, 0x59, 0x28, 0xf3, 0x9b };
299
300// clang-format off
diff --git a/keyboards/ploopyco/trackball/rules.mk b/keyboards/ploopyco/trackball/rules.mk
index e1eb998fe..4ac92ebf6 100644
--- a/keyboards/ploopyco/trackball/rules.mk
+++ b/keyboards/ploopyco/trackball/rules.mk
@@ -24,6 +24,6 @@ POINTING_DEVICE_ENABLE = yes
24MOUSEKEY_ENABLE = yes # Mouse keys 24MOUSEKEY_ENABLE = yes # Mouse keys
25 25
26QUANTUM_LIB_SRC += analog.c spi_master.c 26QUANTUM_LIB_SRC += analog.c spi_master.c
27SRC += pmw3360.c opt_encoder.c 27SRC += drivers/sensors/pmw3360.c opt_encoder.c
28 28
29DEFAULT_FOLDER = ploopyco/trackball/rev1_005 29DEFAULT_FOLDER = ploopyco/trackball/rev1_005
diff --git a/keyboards/ploopyco/trackball/trackball.h b/keyboards/ploopyco/trackball/trackball.h
index fd2bf465a..70f5d83b1 100644
--- a/keyboards/ploopyco/trackball/trackball.h
+++ b/keyboards/ploopyco/trackball/trackball.h
@@ -20,7 +20,7 @@
20 20
21#include "quantum.h" 21#include "quantum.h"
22#include "spi_master.h" 22#include "spi_master.h"
23#include "pmw3360.h" 23#include "drivers/sensors/pmw3360.h"
24#include "analog.h" 24#include "analog.h"
25#include "opt_encoder.h" 25#include "opt_encoder.h"
26#include "pointing_device.h" 26#include "pointing_device.h"
diff --git a/keyboards/ploopyco/trackball_mini/rules.mk b/keyboards/ploopyco/trackball_mini/rules.mk
index 58fad239f..22c5e3c06 100644
--- a/keyboards/ploopyco/trackball_mini/rules.mk
+++ b/keyboards/ploopyco/trackball_mini/rules.mk
@@ -27,6 +27,6 @@ POINTING_DEVICE_ENABLE = yes
27MOUSEKEY_ENABLE = no # Mouse keys 27MOUSEKEY_ENABLE = no # Mouse keys
28 28
29QUANTUM_LIB_SRC += analog.c 29QUANTUM_LIB_SRC += analog.c
30SRC += adns5050.c opt_encoder.c 30SRC += drivers/sensors/adns5050.c opt_encoder.c
31 31
32DEFAULT_FOLDER = ploopyco/trackball_mini/rev1_001 32DEFAULT_FOLDER = ploopyco/trackball_mini/rev1_001
diff --git a/keyboards/ploopyco/trackball_mini/trackball_mini.h b/keyboards/ploopyco/trackball_mini/trackball_mini.h
index b9754cbc7..da1b51b17 100644
--- a/keyboards/ploopyco/trackball_mini/trackball_mini.h
+++ b/keyboards/ploopyco/trackball_mini/trackball_mini.h
@@ -20,7 +20,7 @@
20#pragma once 20#pragma once
21 21
22#include "quantum.h" 22#include "quantum.h"
23#include "adns5050.h" 23#include "drivers/sensors/adns5050.h"
24#include "analog.h" 24#include "analog.h"
25#include "opt_encoder.h" 25#include "opt_encoder.h"
26#include "pointing_device.h" 26#include "pointing_device.h"
diff --git a/keyboards/ploopyco/trackball_nano/rules.mk b/keyboards/ploopyco/trackball_nano/rules.mk
index 0286194b9..f47c31615 100644
--- a/keyboards/ploopyco/trackball_nano/rules.mk
+++ b/keyboards/ploopyco/trackball_nano/rules.mk
@@ -27,6 +27,6 @@ POINTING_DEVICE_ENABLE = yes
27MOUSEKEY_ENABLE = no # Mouse keys 27MOUSEKEY_ENABLE = no # Mouse keys
28 28
29QUANTUM_LIB_SRC += analog.c 29QUANTUM_LIB_SRC += analog.c
30SRC += adns5050.c opt_encoder.c 30SRC += drivers/sensors/adns5050.c opt_encoder.c
31 31
32DEFAULT_FOLDER = ploopyco/trackball_nano/rev1_001 32DEFAULT_FOLDER = ploopyco/trackball_nano/rev1_001
diff --git a/keyboards/ploopyco/trackball_nano/trackball_nano.h b/keyboards/ploopyco/trackball_nano/trackball_nano.h
index 5692383b1..6c8ecace7 100644
--- a/keyboards/ploopyco/trackball_nano/trackball_nano.h
+++ b/keyboards/ploopyco/trackball_nano/trackball_nano.h
@@ -20,7 +20,7 @@
20#pragma once 20#pragma once
21 21
22#include "quantum.h" 22#include "quantum.h"
23#include "adns5050.h" 23#include "drivers/sensors/adns5050.h"
24#include "analog.h" 24#include "analog.h"
25#include "opt_encoder.h" 25#include "opt_encoder.h"
26#include "pointing_device.h" 26#include "pointing_device.h"
diff --git a/layouts/community/ergodox/drashna/config.h b/layouts/community/ergodox/drashna/config.h
index 4ccba8f04..f9daf277f 100644
--- a/layouts/community/ergodox/drashna/config.h
+++ b/layouts/community/ergodox/drashna/config.h
@@ -47,3 +47,4 @@
47 47
48#define PIMORONI_TRACKBALL_INVERT_X 48#define PIMORONI_TRACKBALL_INVERT_X
49#define PIMORONI_TRACKBALL_INVERT_Y 49#define PIMORONI_TRACKBALL_INVERT_Y
50#define PIMORONI_TRACKBALL_CLICK
diff --git a/users/drashna/drashna.h b/users/drashna/drashna.h
index e66f10657..e37c73bb2 100644
--- a/users/drashna/drashna.h
+++ b/users/drashna/drashna.h
@@ -33,7 +33,7 @@
33# include "oled_stuff.h" 33# include "oled_stuff.h"
34#endif 34#endif
35#if defined(PIMORONI_TRACKBALL_ENABLE) 35#if defined(PIMORONI_TRACKBALL_ENABLE)
36# include "pimoroni_trackball.h" 36# include "drivers/sensors/pimoroni_trackball.h"
37#endif 37#endif
38 38
39/* Define layer names */ 39/* Define layer names */
diff --git a/users/drashna/pimoroni_trackball.c b/users/drashna/pimoroni_trackball.c
deleted file mode 100644
index a6ca6c996..000000000
--- a/users/drashna/pimoroni_trackball.c
+++ /dev/null
@@ -1,151 +0,0 @@
1/* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "pimoroni_trackball.h"
18#include "i2c_master.h"
19
20static uint8_t scrolling = 0;
21static int16_t x_offset = 0;
22static int16_t y_offset = 0;
23static int16_t h_offset = 0;
24static int16_t v_offset = 0;
25static float precisionSpeed = 1;
26
27#ifndef I2C_TIMEOUT
28# define I2C_TIMEOUT 100
29#endif
30#ifndef MOUSE_DEBOUNCE
31# define MOUSE_DEBOUNCE 5
32#endif
33
34void trackball_set_rgbw(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
35 uint8_t data[] = {0x00, red, green, blue, white};
36 i2c_transmit(TRACKBALL_ADDRESS << 1, data, sizeof(data), I2C_TIMEOUT);
37}
38
39int16_t mouse_offset(uint8_t positive, uint8_t negative, int16_t scale) {
40 int16_t offset = (int16_t)positive - (int16_t)negative;
41 int16_t magnitude = (int16_t)(scale * offset * offset * precisionSpeed);
42 return offset < 0 ? -magnitude : magnitude;
43}
44
45void update_member(int8_t* member, int16_t* offset) {
46 if (*offset > 127) {
47 *member = 127;
48 *offset -= 127;
49 } else if (*offset < -127) {
50 *member = -127;
51 *offset += 127;
52 } else {
53 *member = *offset;
54 *offset = 0;
55 }
56}
57
58__attribute__((weak)) void trackball_check_click(bool pressed, report_mouse_t* mouse) {
59 if (pressed) {
60 mouse->buttons |= MOUSE_BTN1;
61 } else {
62 mouse->buttons &= ~MOUSE_BTN1;
63 }
64}
65
66void trackball_register_button(bool pressed, enum mouse_buttons button) {
67 report_mouse_t currentReport = pointing_device_get_report();
68 if (pressed) {
69 currentReport.buttons |= button;
70 } else {
71 currentReport.buttons &= ~button;
72 }
73 pointing_device_set_report(currentReport);
74}
75
76float trackball_get_precision(void) { return precisionSpeed; }
77void trackball_set_precision(float precision) { precisionSpeed = precision; }
78bool trackball_is_scrolling(void) { return scrolling; }
79void trackball_set_scrolling(bool scroll) { scrolling = scroll; }
80
81bool has_report_changed (report_mouse_t first, report_mouse_t second) {
82 return !(
83 (!first.buttons && first.buttons == second.buttons) &&
84 (!first.x && first.x == second.x) &&
85 (!first.y && first.y == second.y) &&
86 (!first.h && first.h == second.h) &&
87 (!first.v && first.v == second.v) );
88}
89
90
91__attribute__((weak)) void pointing_device_init(void) { trackball_set_rgbw(0x00, 0x00, 0x00, 0x4F); }
92
93void pointing_device_task(void) {
94 static bool debounce;
95 static uint16_t debounce_timer;
96 uint8_t state[5] = {};
97 if (i2c_readReg(TRACKBALL_ADDRESS << 1, 0x04, state, 5, I2C_TIMEOUT) == I2C_STATUS_SUCCESS) {
98 if (!state[4] && !debounce) {
99 if (scrolling) {
100#ifdef PIMORONI_TRACKBALL_INVERT_X
101 h_offset += mouse_offset(state[2], state[3], 1);
102#else
103 h_offset -= mouse_offset(state[2], state[3], 1);
104#endif
105#ifdef PIMORONI_TRACKBALL_INVERT_Y
106 v_offset += mouse_offset(state[1], state[0], 1);
107#else
108 v_offset -= mouse_offset(state[1], state[0], 1);
109#endif
110 } else {
111#ifdef PIMORONI_TRACKBALL_INVERT_X
112 x_offset -= mouse_offset(state[2], state[3], 5);
113#else
114 x_offset += mouse_offset(state[2], state[3], 5);
115#endif
116#ifdef PIMORONI_TRACKBALL_INVERT_Y
117 y_offset -= mouse_offset(state[1], state[0], 5);
118#else
119 y_offset += mouse_offset(state[1], state[0], 5);
120#endif
121 }
122 } else {
123 if (state[4]) {
124 debounce = true;
125 debounce_timer = timer_read();
126 }
127 }
128 }
129
130 if (timer_elapsed(debounce_timer) > MOUSE_DEBOUNCE) debounce = false;
131
132 report_mouse_t mouse = pointing_device_get_report();
133
134 trackball_check_click(state[4] & (1 << 7), &mouse);
135
136#ifndef PIMORONI_TRACKBALL_ROTATE
137 update_member(&mouse.x, &x_offset);
138 update_member(&mouse.y, &y_offset);
139 update_member(&mouse.h, &h_offset);
140 update_member(&mouse.v, &v_offset);
141#else
142 update_member(&mouse.x, &y_offset);
143 update_member(&mouse.y, &x_offset);
144 update_member(&mouse.h, &v_offset);
145 update_member(&mouse.v, &h_offset);
146#endif
147 pointing_device_set_report(mouse);
148 if (has_report_changed(mouse, pointing_device_get_report())) {
149 pointing_device_send();
150 }
151}
diff --git a/users/drashna/rules.mk b/users/drashna/rules.mk
index b79051508..fa4fb2420 100644
--- a/users/drashna/rules.mk
+++ b/users/drashna/rules.mk
@@ -74,7 +74,7 @@ endif
74ifeq ($(strip $(PIMORONI_TRACKBALL_ENABLE)), yes) 74ifeq ($(strip $(PIMORONI_TRACKBALL_ENABLE)), yes)
75 POINTING_DEVICE_ENABLE := yes 75 POINTING_DEVICE_ENABLE := yes
76 OPT_DEFS += -DPIMORONI_TRACKBALL_ENABLE 76 OPT_DEFS += -DPIMORONI_TRACKBALL_ENABLE
77 SRC += pimoroni_trackball.c 77 SRC += drivers/sensors/pimoroni_trackball.c
78 QUANTUM_LIB_SRC += i2c_master.c 78 QUANTUM_LIB_SRC += i2c_master.c
79endif 79endif
80 80