diff options
author | Drashna Jaelre <drashna@live.com> | 2020-12-19 10:43:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-19 19:43:00 +0100 |
commit | 5619b1d3db335750bed394b0d27980d67f4f50c5 (patch) | |
tree | 854f8fa7cb055193aa481e1e601ae58403e9ee9f | |
parent | bded5f473c887fb36a2ca9d473635c1b84d0a04b (diff) | |
download | qmk_firmware-5619b1d3db335750bed394b0d27980d67f4f50c5.tar.gz qmk_firmware-5619b1d3db335750bed394b0d27980d67f4f50c5.zip |
[Keyboard] Add drashna's dactyl manuform 5x6 with trackball (#11062)
Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
Co-authored-by: Erovia <Erovia@users.noreply.github.com>
17 files changed, 1842 insertions, 0 deletions
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.c b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.c new file mode 100644 index 000000000..c40e4173d --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.c | |||
@@ -0,0 +1,221 @@ | |||
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 "5x6_right_trackball.h" | ||
18 | |||
19 | #ifndef TRACKBALL_DPI_OPTIONS | ||
20 | # define TRACKBALL_DPI_OPTIONS { 1200, 1600, 2400 } | ||
21 | # ifndef TRACKBALL_DPI_DEFAULT | ||
22 | # define TRACKBALL_DPI_DEFAULT 1 | ||
23 | # endif | ||
24 | #endif | ||
25 | #ifndef TRACKBALL_DPI_DEFAULT | ||
26 | # define TRACKBALL_DPI_DEFAULT 0 | ||
27 | #endif | ||
28 | |||
29 | keyboard_config_t keyboard_config; | ||
30 | uint16_t dpi_array[] = TRACKBALL_DPI_OPTIONS; | ||
31 | #define DPI_OPTION_SIZE (sizeof(dpi_array) / sizeof(uint16_t)) | ||
32 | |||
33 | bool BurstState = false; // init burst state for Trackball module | ||
34 | uint16_t MotionStart = 0; // Timer for accel, 0 is resting state | ||
35 | |||
36 | __attribute__((weak)) void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y) { | ||
37 | mouse_report->x = x; | ||
38 | mouse_report->y = y; | ||
39 | } | ||
40 | |||
41 | __attribute__((weak)) void process_mouse(report_mouse_t* mouse_report) { | ||
42 | report_pmw_t data = pmw_read_burst(); | ||
43 | if (data.isOnSurface && data.isMotion) { | ||
44 | // Reset timer if stopped moving | ||
45 | if (!data.isMotion) { | ||
46 | if (MotionStart != 0) MotionStart = 0; | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | // Set timer if new motion | ||
51 | if ((MotionStart == 0) && data.isMotion) { | ||
52 | if (debug_mouse) dprintf("Starting motion.\n"); | ||
53 | MotionStart = timer_read(); | ||
54 | } | ||
55 | |||
56 | if (debug_mouse) { | ||
57 | dprintf("Delt] d: %d t: %u\n", abs(data.dx) + abs(data.dy), MotionStart); | ||
58 | } | ||
59 | if (debug_mouse) { | ||
60 | dprintf("Pre ] X: %d, Y: %d\n", data.dx, data.dy); | ||
61 | } | ||
62 | #if defined(PROFILE_LINEAR) | ||
63 | float scale = float(timer_elaspsed(MotionStart)) / 1000.0; | ||
64 | data.dx *= scale; | ||
65 | data.dy *= scale; | ||
66 | #elif defined(PROFILE_INVERSE) | ||
67 | // TODO | ||
68 | #else | ||
69 | // no post processing | ||
70 | #endif | ||
71 | |||
72 | // Wrap to HID size | ||
73 | data.dx = constrain(data.dx, -127, 127); | ||
74 | data.dy = constrain(data.dy, -127, 127); | ||
75 | if (debug_mouse) dprintf("Cons] X: %d, Y: %d\n", data.dx, data.dy); | ||
76 | // dprintf("Elapsed:%u, X: %f Y: %\n", i, pgm_read_byte(firmware_data+i)); | ||
77 | |||
78 | mouse_report->x = -data.dx; | ||
79 | mouse_report->y = data.dy; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | bool process_record_kb(uint16_t keycode, keyrecord_t* record) { | ||
84 | if (!process_record_user(keycode, record)) { return false; } | ||
85 | |||
86 | #ifdef POINTING_DEVICE_ENABLE | ||
87 | if (keycode == DPI_CONFIG && record->event.pressed) { | ||
88 | keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE; | ||
89 | eeconfig_update_kb(keyboard_config.raw); | ||
90 | trackball_set_cpi(dpi_array[keyboard_config.dpi_config]); | ||
91 | } | ||
92 | #endif | ||
93 | |||
94 | /* If Mousekeys is disabled, then use handle the mouse button | ||
95 | * keycodes. This makes things simpler, and allows usage of | ||
96 | * the keycodes in a consistent manner. But only do this if | ||
97 | * Mousekeys is not enable, so it's not handled twice. | ||
98 | */ | ||
99 | #ifndef MOUSEKEY_ENABLE | ||
100 | if (IS_MOUSEKEY_BUTTON(keycode)) { | ||
101 | report_mouse_t currentReport = pointing_device_get_report(); | ||
102 | if (record->event.pressed) { | ||
103 | currentReport.buttons |= 1 << (keycode - KC_MS_BTN1); | ||
104 | } else { | ||
105 | currentReport.buttons &= ~(1 << (keycode - KC_MS_BTN1)); | ||
106 | } | ||
107 | pointing_device_set_report(currentReport); | ||
108 | pointing_device_send(); | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | return true; | ||
113 | } | ||
114 | |||
115 | // Hardware Setup | ||
116 | void keyboard_pre_init_kb(void) { | ||
117 | // debug_enable = true; | ||
118 | // debug_matrix = true; | ||
119 | // debug_mouse = true; | ||
120 | // debug_encoder = true; | ||
121 | |||
122 | /* Ground all output pins connected to ground. This provides additional | ||
123 | * pathways to ground. If you're messing with this, know this: driving ANY | ||
124 | * of these pins high will cause a short. On the MCU. Ka-blooey. | ||
125 | */ | ||
126 | |||
127 | // This is the debug LED. | ||
128 | #if defined(DEBUG_LED_PIN) | ||
129 | setPinOutput(DEBUG_LED_PIN); | ||
130 | writePin(DEBUG_LED_PIN, debug_enable); | ||
131 | #endif | ||
132 | |||
133 | keyboard_pre_init_user(); | ||
134 | } | ||
135 | |||
136 | #ifdef POINTING_DEVICE_ENABLE | ||
137 | void pointing_device_init(void) { | ||
138 | if (!is_keyboard_left()) { | ||
139 | // initialize ball sensor | ||
140 | pmw_spi_init(); | ||
141 | } | ||
142 | trackball_set_cpi(dpi_array[keyboard_config.dpi_config]); | ||
143 | } | ||
144 | |||
145 | static bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old) { | ||
146 | return (new.buttons != old.buttons) || | ||
147 | (new.x && new.x != old.x) || | ||
148 | (new.y && new.y != old.y) || | ||
149 | (new.h && new.h != old.h) || | ||
150 | (new.v && new.v != old.v); | ||
151 | } | ||
152 | |||
153 | void pointing_device_task(void) { | ||
154 | report_mouse_t mouse_report = pointing_device_get_report(); | ||
155 | if (!is_keyboard_left()) { | ||
156 | process_mouse(&mouse_report); | ||
157 | } | ||
158 | |||
159 | pointing_device_set_report(mouse_report); | ||
160 | pointing_device_send(); | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | void eeconfig_init_kb(void) { | ||
165 | keyboard_config.dpi_config = TRACKBALL_DPI_DEFAULT; | ||
166 | trackball_set_cpi(dpi_array[keyboard_config.dpi_config]); | ||
167 | eeconfig_update_kb(keyboard_config.raw); | ||
168 | } | ||
169 | |||
170 | void matrix_init_kb(void) { | ||
171 | // is safe to just read DPI setting since matrix init | ||
172 | // comes before pointing device init. | ||
173 | keyboard_config.raw = eeconfig_read_kb(); | ||
174 | if (keyboard_config.dpi_config > DPI_OPTION_SIZE) { | ||
175 | eeconfig_init_kb(); | ||
176 | } | ||
177 | matrix_init_user(); | ||
178 | } | ||
179 | |||
180 | #ifdef POINTING_DEVICE_ENABLE | ||
181 | void pointing_device_send(void) { | ||
182 | static report_mouse_t old_report = {}; | ||
183 | report_mouse_t mouseReport = pointing_device_get_report(); | ||
184 | if (is_keyboard_master()) { | ||
185 | int8_t x = mouseReport.x, y = mouseReport.y; | ||
186 | mouseReport.x = 0; | ||
187 | mouseReport.y = 0; | ||
188 | process_mouse_user(&mouseReport, x, y); | ||
189 | if (has_mouse_report_changed(mouseReport, old_report)) { | ||
190 | host_mouse_send(&mouseReport); | ||
191 | } | ||
192 | } else { | ||
193 | master_mouse_send(mouseReport.x, mouseReport.y); | ||
194 | } | ||
195 | mouseReport.x = 0; | ||
196 | mouseReport.y = 0; | ||
197 | mouseReport.v = 0; | ||
198 | mouseReport.h = 0; | ||
199 | old_report = mouseReport; | ||
200 | pointing_device_set_report(mouseReport); | ||
201 | } | ||
202 | #endif | ||
203 | |||
204 | #ifdef SWAP_HANDS_ENABLE | ||
205 | const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { | ||
206 | /* Left hand, matrix positions */ | ||
207 | {{5, 6}, {4, 6}, {3, 6}, {2, 6}, {1, 6}, {0, 6}}, | ||
208 | {{5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7}, {0, 7}}, | ||
209 | {{5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8}}, | ||
210 | {{5, 9}, {4, 9}, {3, 9}, {2, 9}, {1, 9}, {0, 9}}, | ||
211 | {{5, 10}, {4, 10}, {3, 10}, {2, 10}, {1, 10}, {0, 10}}, | ||
212 | {{5, 11}, {4, 11}, {3, 11}, {2, 11}, {1, 11}, {0, 11}}, | ||
213 | /* Right hand, matrix positions */ | ||
214 | {{5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, | ||
215 | {{5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, | ||
216 | {{5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, | ||
217 | {{5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, | ||
218 | {{5, 4}, {4, 4}, {3, 4}, {2, 4}, {1, 4}, {0, 4}}, | ||
219 | {{5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 5}, {0, 5}} | ||
220 | }; | ||
221 | #endif | ||
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 new file mode 100644 index 000000000..c8650f73d --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/5x6_right_trackball.h | |||
@@ -0,0 +1,73 @@ | |||
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 "dactyl_manuform.h" | ||
20 | #include "quantum.h" | ||
21 | #include "spi_master.h" | ||
22 | #include "pmw3360.h" | ||
23 | #include "pointing_device.h" | ||
24 | |||
25 | |||
26 | #define ___ KC_NO | ||
27 | |||
28 | #define LAYOUT_5x6_right_trackball(\ | ||
29 | L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \ | ||
30 | L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \ | ||
31 | L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \ | ||
32 | L30, L31, L32, L33, L34, L35, R30, R31, R32, R33, R34, R35, \ | ||
33 | L42, L43, R42, R43, \ | ||
34 | L44, L45, R41, \ | ||
35 | L54, L55, R51, \ | ||
36 | L52, L53, R52, R53 \ | ||
37 | ) \ | ||
38 | { \ | ||
39 | { L00, L01, L02, L03, L04, L05 }, \ | ||
40 | { L10, L11, L12, L13, L14, L15 }, \ | ||
41 | { L20, L21, L22, L23, L24, L25 }, \ | ||
42 | { L30, L31, L32, L33, L34, L35 }, \ | ||
43 | { ___, ___, L42, L43, L44, L45 }, \ | ||
44 | { ___, ___, L52, L53, L54, L55 }, \ | ||
45 | \ | ||
46 | { R00, R01, R02, R03, R04, R05 }, \ | ||
47 | { R10, R11, R12, R13, R14, R15 }, \ | ||
48 | { R20, R21, R22, R23, R24, R25 }, \ | ||
49 | { R30, R31, R32, R33, R34, R35 }, \ | ||
50 | { ___, R41, R42, R43, ___, ___ }, \ | ||
51 | { ___, R51, R52, R53, ___, ___ } \ | ||
52 | } | ||
53 | |||
54 | |||
55 | void process_wheel(report_mouse_t* mouse_report); | ||
56 | void process_wheel_user(report_mouse_t* mouse_report, int16_t h, int16_t v); | ||
57 | |||
58 | typedef union { | ||
59 | uint32_t raw; | ||
60 | struct { | ||
61 | uint8_t dpi_config; | ||
62 | }; | ||
63 | } keyboard_config_t; | ||
64 | |||
65 | extern keyboard_config_t keyboard_config; | ||
66 | |||
67 | enum ploopy_keycodes { | ||
68 | DPI_CONFIG = SAFE_RANGE, | ||
69 | KEYMAP_SAFE_RANGE, | ||
70 | }; | ||
71 | |||
72 | void master_mouse_send(int8_t x, int8_t y); | ||
73 | void trackball_set_cpi(uint16_t cpi); | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h new file mode 100644 index 000000000..147f12600 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | Copyright 2012 Jun Wako <wakojun@gmail.com> | ||
3 | Copyright 2015 Jack Humbert | ||
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 "config_common.h" | ||
22 | |||
23 | #define PRODUCT_ID 0x3536 | ||
24 | #define DEVICE_VER 0x0001 | ||
25 | #define PRODUCT Tractyl-Manuform (5x6 with right side Trackball) | ||
26 | |||
27 | /* key matrix size */ | ||
28 | // Rows are doubled-up | ||
29 | #define MATRIX_ROWS 12 | ||
30 | #define MATRIX_COLS 6 | ||
31 | |||
32 | // wiring of each half | ||
33 | #define MATRIX_COL_PINS { C0, C1, C2, C3, C4, C5 } | ||
34 | #define MATRIX_ROW_PINS { F7, F6, F5, F4, F3, F2 } | ||
35 | |||
36 | #define DIODE_DIRECTION COL2ROW | ||
37 | |||
38 | // WS2812 RGB LED strip input and number of LEDs | ||
39 | #define RGB_DI_PIN D3 | ||
40 | #define RGBLED_NUM 8 | ||
41 | #define RGBLIGHT_SPLIT | ||
42 | #define RGBLED_SPLIT { 0 , 8 } | ||
43 | #define RGBLIGHT_SLEEP | ||
44 | #define RGBW | ||
45 | #define RGBLIGHT_LIMIT_VAL 150 | ||
46 | /* define if matrix has ghost */ | ||
47 | //#define MATRIX_HAS_GHOST | ||
48 | |||
49 | /* number of backlight levels */ | ||
50 | // #define BACKLIGHT_LEVELS 3 | ||
51 | |||
52 | #define DEBUG_LED_PIN D6 | ||
53 | |||
54 | #define USB_POLLING_INTERVAL_MS 1 | ||
55 | |||
56 | #define ROTATIONAL_TRANSFORM_ANGLE -25 | ||
57 | |||
58 | /* Bootmagic Lite key configuration */ | ||
59 | #define BOOTMAGIC_LITE_ROW 0 | ||
60 | #define BOOTMAGIC_LITE_COLUMN 0 | ||
61 | #define BOOTMAGIC_LITE_ROW_RIGHT 6 | ||
62 | #define BOOTMAGIC_LITE_COLUMN_RIGHT 5 | ||
63 | |||
64 | #define C6_AUDIO | ||
65 | |||
66 | #define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 4095 | ||
67 | #define DYNAMIC_KEYMAP_LAYER_COUNT 16 | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/info.json b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/info.json new file mode 100644 index 000000000..89f99dc23 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/info.json | |||
@@ -0,0 +1,75 @@ | |||
1 | { | ||
2 | "keyboard_name": "Dactyl Manuform 5x6", | ||
3 | "url": "", | ||
4 | "maintainer": "qmk", | ||
5 | "width": 17, | ||
6 | "height": 8, | ||
7 | "layouts": { | ||
8 | "LAYOUT_5x6": { | ||
9 | "layout": [ | ||
10 | {"label":"L00", "x":0, "y":0}, | ||
11 | {"label":"L01", "x":1, "y":0}, | ||
12 | {"label":"L02", "x":2, "y":0}, | ||
13 | {"label":"L03", "x":3, "y":0}, | ||
14 | {"label":"L04", "x":4, "y":0}, | ||
15 | {"label":"L05", "x":5, "y":0}, | ||
16 | {"label":"R00", "x":11, "y":0}, | ||
17 | {"label":"R01", "x":12, "y":0}, | ||
18 | {"label":"R02", "x":13, "y":0}, | ||
19 | {"label":"R03", "x":14, "y":0}, | ||
20 | {"label":"R04", "x":15, "y":0}, | ||
21 | {"label":"R05", "x":16, "y":0}, | ||
22 | {"label":"L10", "x":0, "y":1}, | ||
23 | {"label":"L11", "x":1, "y":1}, | ||
24 | {"label":"L12", "x":2, "y":1}, | ||
25 | {"label":"L13", "x":3, "y":1}, | ||
26 | {"label":"L14", "x":4, "y":1}, | ||
27 | {"label":"L15", "x":5, "y":1}, | ||
28 | {"label":"R10", "x":11, "y":1}, | ||
29 | {"label":"R11", "x":12, "y":1}, | ||
30 | {"label":"R12", "x":13, "y":1}, | ||
31 | {"label":"R13", "x":14, "y":1}, | ||
32 | {"label":"R14", "x":15, "y":1}, | ||
33 | {"label":"R15", "x":16, "y":1}, | ||
34 | {"label":"L20", "x":0, "y":2}, | ||
35 | {"label":"L21", "x":1, "y":2}, | ||
36 | {"label":"L22", "x":2, "y":2}, | ||
37 | {"label":"L23", "x":3, "y":2}, | ||
38 | {"label":"L24", "x":4, "y":2}, | ||
39 | {"label":"L25", "x":5, "y":2}, | ||
40 | {"label":"R20", "x":11, "y":2}, | ||
41 | {"label":"R21", "x":12, "y":2}, | ||
42 | {"label":"R22", "x":13, "y":2}, | ||
43 | {"label":"R23", "x":14, "y":2}, | ||
44 | {"label":"R24", "x":15, "y":2}, | ||
45 | {"label":"R25", "x":16, "y":2}, | ||
46 | {"label":"L30", "x":0, "y":3}, | ||
47 | {"label":"L31", "x":1, "y":3}, | ||
48 | {"label":"L32", "x":2, "y":3}, | ||
49 | {"label":"L33", "x":3, "y":3}, | ||
50 | {"label":"L34", "x":4, "y":3}, | ||
51 | {"label":"L35", "x":5, "y":3}, | ||
52 | {"label":"R30", "x":11, "y":3}, | ||
53 | {"label":"R31", "x":12, "y":3}, | ||
54 | {"label":"R32", "x":13, "y":3}, | ||
55 | {"label":"R33", "x":14, "y":3}, | ||
56 | {"label":"R34", "x":15, "y":3}, | ||
57 | {"label":"R35", "x":16, "y":3}, | ||
58 | {"label":"L42", "x":2, "y":4}, | ||
59 | {"label":"L43", "x":3, "y":4}, | ||
60 | {"label":"R42", "x":13, "y":4}, | ||
61 | {"label":"R43", "x":14, "y":4}, | ||
62 | {"label":"L44", "x":4, "y":5}, | ||
63 | {"label":"L45", "x":5, "y":5}, | ||
64 | {"label":"R41", "x":12, "y":5}, | ||
65 | {"label":"L54", "x":6, "y":6}, | ||
66 | {"label":"L55", "x":7, "y":6}, | ||
67 | {"label":"R51", "x":10, "y":6}, | ||
68 | {"label":"L52", "x":6, "y":7}, | ||
69 | {"label":"L53", "x":7, "y":7}, | ||
70 | {"label":"R52", "x":9, "y":7}, | ||
71 | {"label":"R53", "x":10, "y":7} | ||
72 | ] | ||
73 | } | ||
74 | } | ||
75 | } | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/config.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/config.h new file mode 100644 index 000000000..4e35d4c4f --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/config.h | |||
@@ -0,0 +1,27 @@ | |||
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 | |||
18 | |||
19 | #pragma once | ||
20 | |||
21 | |||
22 | #define USE_SERIAL | ||
23 | |||
24 | #define MASTER_LEFT | ||
25 | // #define MASTER_RIGHT | ||
26 | //#define EE_HANDS | ||
27 | // Rows are doubled-up | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/keymap.c b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/keymap.c new file mode 100644 index 000000000..7550b1fd8 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/default/keymap.c | |||
@@ -0,0 +1,63 @@ | |||
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 QMK_KEYBOARD_H | ||
18 | |||
19 | |||
20 | #define _QWERTY 0 | ||
21 | #define _LOWER 1 | ||
22 | #define _RAISE 2 | ||
23 | |||
24 | #define RAISE MO(_RAISE) | ||
25 | #define LOWER MO(_LOWER) | ||
26 | |||
27 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
28 | |||
29 | [_QWERTY] = LAYOUT_5x6_right_trackball( | ||
30 | KC_ESC , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,KC_BSPC, | ||
31 | KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,KC_MINS, | ||
32 | KC_LSFT, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L ,KC_SCLN,KC_QUOT, | ||
33 | KC_LCTL, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_BSLASH, | ||
34 | KC_LBRC,KC_RBRC, KC_EQL, | ||
35 | RAISE,KC_SPC, LOWER, | ||
36 | KC_TAB,KC_HOME, KC_END, KC_DEL, | ||
37 | KC_BSPC, KC_GRV, KC_LGUI, KC_LALT | ||
38 | ), | ||
39 | |||
40 | [_LOWER] = LAYOUT_5x6_right_trackball( | ||
41 | |||
42 | KC_TILD,KC_EXLM, KC_AT ,KC_HASH,KC_DLR ,KC_PERC, KC_CIRC,KC_AMPR,KC_ASTR,KC_LPRN,KC_RPRN,KC_DEL, | ||
43 | _______,_______,_______,_______,_______,KC_LBRC, KC_RBRC, KC_P7 , KC_P8 , KC_P9 ,_______,KC_PLUS, | ||
44 | _______,KC_HOME,KC_PGUP,KC_PGDN,KC_END ,KC_LPRN, KC_RPRN, KC_P4 , KC_P5 , KC_P6 ,KC_MINS,KC_PIPE, | ||
45 | _______,_______,_______,_______,_______,_______, _______, KC_P1 , KC_P2 , KC_P3 ,KC_EQL ,KC_UNDS, | ||
46 | _______,KC_PSCR, KC_P0, | ||
47 | _______,_______, _______, | ||
48 | _______,_______, _______,_______, | ||
49 | _______,_______, _______,_______ | ||
50 | |||
51 | ), | ||
52 | |||
53 | [_RAISE] = LAYOUT_5x6_right_trackball( | ||
54 | KC_F12 , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 ,KC_F10 ,KC_F11 , | ||
55 | _______,_______,_______,_______,_______,KC_LBRC, KC_RBRC,_______,KC_NLCK,KC_INS ,KC_SLCK,KC_MUTE, | ||
56 | _______,KC_LEFT,KC_UP ,KC_DOWN,KC_RGHT,KC_LPRN, KC_RPRN,KC_MPRV,KC_MPLY,KC_MNXT,_______,KC_VOLU, | ||
57 | _______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,KC_VOLD, | ||
58 | _______,_______, _______, | ||
59 | _______,_______, _______, | ||
60 | _______,_______, _______,_______, | ||
61 | _______,_______, _______,_______ | ||
62 | ), | ||
63 | }; | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/config.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/config.h new file mode 100644 index 000000000..78dff3896 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/config.h | |||
@@ -0,0 +1,28 @@ | |||
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 | // #define USE_I2C | ||
20 | |||
21 | #define EE_HANDS | ||
22 | #define TRACKBALL_DPI_OPTIONS \ | ||
23 | { 1200, 1800, 2600, 3400 } | ||
24 | |||
25 | #define RGBLIGHT_EFFECT_TWINKLE_LIFE 50 | ||
26 | #define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1/63 | ||
27 | |||
28 | #define SOLENOID_PIN F1 | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/keymap.c b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/keymap.c new file mode 100644 index 000000000..ca9733b6e --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/keymap.c | |||
@@ -0,0 +1,197 @@ | |||
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 "drashna.h" | ||
18 | |||
19 | #define TG_DBLO TG(_DIABLO) | ||
20 | #define _MOUSE _MEDIA | ||
21 | |||
22 | |||
23 | // clang-format off | ||
24 | #define LAYOUT_5x6_right_trackball_wrapper(...) LAYOUT_5x6_right_trackball(__VA_ARGS__) | ||
25 | #define LAYOUT_5x6_right_trackball_base( \ | ||
26 | K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, \ | ||
27 | K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, \ | ||
28 | K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A \ | ||
29 | ) \ | ||
30 | LAYOUT_5x6_right_trackball_wrapper( \ | ||
31 | KC_GRV, ________________NUMBER_LEFT________________, ________________NUMBER_RIGHT_______________, KC_MINS, \ | ||
32 | KC_ESC, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, KC_BSLS, \ | ||
33 | LALT_T(KC_TAB), K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, RALT_T(KC_QUOT), \ | ||
34 | OS_LSFT, CTL_T(K21), K22, K23, K24, K25, K26, K27, K28, K29, RCTL_T(K2A), OS_RSFT, \ | ||
35 | OS_LALT, OS_LGUI, TG_GAME, TG_DBLO, \ | ||
36 | OS_LGUI, KC_GRV, OS_RGUI, \ | ||
37 | KC_SPC, _______, KC_ENT, \ | ||
38 | BK_LWER, MO(_MOUSE), MO(_MOUSE), DL_RAIS \ | ||
39 | ) | ||
40 | #define LAYOUT_5x6_right_trackball_base_wrapper(...) LAYOUT_5x6_right_trackball_base(__VA_ARGS__) | ||
41 | |||
42 | |||
43 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
44 | [_QWERTY] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
45 | _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, | ||
46 | _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, | ||
47 | _________________QWERTY_L3_________________, _________________QWERTY_R3_________________ | ||
48 | ), | ||
49 | |||
50 | [_COLEMAK] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
51 | _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, | ||
52 | _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, | ||
53 | _________________COLEMAK_L3________________, _________________COLEMAK_R3________________ | ||
54 | ), | ||
55 | |||
56 | [_DVORAK] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
57 | _________________DVORAK_L1_________________, _________________DVORAK_R1_________________, | ||
58 | _________________DVORAK_L2_________________, _________________DVORAK_R2_________________, | ||
59 | _________________DVORAK_L3_________________, _________________DVORAK_R3_________________ | ||
60 | ), | ||
61 | |||
62 | [_WORKMAN] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
63 | _________________WORKMAN_L1________________, _________________WORKMAN_R1________________, | ||
64 | _________________WORKMAN_L2________________, _________________WORKMAN_R2________________, | ||
65 | _________________WORKMAN_L3________________, _________________WORKMAN_R3________________ | ||
66 | ), | ||
67 | |||
68 | [_NORMAN] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
69 | _________________NORMAN_L1_________________, _________________NORMAN_L1_________________, | ||
70 | _________________NORMAN_L2_________________, _________________NORMAN_R2_________________, | ||
71 | _________________NORMAN_L3_________________, _________________NORMAN_R3_________________ | ||
72 | ), | ||
73 | |||
74 | [_MALTRON] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
75 | _________________MALTRON_L1________________, _________________MALTRON_R1________________, | ||
76 | _________________MALTRON_L2________________, _________________MALTRON_R2________________, | ||
77 | _________________MALTRON_L3________________, _________________MALTRON_R3________________ | ||
78 | ), | ||
79 | |||
80 | [_EUCALYN] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
81 | _________________EUCALYN_L1________________, _________________EUCALYN_R1________________, | ||
82 | _________________EUCALYN_L2________________, _________________EUCALYN_R2________________, | ||
83 | _________________EUCALYN_L3________________, _________________EUCALYN_R3________________ | ||
84 | ), | ||
85 | |||
86 | [_CARPLAX] = LAYOUT_5x6_right_trackball_base_wrapper( | ||
87 | _____________CARPLAX_QFMLWY_L1_____________, _____________CARPLAX_QFMLWY_R1_____________, | ||
88 | _____________CARPLAX_QFMLWY_L2_____________, _____________CARPLAX_QFMLWY_R2_____________, | ||
89 | _____________CARPLAX_QFMLWY_L3_____________, _____________CARPLAX_QFMLWY_R3_____________ | ||
90 | ), | ||
91 | |||
92 | [_MOUSE] = LAYOUT_5x6_right_trackball( | ||
93 | _______, _______, _______, _______, _______, _______, DPI_CONFIG, _______, _______, _______, _______, _______, | ||
94 | _______, _______, _______, _______, _______, _______, KC_WH_U, _______, _______, _______, _______, _______, | ||
95 | _______, _______, _______, _______, _______, _______, KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, _______, _______, | ||
96 | _______, _______, _______, _______, _______, _______, _______, KC_BTN4, KC_BTN5, _______, _______, _______, | ||
97 | _______, _______, _______, _______, | ||
98 | _______, _______, _______, | ||
99 | _______, _______, _______, | ||
100 | _______, _______, _______, _______ | ||
101 | ), | ||
102 | [_GAMEPAD] = LAYOUT_5x6_right_trackball( | ||
103 | KC_ESC, KC_NO, KC_1, KC_2, KC_3, KC_4, DPI_CONFIG, _______, _______, _______, _______, _______, | ||
104 | KC_F1, KC_K, KC_Q, KC_W, KC_E, KC_R, KC_WH_U, _______, _______, _______, _______, _______, | ||
105 | KC_TAB, KC_G, KC_A, KC_S, KC_D, KC_F, KC_WH_D, KC_BTN1, KC_BTN3, KC_BTN2, _______, _______, | ||
106 | KC_LCTL, KC_LSFT, KC_Z, KC_X, KC_C, KC_H, _______, KC_BTN4, KC_BTN5, _______, _______, _______, | ||
107 | KC_I, KC_T, TG_GAME, KC_NO, | ||
108 | KC_V, KC_O, _______, | ||
109 | KC_SPC, KC_P, _______, | ||
110 | KC_H, KC_LGUI, _______, _______ | ||
111 | ), | ||
112 | [_DIABLO] = LAYOUT_5x6_right_trackball( | ||
113 | KC_ESC, KC_V, KC_D, KC_LALT, KC_NO, KC_NO, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_NO, | ||
114 | KC_TAB, KC_S, KC_I, KC_F, KC_M, KC_T, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, | ||
115 | KC_Q, KC_1, KC_2, KC_3, KC_4, KC_G, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, | ||
116 | KC_LCTL, KC_D3_1, KC_D3_2, KC_D3_3, KC_D3_4, KC_Z, KC_NO, KC_N, KC_M, KC_NO, KC_NO, KC_NO, | ||
117 | KC_F, KC_L, KC_NO, TG_DBLO, | ||
118 | SFT_T(KC_SPC), KC_F, _______, | ||
119 | ALT_T(KC_Q), KC_J, _______, | ||
120 | KC_DIABLO_CLEAR, KC_LGUI, _______, _______ | ||
121 | ), | ||
122 | [_LOWER] = LAYOUT_5x6_right_trackball_wrapper( | ||
123 | KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11, | ||
124 | _______, _________________LOWER_L1__________________, _________________LOWER_R1__________________, _______, | ||
125 | _______, _________________LOWER_L2__________________, _________________LOWER_R2__________________, KC_PIPE, | ||
126 | _______, _________________LOWER_L3__________________, _________________LOWER_R3__________________, _______, | ||
127 | _______, _______, _______, _______, | ||
128 | _______, _______, _______, | ||
129 | _______, _______, _______, | ||
130 | _______, _______, _______, _______ | ||
131 | ), | ||
132 | [_RAISE] = LAYOUT_5x6_right_trackball_wrapper( | ||
133 | KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11, | ||
134 | KC_GRV, _________________RAISE_L1__________________, _________________RAISE_R1__________________, _______, | ||
135 | _______, _________________RAISE_L2__________________, _________________RAISE_R2__________________, KC_BSLS, | ||
136 | _______, _________________RAISE_L3__________________, _________________RAISE_R3__________________, _______, | ||
137 | _______, _______, _______, _______, | ||
138 | _______, _______, _______, | ||
139 | _______, _______, _______, | ||
140 | _______, _______, _______, _______ | ||
141 | ), | ||
142 | [_ADJUST] = LAYOUT_5x6_right_trackball_wrapper( | ||
143 | KC_MAKE, ___________________BLANK___________________, _________________ADJUST_R1_________________, KC_RST, | ||
144 | VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST, | ||
145 | _______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS, | ||
146 | _______, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY, | ||
147 | HPT_DWLI, HPT_DWLD, _______, _______, | ||
148 | HPT_TOG, HPT_BUZ, KC_NUKE, | ||
149 | _______, _______, _______, | ||
150 | _______, _______, KC_NUKE, _______ | ||
151 | ), | ||
152 | }; | ||
153 | // clang-format off | ||
154 | |||
155 | |||
156 | #ifdef POINTING_DEVICE_ENABLE | ||
157 | static uint16_t mouse_timer = 0; | ||
158 | static uint16_t mouse_debounce_timer = 0; | ||
159 | static uint8_t mouse_keycode_tracker = 0; | ||
160 | |||
161 | void process_mouse_user(report_mouse_t* mouse_report, int16_t x, int16_t y) { | ||
162 | if ((x || y) && timer_elapsed(mouse_timer) > 125) { | ||
163 | mouse_timer = timer_read(); | ||
164 | if (!layer_state_is(_MOUSE) && !layer_state_is(_GAMEPAD) && timer_elapsed(mouse_debounce_timer) > 125) { | ||
165 | layer_on(_MOUSE); | ||
166 | } | ||
167 | } | ||
168 | if (timer_elapsed(mouse_debounce_timer) > 125 || layer_state_is(_GAMEPAD) ) { | ||
169 | mouse_report->x = x; | ||
170 | mouse_report->y = y; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | void matrix_scan_keymap(void) { | ||
175 | if (timer_elapsed(mouse_timer) > 750 && layer_state_is(_MOUSE) && !mouse_keycode_tracker) { | ||
176 | layer_off(_MOUSE); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { | ||
181 | switch(keycode){ | ||
182 | case MO(_MOUSE): | ||
183 | case DPI_CONFIG: | ||
184 | case KC_MS_UP...KC_MS_WH_RIGHT: | ||
185 | record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--; | ||
186 | mouse_timer = timer_read(); | ||
187 | break; | ||
188 | default: | ||
189 | if (layer_state_is(_MOUSE) && !mouse_keycode_tracker) { | ||
190 | layer_off(_MOUSE); | ||
191 | } | ||
192 | mouse_debounce_timer = timer_read(); | ||
193 | break; | ||
194 | } | ||
195 | return true; | ||
196 | } | ||
197 | #endif | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/rules.mk b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/rules.mk new file mode 100644 index 000000000..2e3e9607c --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/keymaps/drashna/rules.mk | |||
@@ -0,0 +1,2 @@ | |||
1 | RGBLIGHT_STARTUP_ANIMATION = yes | ||
2 | HAPTIC_ENABLE = SOLENOID | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c new file mode 100644 index 000000000..8007fecef --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.c | |||
@@ -0,0 +1,225 @@ | |||
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 | |||
20 | #include "pmw3360.h" | ||
21 | #include "pmw3360_firmware.h" | ||
22 | |||
23 | #ifdef CONSOLE_ENABLE | ||
24 | # include "print.h" | ||
25 | #endif | ||
26 | bool _inBurst = false; | ||
27 | |||
28 | #ifndef PMW_CPI | ||
29 | # define PMW_CPI 1600 | ||
30 | #endif | ||
31 | #ifndef SPI_DIVISOR | ||
32 | # define SPI_DIVISOR 2 | ||
33 | #endif | ||
34 | #ifndef ROTATIONAL_TRANSFORM_ANGLE | ||
35 | # define ROTATIONAL_TRANSFORM_ANGLE 0x00 | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONSOLE_ENABLE | ||
39 | void 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 | #endif | ||
41 | |||
42 | |||
43 | bool spi_start_adv(void) { | ||
44 | bool status = spi_start(SPI_SS_PIN, false, 3, SPI_DIVISOR); | ||
45 | wait_us(1); | ||
46 | return status; | ||
47 | } | ||
48 | |||
49 | void spi_stop_adv(void) { | ||
50 | wait_us(1); | ||
51 | spi_stop(); | ||
52 | } | ||
53 | |||
54 | spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data) { | ||
55 | if (reg_addr != REG_Motion_Burst) { | ||
56 | _inBurst = false; | ||
57 | } | ||
58 | |||
59 | spi_start_adv(); | ||
60 | // send address of the register, with MSBit = 1 to indicate it's a write | ||
61 | spi_status_t status = spi_write(reg_addr | 0x80); | ||
62 | status = spi_write(data); | ||
63 | |||
64 | // tSCLK-NCS for write operation | ||
65 | wait_us(20); | ||
66 | |||
67 | // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound | ||
68 | wait_us(100); | ||
69 | spi_stop(); | ||
70 | return status; | ||
71 | } | ||
72 | |||
73 | uint8_t spi_read_adv(uint8_t reg_addr) { | ||
74 | spi_start_adv(); | ||
75 | // send adress of the register, with MSBit = 0 to indicate it's a read | ||
76 | spi_write(reg_addr & 0x7f); | ||
77 | |||
78 | uint8_t data = spi_read(); | ||
79 | |||
80 | // tSCLK-NCS for read operation is 120ns | ||
81 | wait_us(1); | ||
82 | |||
83 | // tSRW/tSRR (=20us) minus tSCLK-NCS | ||
84 | wait_us(19); | ||
85 | |||
86 | spi_stop(); | ||
87 | return data; | ||
88 | } | ||
89 | |||
90 | void pmw_set_cpi(uint16_t cpi) { | ||
91 | int cpival = constrain((cpi / 100) - 1, 0, 0x77); // limits to 0--119 | ||
92 | |||
93 | spi_start_adv(); | ||
94 | spi_write_adv(REG_Config1, cpival); | ||
95 | spi_stop(); | ||
96 | } | ||
97 | |||
98 | bool pmw_spi_init(void) { | ||
99 | spi_init(); | ||
100 | _inBurst = false; | ||
101 | |||
102 | spi_stop(); | ||
103 | spi_start_adv(); | ||
104 | spi_stop(); | ||
105 | |||
106 | spi_write_adv(REG_Shutdown, 0xb6); // Shutdown first | ||
107 | wait_ms(300); | ||
108 | |||
109 | spi_start_adv(); | ||
110 | wait_us(40); | ||
111 | spi_stop_adv(); | ||
112 | wait_us(40); | ||
113 | |||
114 | spi_write_adv(REG_Power_Up_Reset, 0x5a); | ||
115 | wait_ms(50); | ||
116 | |||
117 | spi_read_adv(REG_Motion); | ||
118 | spi_read_adv(REG_Delta_X_L); | ||
119 | spi_read_adv(REG_Delta_X_H); | ||
120 | spi_read_adv(REG_Delta_Y_L); | ||
121 | spi_read_adv(REG_Delta_Y_H); | ||
122 | |||
123 | pmw_upload_firmware(); | ||
124 | |||
125 | spi_stop_adv(); | ||
126 | |||
127 | wait_ms(10); | ||
128 | pmw_set_cpi(PMW_CPI); | ||
129 | |||
130 | wait_ms(1); | ||
131 | |||
132 | return pmw_check_signature(); | ||
133 | } | ||
134 | |||
135 | void pmw_upload_firmware(void) { | ||
136 | spi_write_adv(REG_Config2, 0x00); | ||
137 | |||
138 | spi_write_adv(REG_Angle_Tune, constrain(ROTATIONAL_TRANSFORM_ANGLE, -30, 30)); | ||
139 | |||
140 | spi_write_adv(REG_SROM_Enable, 0x1d); | ||
141 | |||
142 | wait_ms(10); | ||
143 | |||
144 | spi_write_adv(REG_SROM_Enable, 0x18); | ||
145 | |||
146 | spi_start_adv(); | ||
147 | spi_write(REG_SROM_Load_Burst | 0x80); | ||
148 | wait_us(15); | ||
149 | |||
150 | unsigned char c; | ||
151 | for (int i = 0; i < firmware_length; i++) { | ||
152 | c = (unsigned char)pgm_read_byte(firmware_data + i); | ||
153 | spi_write(c); | ||
154 | wait_us(15); | ||
155 | } | ||
156 | wait_us(200); | ||
157 | |||
158 | spi_read_adv(REG_SROM_ID); | ||
159 | |||
160 | spi_write_adv(REG_Config2, 0x00); | ||
161 | |||
162 | spi_stop(); | ||
163 | wait_ms(10); | ||
164 | } | ||
165 | |||
166 | bool pmw_check_signature(void) { | ||
167 | uint8_t pid = spi_read_adv(REG_Product_ID); | ||
168 | uint8_t iv_pid = spi_read_adv(REG_Inverse_Product_ID); | ||
169 | uint8_t SROM_ver = spi_read_adv(REG_SROM_ID); | ||
170 | return (pid == 0x42 && iv_pid == 0xBD && SROM_ver == 0x04); // signature for SROM 0x04 | ||
171 | } | ||
172 | |||
173 | report_pmw_t pmw_read_burst(void) { | ||
174 | if (!_inBurst) { | ||
175 | #ifdef CONSOLE_ENABLE | ||
176 | dprintf("burst on"); | ||
177 | #endif | ||
178 | spi_write_adv(REG_Motion_Burst, 0x00); | ||
179 | _inBurst = true; | ||
180 | } | ||
181 | |||
182 | spi_start_adv(); | ||
183 | spi_write(REG_Motion_Burst); | ||
184 | wait_us(35); // waits for tSRAD | ||
185 | |||
186 | report_pmw_t data; | ||
187 | data.motion = 0; | ||
188 | data.dx = 0; | ||
189 | data.mdx = 0; | ||
190 | data.dy = 0; | ||
191 | data.mdx = 0; | ||
192 | |||
193 | data.motion = spi_read(); | ||
194 | spi_write(0x00); // skip Observation | ||
195 | data.dx = spi_read(); | ||
196 | data.mdx = spi_read(); | ||
197 | data.dy = spi_read(); | ||
198 | data.mdy = spi_read(); | ||
199 | |||
200 | spi_stop(); | ||
201 | |||
202 | #ifdef CONSOLE_ENABLE | ||
203 | print_byte(data.motion); | ||
204 | print_byte(data.dx); | ||
205 | print_byte(data.mdx); | ||
206 | print_byte(data.dy); | ||
207 | print_byte(data.mdy); | ||
208 | dprintf("\n"); | ||
209 | #endif | ||
210 | |||
211 | data.isMotion = (data.motion & 0x80) != 0; | ||
212 | data.isOnSurface = (data.motion & 0x08) == 0; | ||
213 | data.dx |= (data.mdx << 8); | ||
214 | data.dx = data.dx * -1; | ||
215 | data.dy |= (data.mdy << 8); | ||
216 | data.dy = data.dy * -1; | ||
217 | |||
218 | spi_stop(); | ||
219 | |||
220 | if (data.motion & 0b111) { // panic recovery, sometimes burst mode works weird. | ||
221 | _inBurst = false; | ||
222 | } | ||
223 | |||
224 | return data; | ||
225 | } | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h new file mode 100644 index 000000000..c1d5e3bad --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360.h | |||
@@ -0,0 +1,103 @@ | |||
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 | ||
75 | void print_byte(uint8_t byte); | ||
76 | #endif | ||
77 | |||
78 | typedef 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 | |||
90 | bool spi_start_adv(void); | ||
91 | void spi_stop_adv(void); | ||
92 | spi_status_t spi_write_adv(uint8_t reg_addr, uint8_t data); | ||
93 | uint8_t spi_read_adv(uint8_t reg_addr); | ||
94 | bool pmw_spi_init(void); | ||
95 | void pmw_set_cpi(uint16_t cpi); | ||
96 | void pmw_upload_firmware(void); | ||
97 | bool pmw_check_signature(void); | ||
98 | report_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/pmw3360_firmware.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360_firmware.h new file mode 100644 index 000000000..cca5a6a4d --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pmw3360_firmware.h | |||
@@ -0,0 +1,300 @@ | |||
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 | ||
23 | const uint16_t firmware_length = 4094; | ||
24 | // clang-format off | ||
25 | const uint8_t firmware_data[] PROGMEM = { // SROM 0x04 | ||
26 | 0x01, 0x04, 0x8e, 0x96, 0x6e, 0x77, 0x3e, 0xfe, 0x7e, 0x5f, 0x1d, 0xb8, 0xf2, 0x66, 0x4e, | ||
27 | 0xff, 0x5d, 0x19, 0xb0, 0xc2, 0x04, 0x69, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0xb0, | ||
28 | 0xc3, 0xe5, 0x29, 0xb1, 0xe0, 0x23, 0xa5, 0xa9, 0xb1, 0xc1, 0x00, 0x82, 0x67, 0x4c, 0x1a, | ||
29 | 0x97, 0x8d, 0x79, 0x51, 0x20, 0xc7, 0x06, 0x8e, 0x7c, 0x7c, 0x7a, 0x76, 0x4f, 0xfd, 0x59, | ||
30 | 0x30, 0xe2, 0x46, 0x0e, 0x9e, 0xbe, 0xdf, 0x1d, 0x99, 0x91, 0xa0, 0xa5, 0xa1, 0xa9, 0xd0, | ||
31 | 0x22, 0xc6, 0xef, 0x5c, 0x1b, 0x95, 0x89, 0x90, 0xa2, 0xa7, 0xcc, 0xfb, 0x55, 0x28, 0xb3, | ||
32 | 0xe4, 0x4a, 0xf7, 0x6c, 0x3b, 0xf4, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x05, | ||
33 | 0x88, 0x92, 0xa6, 0xce, 0x1e, 0xbe, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x07, | ||
34 | 0x11, 0x5d, 0x98, 0x0b, 0x9d, 0x94, 0x97, 0xee, 0x4e, 0x45, 0x33, 0x6b, 0x44, 0xc7, 0x29, | ||
35 | 0x56, 0x27, 0x30, 0xc6, 0xa7, 0xd5, 0xf2, 0x56, 0xdf, 0xb4, 0x38, 0x62, 0xcb, 0xa0, 0xb6, | ||
36 | 0xe3, 0x0f, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6f, 0x76, 0x89, 0xb5, 0x77, 0x41, 0x27, 0x82, | ||
37 | 0x66, 0x65, 0x82, 0xcc, 0xd5, 0xe6, 0x20, 0xd5, 0x27, 0x17, 0xc5, 0xf8, 0x03, 0x23, 0x7c, | ||
38 | 0x5f, 0x64, 0xa5, 0x1d, 0xc1, 0xd6, 0x36, 0xcb, 0x4c, 0xd4, 0xdb, 0x66, 0xd7, 0x8b, 0xb1, | ||
39 | 0x99, 0x7e, 0x6f, 0x4c, 0x36, 0x40, 0x06, 0xd6, 0xeb, 0xd7, 0xa2, 0xe4, 0xf4, 0x95, 0x51, | ||
40 | 0x5a, 0x54, 0x96, 0xd5, 0x53, 0x44, 0xd7, 0x8c, 0xe0, 0xb9, 0x40, 0x68, 0xd2, 0x18, 0xe9, | ||
41 | 0xdd, 0x9a, 0x23, 0x92, 0x48, 0xee, 0x7f, 0x43, 0xaf, 0xea, 0x77, 0x38, 0x84, 0x8c, 0x0a, | ||
42 | 0x72, 0xaf, 0x69, 0xf8, 0xdd, 0xf1, 0x24, 0x83, 0xa3, 0xf8, 0x4a, 0xbf, 0xf5, 0x94, 0x13, | ||
43 | 0xdb, 0xbb, 0xd8, 0xb4, 0xb3, 0xa0, 0xfb, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, | ||
44 | 0xa2, 0xd3, 0x13, 0xe7, 0xfa, 0xe7, 0xce, 0x0f, 0x63, 0x15, 0x0b, 0x6b, 0x94, 0xbb, 0x37, | ||
45 | 0x83, 0x26, 0x05, 0x9d, 0xfb, 0x46, 0x92, 0xfc, 0x0a, 0x15, 0xd1, 0x0d, 0x73, 0x92, 0xd6, | ||
46 | 0x8c, 0x1b, 0x8c, 0xb8, 0x55, 0x8a, 0xce, 0xbd, 0xfe, 0x8e, 0xfc, 0xed, 0x09, 0x12, 0x83, | ||
47 | 0x91, 0x82, 0x51, 0x31, 0x23, 0xfb, 0xb4, 0x0c, 0x76, 0xad, 0x7c, 0xd9, 0xb4, 0x4b, 0xb2, | ||
48 | 0x67, 0x14, 0x09, 0x9c, 0x7f, 0x0c, 0x18, 0xba, 0x3b, 0xd6, 0x8e, 0x14, 0x2a, 0xe4, 0x1b, | ||
49 | 0x52, 0x9f, 0x2b, 0x7d, 0xe1, 0xfb, 0x6a, 0x33, 0x02, 0xfa, 0xac, 0x5a, 0xf2, 0x3e, 0x88, | ||
50 | 0x7e, 0xae, 0xd1, 0xf3, 0x78, 0xe8, 0x05, 0xd1, 0xe3, 0xdc, 0x21, 0xf6, 0xe1, 0x9a, 0xbd, | ||
51 | 0x17, 0x0e, 0xd9, 0x46, 0x9b, 0x88, 0x03, 0xea, 0xf6, 0x66, 0xbe, 0x0e, 0x1b, 0x50, 0x49, | ||
52 | 0x96, 0x40, 0x97, 0xf1, 0xf1, 0xe4, 0x80, 0xa6, 0x6e, 0xe8, 0x77, 0x34, 0xbf, 0x29, 0x40, | ||
53 | 0x44, 0xc2, 0xff, 0x4e, 0x98, 0xd3, 0x9c, 0xa3, 0x32, 0x2b, 0x76, 0x51, 0x04, 0x09, 0xe7, | ||
54 | 0xa9, 0xd1, 0xa6, 0x32, 0xb1, 0x23, 0x53, 0xe2, 0x47, 0xab, 0xd6, 0xf5, 0x69, 0x5c, 0x3e, | ||
55 | 0x5f, 0xfa, 0xae, 0x45, 0x20, 0xe5, 0xd2, 0x44, 0xff, 0x39, 0x32, 0x6d, 0xfd, 0x27, 0x57, | ||
56 | 0x5c, 0xfd, 0xf0, 0xde, 0xc1, 0xb5, 0x99, 0xe5, 0xf5, 0x1c, 0x77, 0x01, 0x75, 0xc5, 0x6d, | ||
57 | 0x58, 0x92, 0xf2, 0xb2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7a, 0x30, 0xff, 0xb7, 0xf0, 0xef, | ||
58 | 0x77, 0xc1, 0x8a, 0x5d, 0xdc, 0xc0, 0xd1, 0x29, 0x30, 0x1e, 0x77, 0x38, 0x7a, 0x94, 0xf1, | ||
59 | 0xb8, 0x7a, 0x7e, 0xef, 0xa4, 0xd1, 0xac, 0x31, 0x4a, 0xf2, 0x5d, 0x64, 0x3d, 0xb2, 0xe2, | ||
60 | 0xf0, 0x08, 0x99, 0xfc, 0x70, 0xee, 0x24, 0xa7, 0x7e, 0xee, 0x1e, 0x20, 0x69, 0x7d, 0x44, | ||
61 | 0xbf, 0x87, 0x42, 0xdf, 0x88, 0x3b, 0x0c, 0xda, 0x42, 0xc9, 0x04, 0xf9, 0x45, 0x50, 0xfc, | ||
62 | 0x83, 0x8f, 0x11, 0x6a, 0x72, 0xbc, 0x99, 0x95, 0xf0, 0xac, 0x3d, 0xa7, 0x3b, 0xcd, 0x1c, | ||
63 | 0xe2, 0x88, 0x79, 0x37, 0x11, 0x5f, 0x39, 0x89, 0x95, 0x0a, 0x16, 0x84, 0x7a, 0xf6, 0x8a, | ||
64 | 0xa4, 0x28, 0xe4, 0xed, 0x83, 0x80, 0x3b, 0xb1, 0x23, 0xa5, 0x03, 0x10, 0xf4, 0x66, 0xea, | ||
65 | 0xbb, 0x0c, 0x0f, 0xc5, 0xec, 0x6c, 0x69, 0xc5, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0x99, | ||
66 | 0x88, 0x76, 0x08, 0xa0, 0xa8, 0x95, 0x7c, 0xd8, 0x38, 0x6d, 0xcd, 0x59, 0x02, 0x51, 0x4b, | ||
67 | 0xf1, 0xb5, 0x2b, 0x50, 0xe3, 0xb6, 0xbd, 0xd0, 0x72, 0xcf, 0x9e, 0xfd, 0x6e, 0xbb, 0x44, | ||
68 | 0xc8, 0x24, 0x8a, 0x77, 0x18, 0x8a, 0x13, 0x06, 0xef, 0x97, 0x7d, 0xfa, 0x81, 0xf0, 0x31, | ||
69 | 0xe6, 0xfa, 0x77, 0xed, 0x31, 0x06, 0x31, 0x5b, 0x54, 0x8a, 0x9f, 0x30, 0x68, 0xdb, 0xe2, | ||
70 | 0x40, 0xf8, 0x4e, 0x73, 0xfa, 0xab, 0x74, 0x8b, 0x10, 0x58, 0x13, 0xdc, 0xd2, 0xe6, 0x78, | ||
71 | 0xd1, 0x32, 0x2e, 0x8a, 0x9f, 0x2c, 0x58, 0x06, 0x48, 0x27, 0xc5, 0xa9, 0x5e, 0x81, 0x47, | ||
72 | 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xa4, 0x3e, 0x88, 0x9c, 0xda, 0x33, 0x0a, 0xce, 0xbc, | ||
73 | 0x8b, 0x8e, 0xcf, 0x9f, 0xd3, 0x71, 0x80, 0x43, 0xcf, 0x6b, 0xa9, 0x51, 0x83, 0x76, 0x30, | ||
74 | 0x82, 0xc5, 0x6a, 0x85, 0x39, 0x11, 0x50, 0x1a, 0x82, 0xdc, 0x1e, 0x1c, 0xd5, 0x7d, 0xa9, | ||
75 | 0x71, 0x99, 0x33, 0x47, 0x19, 0x97, 0xb3, 0x5a, 0xb1, 0xdf, 0xed, 0xa4, 0xf2, 0xe6, 0x26, | ||
76 | 0x84, 0xa2, 0x28, 0x9a, 0x9e, 0xdf, 0xa6, 0x6a, 0xf4, 0xd6, 0xfc, 0x2e, 0x5b, 0x9d, 0x1a, | ||
77 | 0x2a, 0x27, 0x68, 0xfb, 0xc1, 0x83, 0x21, 0x4b, 0x90, 0xe0, 0x36, 0xdd, 0x5b, 0x31, 0x42, | ||
78 | 0x55, 0xa0, 0x13, 0xf7, 0xd0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xc5, 0xf3, 0x21, | ||
79 | 0xf8, 0x37, 0x2f, 0x40, 0xf3, 0xd4, 0xaf, 0x16, 0x08, 0x36, 0x02, 0xfc, 0x77, 0xc5, 0x8b, | ||
80 | 0x04, 0x90, 0x56, 0xb9, 0xc9, 0x67, 0x9a, 0x99, 0xe8, 0x00, 0xd3, 0x86, 0xff, 0x97, 0x2d, | ||
81 | 0x08, 0xe9, 0xb7, 0xb3, 0x91, 0xbc, 0xdf, 0x45, 0xc6, 0xed, 0x0f, 0x8c, 0x4c, 0x1e, 0xe6, | ||
82 | 0x5b, 0x6e, 0x38, 0x30, 0xe4, 0xaa, 0xe3, 0x95, 0xde, 0xb9, 0xe4, 0x9a, 0xf5, 0xb2, 0x55, | ||
83 | 0x9a, 0x87, 0x9b, 0xf6, 0x6a, 0xb2, 0xf2, 0x77, 0x9a, 0x31, 0xf4, 0x7a, 0x31, 0xd1, 0x1d, | ||
84 | 0x04, 0xc0, 0x7c, 0x32, 0xa2, 0x9e, 0x9a, 0xf5, 0x62, 0xf8, 0x27, 0x8d, 0xbf, 0x51, 0xff, | ||
85 | 0xd3, 0xdf, 0x64, 0x37, 0x3f, 0x2a, 0x6f, 0x76, 0x3a, 0x7d, 0x77, 0x06, 0x9e, 0x77, 0x7f, | ||
86 | 0x5e, 0xeb, 0x32, 0x51, 0xf9, 0x16, 0x66, 0x9a, 0x09, 0xf3, 0xb0, 0x08, 0xa4, 0x70, 0x96, | ||
87 | 0x46, 0x30, 0xff, 0xda, 0x4f, 0xe9, 0x1b, 0xed, 0x8d, 0xf8, 0x74, 0x1f, 0x31, 0x92, 0xb3, | ||
88 | 0x73, 0x17, 0x36, 0xdb, 0x91, 0x30, 0xd6, 0x88, 0x55, 0x6b, 0x34, 0x77, 0x87, 0x7a, 0xe7, | ||
89 | 0xee, 0x06, 0xc6, 0x1c, 0x8c, 0x19, 0x0c, 0x48, 0x46, 0x23, 0x5e, 0x9c, 0x07, 0x5c, 0xbf, | ||
90 | 0xb4, 0x7e, 0xd6, 0x4f, 0x74, 0x9c, 0xe2, 0xc5, 0x50, 0x8b, 0xc5, 0x8b, 0x15, 0x90, 0x60, | ||
91 | 0x62, 0x57, 0x29, 0xd0, 0x13, 0x43, 0xa1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xc7, 0x4d, 0x19, | ||
92 | 0x86, 0xcc, 0x2f, 0x2a, 0x75, 0x5a, 0xfc, 0xeb, 0x97, 0x2a, 0x70, 0xe3, 0x78, 0xd8, 0x91, | ||
93 | 0xb0, 0x4f, 0x99, 0x07, 0xa3, 0x95, 0xea, 0x24, 0x21, 0xd5, 0xde, 0x51, 0x20, 0x93, 0x27, | ||
94 | 0x0a, 0x30, 0x73, 0xa8, 0xff, 0x8a, 0x97, 0xe9, 0xa7, 0x6a, 0x8e, 0x0d, 0xe8, 0xf0, 0xdf, | ||
95 | 0xec, 0xea, 0xb4, 0x6c, 0x1d, 0x39, 0x2a, 0x62, 0x2d, 0x3d, 0x5a, 0x8b, 0x65, 0xf8, 0x90, | ||
96 | 0x05, 0x2e, 0x7e, 0x91, 0x2c, 0x78, 0xef, 0x8e, 0x7a, 0xc1, 0x2f, 0xac, 0x78, 0xee, 0xaf, | ||
97 | 0x28, 0x45, 0x06, 0x4c, 0x26, 0xaf, 0x3b, 0xa2, 0xdb, 0xa3, 0x93, 0x06, 0xb5, 0x3c, 0xa5, | ||
98 | 0xd8, 0xee, 0x8f, 0xaf, 0x25, 0xcc, 0x3f, 0x85, 0x68, 0x48, 0xa9, 0x62, 0xcc, 0x97, 0x8f, | ||
99 | 0x7f, 0x2a, 0xea, 0xe0, 0x15, 0x0a, 0xad, 0x62, 0x07, 0xbd, 0x45, 0xf8, 0x41, 0xd8, 0x36, | ||
100 | 0xcb, 0x4c, 0xdb, 0x6e, 0xe6, 0x3a, 0xe7, 0xda, 0x15, 0xe9, 0x29, 0x1e, 0x12, 0x10, 0xa0, | ||
101 | 0x14, 0x2c, 0x0e, 0x3d, 0xf4, 0xbf, 0x39, 0x41, 0x92, 0x75, 0x0b, 0x25, 0x7b, 0xa3, 0xce, | ||
102 | 0x39, 0x9c, 0x15, 0x64, 0xc8, 0xfa, 0x3d, 0xef, 0x73, 0x27, 0xfe, 0x26, 0x2e, 0xce, 0xda, | ||
103 | 0x6e, 0xfd, 0x71, 0x8e, 0xdd, 0xfe, 0x76, 0xee, 0xdc, 0x12, 0x5c, 0x02, 0xc5, 0x3a, 0x4e, | ||
104 | 0x4e, 0x4f, 0xbf, 0xca, 0x40, 0x15, 0xc7, 0x6e, 0x8d, 0x41, 0xf1, 0x10, 0xe0, 0x4f, 0x7e, | ||
105 | 0x97, 0x7f, 0x1c, 0xae, 0x47, 0x8e, 0x6b, 0xb1, 0x25, 0x31, 0xb0, 0x73, 0xc7, 0x1b, 0x97, | ||
106 | 0x79, 0xf9, 0x80, 0xd3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1e, 0xe4, 0xd0, 0x80, 0x21, 0xd6, | ||
107 | 0xee, 0x6b, 0x6c, 0x4f, 0xbf, 0xf5, 0xb7, 0xd9, 0x09, 0x87, 0x2f, 0xa9, 0x14, 0xbe, 0x27, | ||
108 | 0xd9, 0x72, 0x50, 0x01, 0xd4, 0x13, 0x73, 0xa6, 0xa7, 0x51, 0x02, 0x75, 0x25, 0xe1, 0xb3, | ||
109 | 0x45, 0x34, 0x7d, 0xa8, 0x8e, 0xeb, 0xf3, 0x16, 0x49, 0xcb, 0x4f, 0x8c, 0xa1, 0xb9, 0x36, | ||
110 | 0x85, 0x39, 0x75, 0x5d, 0x08, 0x00, 0xae, 0xeb, 0xf6, 0xea, 0xd7, 0x13, 0x3a, 0x21, 0x5a, | ||
111 | 0x5f, 0x30, 0x84, 0x52, 0x26, 0x95, 0xc9, 0x14, 0xf2, 0x57, 0x55, 0x6b, 0xb1, 0x10, 0xc2, | ||
112 | 0xe1, 0xbd, 0x3b, 0x51, 0xc0, 0xb7, 0x55, 0x4c, 0x71, 0x12, 0x26, 0xc7, 0x0d, 0xf9, 0x51, | ||
113 | 0xa4, 0x38, 0x02, 0x05, 0x7f, 0xb8, 0xf1, 0x72, 0x4b, 0xbf, 0x71, 0x89, 0x14, 0xf3, 0x77, | ||
114 | 0x38, 0xd9, 0x71, 0x24, 0xf3, 0x00, 0x11, 0xa1, 0xd8, 0xd4, 0x69, 0x27, 0x08, 0x37, 0x35, | ||
115 | 0xc9, 0x11, 0x9d, 0x90, 0x1c, 0x0e, 0xe7, 0x1c, 0xff, 0x2d, 0x1e, 0xe8, 0x92, 0xe1, 0x18, | ||
116 | 0x10, 0x95, 0x7c, 0xe0, 0x80, 0xf4, 0x96, 0x43, 0x21, 0xf9, 0x75, 0x21, 0x64, 0x38, 0xdd, | ||
117 | 0x9f, 0x1e, 0x95, 0x16, 0xda, 0x56, 0x1d, 0x4f, 0x9a, 0x53, 0xb2, 0xe2, 0xe4, 0x18, 0xcb, | ||
118 | 0x6b, 0x1a, 0x65, 0xeb, 0x56, 0xc6, 0x3b, 0xe5, 0xfe, 0xd8, 0x26, 0x3f, 0x3a, 0x84, 0x59, | ||
119 | 0x72, 0x66, 0xa2, 0xf3, 0x75, 0xff, 0xfb, 0x60, 0xb3, 0x22, 0xad, 0x3f, 0x2d, 0x6b, 0xf9, | ||
120 | 0xeb, 0xea, 0x05, 0x7c, 0xd8, 0x8f, 0x6d, 0x2c, 0x98, 0x9e, 0x2b, 0x93, 0xf1, 0x5e, 0x46, | ||
121 | 0xf0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xd7, 0x7f, 0xf9, 0xf0, 0xe5, 0x7d, 0xdb, 0x1d, 0x75, | ||
122 | 0x19, 0xf3, 0xc4, 0x58, 0x9b, 0x17, 0x88, 0xa8, 0x92, 0xe0, 0xbe, 0xbd, 0x8b, 0x1d, 0x8d, | ||
123 | 0x9f, 0x56, 0x76, 0xad, 0xaf, 0x29, 0xe2, 0xd9, 0xd5, 0x52, 0xf6, 0xb5, 0x56, 0x35, 0x57, | ||
124 | 0x3a, 0xc8, 0xe1, 0x56, 0x43, 0x19, 0x94, 0xd3, 0x04, 0x9b, 0x6d, 0x35, 0xd8, 0x0b, 0x5f, | ||
125 | 0x4d, 0x19, 0x8e, 0xec, 0xfa, 0x64, 0x91, 0x0a, 0x72, 0x20, 0x2b, 0xbc, 0x1a, 0x4a, 0xfe, | ||
126 | 0x8b, 0xfd, 0xbb, 0xed, 0x1b, 0x23, 0xea, 0xad, 0x72, 0x82, 0xa1, 0x29, 0x99, 0x71, 0xbd, | ||
127 | 0xf0, 0x95, 0xc1, 0x03, 0xdd, 0x7b, 0xc2, 0xb2, 0x3c, 0x28, 0x54, 0xd3, 0x68, 0xa4, 0x72, | ||
128 | 0xc8, 0x66, 0x96, 0xe0, 0xd1, 0xd8, 0x7f, 0xf8, 0xd1, 0x26, 0x2b, 0xf7, 0xad, 0xba, 0x55, | ||
129 | 0xca, 0x15, 0xb9, 0x32, 0xc3, 0xe5, 0x88, 0x97, 0x8e, 0x5c, 0xfb, 0x92, 0x25, 0x8b, 0xbf, | ||
130 | 0xa2, 0x45, 0x55, 0x7a, 0xa7, 0x6f, 0x8b, 0x57, 0x5b, 0xcf, 0x0e, 0xcb, 0x1d, 0xfb, 0x20, | ||
131 | 0x82, 0x77, 0xa8, 0x8c, 0xcc, 0x16, 0xce, 0x1d, 0xfa, 0xde, 0xcc, 0x0b, 0x62, 0xfe, 0xcc, | ||
132 | 0xe1, 0xb7, 0xf0, 0xc3, 0x81, 0x64, 0x73, 0x40, 0xa0, 0xc2, 0x4d, 0x89, 0x11, 0x75, 0x33, | ||
133 | 0x55, 0x33, 0x8d, 0xe8, 0x4a, 0xfd, 0xea, 0x6e, 0x30, 0x0b, 0xd7, 0x31, 0x2c, 0xde, 0x47, | ||
134 | 0xe3, 0xbf, 0xf8, 0x55, 0x42, 0xe2, 0x7f, 0x59, 0xe5, 0x17, 0xef, 0x99, 0x34, 0x69, 0x91, | ||
135 | 0xb1, 0x23, 0x8e, 0x20, 0x87, 0x2d, 0xa8, 0xfe, 0xd5, 0x8a, 0xf3, 0x84, 0x3a, 0xf0, 0x37, | ||
136 | 0xe4, 0x09, 0x00, 0x54, 0xee, 0x67, 0x49, 0x93, 0xe4, 0x81, 0x70, 0xe3, 0x90, 0x4d, 0xef, | ||
137 | 0xfe, 0x41, 0xb7, 0x99, 0x7b, 0xc1, 0x83, 0xba, 0x62, 0x12, 0x6f, 0x7d, 0xde, 0x6b, 0xaf, | ||
138 | 0xda, 0x16, 0xf9, 0x55, 0x51, 0xee, 0xa6, 0x0c, 0x2b, 0x02, 0xa3, 0xfd, 0x8d, 0xfb, 0x30, | ||
139 | 0x17, 0xe4, 0x6f, 0xdf, 0x36, 0x71, 0xc4, 0xca, 0x87, 0x25, 0x48, 0xb0, 0x47, 0xec, 0xea, | ||
140 | 0xb4, 0xbf, 0xa5, 0x4d, 0x9b, 0x9f, 0x02, 0x93, 0xc4, 0xe3, 0xe4, 0xe8, 0x42, 0x2d, 0x68, | ||
141 | 0x81, 0x15, 0x0a, 0xeb, 0x84, 0x5b, 0xd6, 0xa8, 0x74, 0xfb, 0x7d, 0x1d, 0xcb, 0x2c, 0xda, | ||
142 | 0x46, 0x2a, 0x76, 0x62, 0xce, 0xbc, 0x5c, 0x9e, 0x8b, 0xe7, 0xcf, 0xbe, 0x78, 0xf5, 0x7c, | ||
143 | 0xeb, 0xb3, 0x3a, 0x9c, 0xaa, 0x6f, 0xcc, 0x72, 0xd1, 0x59, 0xf2, 0x11, 0x23, 0xd6, 0x3f, | ||
144 | 0x48, 0xd1, 0xb7, 0xce, 0xb0, 0xbf, 0xcb, 0xea, 0x80, 0xde, 0x57, 0xd4, 0x5e, 0x97, 0x2f, | ||
145 | 0x75, 0xd1, 0x50, 0x8e, 0x80, 0x2c, 0x66, 0x79, 0xbf, 0x72, 0x4b, 0xbd, 0x8a, 0x81, 0x6c, | ||
146 | 0xd3, 0xe1, 0x01, 0xdc, 0xd2, 0x15, 0x26, 0xc5, 0x36, 0xda, 0x2c, 0x1a, 0xc0, 0x27, 0x94, | ||
147 | 0xed, 0xb7, 0x9b, 0x85, 0x0b, 0x5e, 0x80, 0x97, 0xc5, 0xec, 0x4f, 0xec, 0x88, 0x5d, 0x50, | ||
148 | 0x07, 0x35, 0x47, 0xdc, 0x0b, 0x3b, 0x3d, 0xdd, 0x60, 0xaf, 0xa8, 0x5d, 0x81, 0x38, 0x24, | ||
149 | 0x25, 0x5d, 0x5c, 0x15, 0xd1, 0xde, 0xb3, 0xab, 0xec, 0x05, 0x69, 0xef, 0x83, 0xed, 0x57, | ||
150 | 0x54, 0xb8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xda, 0x9f, 0x2d, 0x7f, 0x36, 0xbb, 0x44, | ||
151 | 0x5a, 0x34, 0xe8, 0x7f, 0xbf, 0x03, 0xeb, 0x00, 0x7f, 0x59, 0x68, 0x22, 0x79, 0xcf, 0x73, | ||
152 | 0x6c, 0x2c, 0x29, 0xa7, 0xa1, 0x5f, 0x38, 0xa1, 0x1d, 0xf0, 0x20, 0x53, 0xe0, 0x1a, 0x63, | ||
153 | 0x14, 0x58, 0x71, 0x10, 0xaa, 0x08, 0x0c, 0x3e, 0x16, 0x1a, 0x60, 0x22, 0x82, 0x7f, 0xba, | ||
154 | 0xa4, 0x43, 0xa0, 0xd0, 0xac, 0x1b, 0xd5, 0x6b, 0x64, 0xb5, 0x14, 0x93, 0x31, 0x9e, 0x53, | ||
155 | 0x50, 0xd0, 0x57, 0x66, 0xee, 0x5a, 0x4f, 0xfb, 0x03, 0x2a, 0x69, 0x58, 0x76, 0xf1, 0x83, | ||
156 | 0xf7, 0x4e, 0xba, 0x8c, 0x42, 0x06, 0x60, 0x5d, 0x6d, 0xce, 0x60, 0x88, 0xae, 0xa4, 0xc3, | ||
157 | 0xf1, 0x03, 0xa5, 0x4b, 0x98, 0xa1, 0xff, 0x67, 0xe1, 0xac, 0xa2, 0xb8, 0x62, 0xd7, 0x6f, | ||
158 | 0xa0, 0x31, 0xb4, 0xd2, 0x77, 0xaf, 0x21, 0x10, 0x06, 0xc6, 0x9a, 0xff, 0x1d, 0x09, 0x17, | ||
159 | 0x0e, 0x5f, 0xf1, 0xaa, 0x54, 0x34, 0x4b, 0x45, 0x8a, 0x87, 0x63, 0xa6, 0xdc, 0xf9, 0x24, | ||
160 | 0x30, 0x67, 0xc6, 0xb2, 0xd6, 0x61, 0x33, 0x69, 0xee, 0x50, 0x61, 0x57, 0x28, 0xe7, 0x7e, | ||
161 | 0xee, 0xec, 0x3a, 0x5a, 0x73, 0x4e, 0xa8, 0x8d, 0xe4, 0x18, 0xea, 0xec, 0x41, 0x64, 0xc8, | ||
162 | 0xe2, 0xe8, 0x66, 0xb6, 0x2d, 0xb6, 0xfb, 0x6a, 0x6c, 0x16, 0xb3, 0xdd, 0x46, 0x43, 0xb9, | ||
163 | 0x73, 0x00, 0x6a, 0x71, 0xed, 0x4e, 0x9d, 0x25, 0x1a, 0xc3, 0x3c, 0x4a, 0x95, 0x15, 0x99, | ||
164 | 0x35, 0x81, 0x14, 0x02, 0xd6, 0x98, 0x9b, 0xec, 0xd8, 0x23, 0x3b, 0x84, 0x29, 0xaf, 0x0c, | ||
165 | 0x99, 0x83, 0xa6, 0x9a, 0x34, 0x4f, 0xfa, 0xe8, 0xd0, 0x3c, 0x4b, 0xd0, 0xfb, 0xb6, 0x68, | ||
166 | 0xb8, 0x9e, 0x8f, 0xcd, 0xf7, 0x60, 0x2d, 0x7a, 0x22, 0xe5, 0x7d, 0xab, 0x65, 0x1b, 0x95, | ||
167 | 0xa7, 0xa8, 0x7f, 0xb6, 0x77, 0x47, 0x7b, 0x5f, 0x8b, 0x12, 0x72, 0xd0, 0xd4, 0x91, 0xef, | ||
168 | 0xde, 0x19, 0x50, 0x3c, 0xa7, 0x8b, 0xc4, 0xa9, 0xb3, 0x23, 0xcb, 0x76, 0xe6, 0x81, 0xf0, | ||
169 | 0xc1, 0x04, 0x8f, 0xa3, 0xb8, 0x54, 0x5b, 0x97, 0xac, 0x19, 0xff, 0x3f, 0x55, 0x27, 0x2f, | ||
170 | 0xe0, 0x1d, 0x42, 0x9b, 0x57, 0xfc, 0x4b, 0x4e, 0x0f, 0xce, 0x98, 0xa9, 0x43, 0x57, 0x03, | ||
171 | 0xbd, 0xe7, 0xc8, 0x94, 0xdf, 0x6e, 0x36, 0x73, 0x32, 0xb4, 0xef, 0x2e, 0x85, 0x7a, 0x6e, | ||
172 | 0xfc, 0x6c, 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xf3, 0xe4, 0x9f, 0x3e, 0xdc, 0x68, 0xf3, | ||
173 | 0xb5, 0xf3, 0x19, 0x80, 0x92, 0x06, 0x99, 0xa2, 0xe8, 0x6f, 0xff, 0x2e, 0x7f, 0xae, 0x42, | ||
174 | 0xa4, 0x5f, 0xfb, 0xd4, 0x0e, 0x81, 0x2b, 0xc3, 0x04, 0xff, 0x2b, 0xb3, 0x74, 0x4e, 0x36, | ||
175 | 0x5b, 0x9c, 0x15, 0x00, 0xc6, 0x47, 0x2b, 0xe8, 0x8b, 0x3d, 0xf1, 0x9c, 0x03, 0x9a, 0x58, | ||
176 | 0x7f, 0x9b, 0x9c, 0xbf, 0x85, 0x49, 0x79, 0x35, 0x2e, 0x56, 0x7b, 0x41, 0x14, 0x39, 0x47, | ||
177 | 0x83, 0x26, 0xaa, 0x07, 0x89, 0x98, 0x11, 0x1b, 0x86, 0xe7, 0x73, 0x7a, 0xd8, 0x7d, 0x78, | ||
178 | 0x61, 0x53, 0xe9, 0x79, 0xf5, 0x36, 0x8d, 0x44, 0x92, 0x84, 0xf9, 0x13, 0x50, 0x58, 0x3b, | ||
179 | 0xa4, 0x6a, 0x36, 0x65, 0x49, 0x8e, 0x3c, 0x0e, 0xf1, 0x6f, 0xd2, 0x84, 0xc4, 0x7e, 0x8e, | ||
180 | 0x3f, 0x39, 0xae, 0x7c, 0x84, 0xf1, 0x63, 0x37, 0x8e, 0x3c, 0xcc, 0x3e, 0x44, 0x81, 0x45, | ||
181 | 0xf1, 0x4b, 0xb9, 0xed, 0x6b, 0x36, 0x5d, 0xbb, 0x20, 0x60, 0x1a, 0x0f, 0xa3, 0xaa, 0x55, | ||
182 | 0x77, 0x3a, 0xa9, 0xae, 0x37, 0x4d, 0xba, 0xb8, 0x86, 0x6b, 0xbc, 0x08, 0x50, 0xf6, 0xcc, | ||
183 | 0xa4, 0xbd, 0x1d, 0x40, 0x72, 0xa5, 0x86, 0xfa, 0xe2, 0x10, 0xae, 0x3d, 0x58, 0x4b, 0x97, | ||
184 | 0xf3, 0x43, 0x74, 0xa9, 0x9e, 0xeb, 0x21, 0xb7, 0x01, 0xa4, 0x86, 0x93, 0x97, 0xee, 0x2f, | ||
185 | 0x4f, 0x3b, 0x86, 0xa1, 0x41, 0x6f, 0x41, 0x26, 0x90, 0x78, 0x5c, 0x7f, 0x30, 0x38, 0x4b, | ||
186 | 0x3f, 0xaa, 0xec, 0xed, 0x5c, 0x6f, 0x0e, 0xad, 0x43, 0x87, 0xfd, 0x93, 0x35, 0xe6, 0x01, | ||
187 | 0xef, 0x41, 0x26, 0x90, 0x99, 0x9e, 0xfb, 0x19, 0x5b, 0xad, 0xd2, 0x91, 0x8a, 0xe0, 0x46, | ||
188 | 0xaf, 0x65, 0xfa, 0x4f, 0x84, 0xc1, 0xa1, 0x2d, 0xcf, 0x45, 0x8b, 0xd3, 0x85, 0x50, 0x55, | ||
189 | 0x7c, 0xf9, 0x67, 0x88, 0xd4, 0x4e, 0xe9, 0xd7, 0x6b, 0x61, 0x54, 0xa1, 0xa4, 0xa6, 0xa2, | ||
190 | 0xc2, 0xbf, 0x30, 0x9c, 0x40, 0x9f, 0x5f, 0xd7, 0x69, 0x2b, 0x24, 0x82, 0x5e, 0xd9, 0xd6, | ||
191 | 0xa7, 0x12, 0x54, 0x1a, 0xf7, 0x55, 0x9f, 0x76, 0x50, 0xa9, 0x95, 0x84, 0xe6, 0x6b, 0x6d, | ||
192 | 0xb5, 0x96, 0x54, 0xd6, 0xcd, 0xb3, 0xa1, 0x9b, 0x46, 0xa7, 0x94, 0x4d, 0xc4, 0x94, 0xb4, | ||
193 | 0x98, 0xe3, 0xe1, 0xe2, 0x34, 0xd5, 0x33, 0x16, 0x07, 0x54, 0xcd, 0xb7, 0x77, 0x53, 0xdb, | ||
194 | 0x4f, 0x4d, 0x46, 0x9d, 0xe9, 0xd4, 0x9c, 0x8a, 0x36, 0xb6, 0xb8, 0x38, 0x26, 0x6c, 0x0e, | ||
195 | 0xff, 0x9c, 0x1b, 0x43, 0x8b, 0x80, 0xcc, 0xb9, 0x3d, 0xda, 0xc7, 0xf1, 0x8a, 0xf2, 0x6d, | ||
196 | 0xb8, 0xd7, 0x74, 0x2f, 0x7e, 0x1e, 0xb7, 0xd3, 0x4a, 0xb4, 0xac, 0xfc, 0x79, 0x48, 0x6c, | ||
197 | 0xbc, 0x96, 0xb6, 0x94, 0x46, 0x57, 0x2d, 0xb0, 0xa3, 0xfc, 0x1e, 0xb9, 0x52, 0x60, 0x85, | ||
198 | 0x2d, 0x41, 0xd0, 0x43, 0x01, 0x1e, 0x1c, 0xd5, 0x7d, 0xfc, 0xf3, 0x96, 0x0d, 0xc7, 0xcb, | ||
199 | 0x2a, 0x29, 0x9a, 0x93, 0xdd, 0x88, 0x2d, 0x37, 0x5d, 0xaa, 0xfb, 0x49, 0x68, 0xa0, 0x9c, | ||
200 | 0x50, 0x86, 0x7f, 0x68, 0x56, 0x57, 0xf9, 0x79, 0x18, 0x39, 0xd4, 0xe0, 0x01, 0x84, 0x33, | ||
201 | 0x61, 0xca, 0xa5, 0xd2, 0xd6, 0xe4, 0xc9, 0x8a, 0x4a, 0x23, 0x44, 0x4e, 0xbc, 0xf0, 0xdc, | ||
202 | 0x24, 0xa1, 0xa0, 0xc4, 0xe2, 0x07, 0x3c, 0x10, 0xc4, 0xb5, 0x25, 0x4b, 0x65, 0x63, 0xf4, | ||
203 | 0x80, 0xe7, 0xcf, 0x61, 0xb1, 0x71, 0x82, 0x21, 0x87, 0x2c, 0xf5, 0x91, 0x00, 0x32, 0x0c, | ||
204 | 0xec, 0xa9, 0xb5, 0x9a, 0x74, 0x85, 0xe3, 0x36, 0x8f, 0x76, 0x4f, 0x9c, 0x6d, 0xce, 0xbc, | ||
205 | 0xad, 0x0a, 0x4b, 0xed, 0x76, 0x04, 0xcb, 0xc3, 0xb9, 0x33, 0x9e, 0x01, 0x93, 0x96, 0x69, | ||
206 | 0x7d, 0xc5, 0xa2, 0x45, 0x79, 0x9b, 0x04, 0x5c, 0x84, 0x09, 0xed, 0x88, 0x43, 0xc7, 0xab, | ||
207 | 0x93, 0x14, 0x26, 0xa1, 0x40, 0xb5, 0xce, 0x4e, 0xbf, 0x2a, 0x42, 0x85, 0x3e, 0x2c, 0x3b, | ||
208 | 0x54, 0xe8, 0x12, 0x1f, 0x0e, 0x97, 0x59, 0xb2, 0x27, 0x89, 0xfa, 0xf2, 0xdf, 0x8e, 0x68, | ||
209 | 0x59, 0xdc, 0x06, 0xbc, 0xb6, 0x85, 0x0d, 0x06, 0x22, 0xec, 0xb1, 0xcb, 0xe5, 0x04, 0xe6, | ||
210 | 0x3d, 0xb3, 0xb0, 0x41, 0x73, 0x08, 0x3f, 0x3c, 0x58, 0x86, 0x63, 0xeb, 0x50, 0xee, 0x1d, | ||
211 | 0x2c, 0x37, 0x74, 0xa9, 0xd3, 0x18, 0xa3, 0x47, 0x6e, 0x93, 0x54, 0xad, 0x0a, 0x5d, 0xb8, | ||
212 | 0x2a, 0x55, 0x5d, 0x78, 0xf6, 0xee, 0xbe, 0x8e, 0x3c, 0x76, 0x69, 0xb9, 0x40, 0xc2, 0x34, | ||
213 | 0xec, 0x2a, 0xb9, 0xed, 0x7e, 0x20, 0xe4, 0x8d, 0x00, 0x38, 0xc7, 0xe6, 0x8f, 0x44, 0xa8, | ||
214 | 0x86, 0xce, 0xeb, 0x2a, 0xe9, 0x90, 0xf1, 0x4c, 0xdf, 0x32, 0xfb, 0x73, 0x1b, 0x6d, 0x92, | ||
215 | 0x1e, 0x95, 0xfe, 0xb4, 0xdb, 0x65, 0xdf, 0x4d, 0x23, 0x54, 0x89, 0x48, 0xbf, 0x4a, 0x2e, | ||
216 | 0x70, 0xd6, 0xd7, 0x62, 0xb4, 0x33, 0x29, 0xb1, 0x3a, 0x33, 0x4c, 0x23, 0x6d, 0xa6, 0x76, | ||
217 | 0xa5, 0x21, 0x63, 0x48, 0xe6, 0x90, 0x5d, 0xed, 0x90, 0x95, 0x0b, 0x7a, 0x84, 0xbe, 0xb8, | ||
218 | 0x0d, 0x5e, 0x63, 0x0c, 0x62, 0x26, 0x4c, 0x14, 0x5a, 0xb3, 0xac, 0x23, 0xa4, 0x74, 0xa7, | ||
219 | 0x6f, 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xa0, 0x28, 0xb7, 0xee, 0x19, 0x38, 0xf1, 0x64, | ||
220 | 0x80, 0x82, 0x43, 0xe1, 0x41, 0x27, 0x1f, 0x1f, 0x90, 0x54, 0x7a, 0xd5, 0x23, 0x2e, 0xd1, | ||
221 | 0x3d, 0xcb, 0x28, 0xba, 0x58, 0x7f, 0xdc, 0x7c, 0x91, 0x24, 0xe9, 0x28, 0x51, 0x83, 0x6e, | ||
222 | 0xc5, 0x56, 0x21, 0x42, 0xed, 0xa0, 0x56, 0x22, 0xa1, 0x40, 0x80, 0x6b, 0xa8, 0xf7, 0x94, | ||
223 | 0xca, 0x13, 0x6b, 0x0c, 0x39, 0xd9, 0xfd, 0xe9, 0xf3, 0x6f, 0xa6, 0x9e, 0xfc, 0x70, 0x8a, | ||
224 | 0xb3, 0xbc, 0x59, 0x3c, 0x1e, 0x1d, 0x6c, 0xf9, 0x7c, 0xaf, 0xf9, 0x88, 0x71, 0x95, 0xeb, | ||
225 | 0x57, 0x00, 0xbd, 0x9f, 0x8c, 0x4f, 0xe1, 0x24, 0x83, 0xc5, 0x22, 0xea, 0xfd, 0xd3, 0x0c, | ||
226 | 0xe2, 0x17, 0x18, 0x7c, 0x6a, 0x4c, 0xde, 0x77, 0xb4, 0x53, 0x9b, 0x4c, 0x81, 0xcd, 0x23, | ||
227 | 0x60, 0xaa, 0x0e, 0x25, 0x73, 0x9c, 0x02, 0x79, 0x32, 0x30, 0xdf, 0x74, 0xdf, 0x75, 0x19, | ||
228 | 0xf4, 0xa5, 0x14, 0x5c, 0xf7, 0x7a, 0xa8, 0xa5, 0x91, 0x84, 0x7c, 0x60, 0x03, 0x06, 0x3b, | ||
229 | 0xcd, 0x50, 0xb6, 0x27, 0x9c, 0xfe, 0xb1, 0xdd, 0xcc, 0xd3, 0xb0, 0x59, 0x24, 0xb2, 0xca, | ||
230 | 0xe2, 0x1c, 0x81, 0x22, 0x9d, 0x07, 0x8f, 0x8e, 0xb9, 0xbe, 0x4e, 0xfa, 0xfc, 0x39, 0x65, | ||
231 | 0xba, 0xbf, 0x9d, 0x12, 0x37, 0x5e, 0x97, 0x7e, 0xf3, 0x89, 0xf5, 0x5d, 0xf5, 0xe3, 0x09, | ||
232 | 0x8c, 0x62, 0xb5, 0x20, 0x9d, 0x0c, 0x53, 0x8a, 0x68, 0x1b, 0xd2, 0x8f, 0x75, 0x17, 0x5d, | ||
233 | 0xd4, 0xe5, 0xda, 0x75, 0x62, 0x19, 0x14, 0x6a, 0x26, 0x2d, 0xeb, 0xf8, 0xaf, 0x37, 0xf0, | ||
234 | 0x6c, 0xa4, 0x55, 0xb1, 0xbc, 0xe2, 0x33, 0xc0, 0x9a, 0xca, 0xb0, 0x11, 0x49, 0x4f, 0x68, | ||
235 | 0x9b, 0x3b, 0x6b, 0x3c, 0xcc, 0x13, 0xf6, 0xc7, 0x85, 0x61, 0x68, 0x42, 0xae, 0xbb, 0xdd, | ||
236 | 0xcd, 0x45, 0x16, 0x29, 0x1d, 0xea, 0xdb, 0xc8, 0x03, 0x94, 0x3c, 0xee, 0x4f, 0x82, 0x11, | ||
237 | 0xc3, 0xec, 0x28, 0xbd, 0x97, 0x05, 0x99, 0xde, 0xd7, 0xbb, 0x5e, 0x22, 0x1f, 0xd4, 0xeb, | ||
238 | 0x64, 0xd9, 0x92, 0xd9, 0x85, 0xb7, 0x6a, 0x05, 0x6a, 0xe4, 0x24, 0x41, 0xf1, 0xcd, 0xf0, | ||
239 | 0xd8, 0x3f, 0xf8, 0x9e, 0x0e, 0xcd, 0x0b, 0x7a, 0x70, 0x6b, 0x5a, 0x75, 0x0a, 0x6a, 0x33, | ||
240 | 0x88, 0xec, 0x17, 0x75, 0x08, 0x70, 0x10, 0x2f, 0x24, 0xcf, 0xc4, 0xe9, 0x42, 0x00, 0x61, | ||
241 | 0x94, 0xca, 0x1f, 0x3a, 0x76, 0x06, 0xfa, 0xd2, 0x48, 0x81, 0xf0, 0x77, 0x60, 0x03, 0x45, | ||
242 | 0xd9, 0x61, 0xf4, 0xa4, 0x6f, 0x3d, 0xd9, 0x30, 0xc3, 0x04, 0x6b, 0x54, 0x2a, 0xb7, 0xec, | ||
243 | 0x3b, 0xf4, 0x4b, 0xf5, 0x68, 0x52, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, | ||
244 | 0xa9, 0xb1, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xa5, 0xa9, 0xb1, | ||
245 | 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0xeb, 0x54, 0x0b, | ||
246 | 0x75, 0x68, 0x52, 0x07, 0x8c, 0x9a, 0x97, 0x8d, 0x79, 0x70, 0x62, 0x46, 0xef, 0x5c, 0x1b, | ||
247 | 0x95, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x67, 0x4c, 0x1a, 0xb6, | ||
248 | 0xcf, 0xfd, 0x78, 0x53, 0x24, 0xab, 0xb5, 0xc9, 0xf1, 0x60, 0x23, 0xa5, 0xc8, 0x12, 0x87, | ||
249 | 0x6d, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xc7, 0x0c, 0x9a, 0x97, 0xac, | ||
250 | 0xda, 0x36, 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x47, | ||
251 | 0xed, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8c, 0x7b, 0x55, 0x09, 0x90, 0xa2, 0xc6, 0xef, | ||
252 | 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xdf, | ||
253 | 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x59, 0x30, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x53, 0x05, 0x69, | ||
254 | 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0xb0, 0xe2, 0x27, 0xcc, 0xfb, 0x74, | ||
255 | 0x4b, 0x14, 0x8b, 0x94, 0x8b, 0x75, 0x68, 0x33, 0xc5, 0x08, 0x92, 0x87, 0x8c, 0x9a, 0xb6, | ||
256 | 0xcf, 0x1c, 0xba, 0xd7, 0x0d, 0x98, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0x89, 0x71, 0x60, | ||
257 | 0x23, 0xc4, 0x0a, 0x96, 0x8f, 0x9c, 0xba, 0xf6, 0x6e, 0x3f, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, | ||
258 | 0x26, 0xaf, 0xbd, 0xf8, 0x72, 0x66, 0x2f, 0xdc, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, | ||
259 | 0xb7, 0xcd, 0xf9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6f, 0x3d, 0xd9, 0x30, 0xe2, 0x27, 0xcc, | ||
260 | 0xfb, 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x70, 0x43, 0x04, 0x6b, 0x35, 0xc9, 0xf1, | ||
261 | 0x60, 0x23, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xe6, 0x2f, 0xbd, | ||
262 | 0xf8, 0x72, 0x66, 0x4e, 0x1e, 0xbe, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x1d, 0x99, 0x91, 0xa0, | ||
263 | 0xa3, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93, 0xa4, 0xab, 0xd4, 0x0b, 0x75, 0x49, 0x10, 0xa2, | ||
264 | 0xc6, 0xef, 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xb5, 0xe8, 0x33, 0xe4, 0x4a, 0x16, 0xae, 0xde, | ||
265 | 0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xb3, 0xc5, 0x08, 0x73, 0x45, 0xe9, 0x31, 0xc1, 0xe1, 0x21, | ||
266 | 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x86, 0x6f, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, 0x93, 0xa4, 0xca, | ||
267 | 0x16, 0xae, 0xde, 0x1f, 0x9d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x72, 0x47, 0x0c, | ||
268 | 0x9a, 0xb6, 0xcf, 0xfd, 0x59, 0x11, 0xa0, 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, | ||
269 | 0x6d, 0x39, 0xf0, 0x43, 0x04, 0x8a, 0x96, 0xae, 0xde, 0x3e, 0xdf, 0x1d, 0x99, 0x91, 0xa0, | ||
270 | 0xc2, 0x06, 0x6f, 0x3d, 0xf8, 0x72, 0x47, 0x0c, 0x9a, 0x97, 0x8d, 0x98, 0x93, 0x85, 0x88, | ||
271 | 0x73, 0x45, 0xe9, 0x31, 0xe0, 0x23, 0xa5, 0xa9, 0xd0, 0x03, 0x84, 0x8a, 0x96, 0xae, 0xde, | ||
272 | 0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xd2, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x82, | ||
273 | 0x67, 0x2d, 0xd8, 0x13, 0xa4, 0xab, 0xd4, 0x0b, 0x94, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, | ||
274 | 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0xe9, 0x50, 0x22, 0xc6, 0xef, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, | ||
275 | 0x93, 0x85, 0x88, 0x73, 0x64, 0x4a, 0xf7, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0x0a, 0x96, | ||
276 | 0xae, 0xde, 0x3e, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x78, 0x72, | ||
277 | 0x66, 0x2f, 0xbd, 0xd9, 0x30, 0xc3, 0xe5, 0x48, 0x12, 0x87, 0x8c, 0x7b, 0x55, 0x28, 0xd2, | ||
278 | 0x07, 0x8c, 0x9a, 0x97, 0xac, 0xda, 0x17, 0x8d, 0x79, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x54, | ||
279 | 0x0b, 0x94, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, 0x26, 0xaf, | ||
280 | 0xdc, 0x1b, 0xb4, 0xea, 0x37, 0xec, 0x3b, 0xf4, 0x6a, 0x37, 0xcd, 0x18, 0x93, 0x85, 0x69, | ||
281 | 0x31, 0xc1, 0xe1, 0x40, 0xe3, 0x25, 0xc8, 0x12, 0x87, 0x8c, 0x9a, 0xb6, 0xcf, 0xfd, 0x59, | ||
282 | 0x11, 0xa0, 0xc2, 0x06, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x37, | ||
283 | 0xec, 0x5a, 0x36, 0xee, 0x3f, 0xfc, 0x7a, 0x76, 0x4f, 0x1c, 0x9b, 0x95, 0x89, 0x71, 0x41, | ||
284 | 0x00, 0x63, 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x0f, 0x9c, 0xba, 0xd7, 0x0d, 0x98, 0x93, 0x85, | ||
285 | 0x69, 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x9e, 0xbe, 0xdf, 0x3c, 0xfa, 0x57, 0x2c, 0xda, | ||
286 | 0x36, 0xee, 0x3f, 0xfc, 0x5b, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, | ||
287 | 0x38, 0xf2, 0x47, 0xed, 0x58, 0x13, 0xa4, 0xca, 0xf7, 0x4d, 0xf9, 0x51, 0x01, 0x80, 0x63, | ||
288 | 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xa9, 0xb1, | ||
289 | 0xe0, 0x42, 0x06, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0x0a, 0x96, 0x8f, 0x7d, | ||
290 | 0x78, 0x72, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0xbc, 0xfa, 0x57, 0x0d, | ||
291 | 0x79, 0x51, 0x01, 0x61, 0x21, 0xa1, 0xc0, 0xe3, 0x25, 0xa9, 0xb1, 0xc1, 0xe1, 0x40, 0x02, | ||
292 | 0x67, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xd6, 0x0f, 0x9c, 0x9b, | ||
293 | 0xb4, 0xcb, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x35, 0xc9, 0xf1, | ||
294 | 0x60, 0x42, 0x06, 0x8e, 0x7f, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xfc, 0x7a, 0x76, 0x6e, 0x5e, | ||
295 | 0x3e, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xc0, 0xe3, 0x44, | ||
296 | 0xeb, 0x54, 0x2a, 0xb7, 0xcd, 0xf9, 0x70, 0x62, 0x27, 0xad, 0xd8, 0x32, 0xc7, 0x0c, 0x7b, | ||
297 | 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x6d, 0x39, 0xd1, 0x20, | ||
298 | 0xc2, 0xe7, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0xb2, 0xc7, 0x0c, 0x59, 0x28, 0xf3, 0x9b }; | ||
299 | |||
300 | // clang-format off | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pointer_transport.c b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pointer_transport.c new file mode 100644 index 000000000..003468c82 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/pointer_transport.c | |||
@@ -0,0 +1,375 @@ | |||
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 <string.h> | ||
18 | #include <stddef.h> | ||
19 | |||
20 | #include "matrix.h" | ||
21 | #include QMK_KEYBOARD_H | ||
22 | |||
23 | #define ROWS_PER_HAND (MATRIX_ROWS / 2) | ||
24 | |||
25 | #ifdef RGBLIGHT_ENABLE | ||
26 | # include "rgblight.h" | ||
27 | #endif | ||
28 | |||
29 | #ifdef BACKLIGHT_ENABLE | ||
30 | # include "backlight.h" | ||
31 | #endif | ||
32 | |||
33 | #ifdef ENCODER_ENABLE | ||
34 | # include "encoder.h" | ||
35 | static pin_t encoders_pad[] = ENCODERS_PAD_A; | ||
36 | # define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) | ||
37 | #endif | ||
38 | |||
39 | #ifdef POINTING_DEVICE_ENABLE | ||
40 | static uint16_t device_cpi = 0; | ||
41 | static int8_t split_mouse_x = 0, split_mouse_y = 0; | ||
42 | #endif | ||
43 | |||
44 | #if defined(USE_I2C) | ||
45 | |||
46 | # include "i2c_master.h" | ||
47 | # include "i2c_slave.h" | ||
48 | |||
49 | typedef struct _I2C_slave_buffer_t { | ||
50 | matrix_row_t smatrix[ROWS_PER_HAND]; | ||
51 | uint8_t backlight_level; | ||
52 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
53 | rgblight_syncinfo_t rgblight_sync; | ||
54 | # endif | ||
55 | # ifdef ENCODER_ENABLE | ||
56 | uint8_t encoder_state[NUMBER_OF_ENCODERS]; | ||
57 | # endif | ||
58 | # ifdef WPM_ENABLE | ||
59 | uint8_t current_wpm; | ||
60 | # endif | ||
61 | int8_t mouse_x; | ||
62 | int8_t mouse_y; | ||
63 | uint16_t device_cpi; | ||
64 | } I2C_slave_buffer_t; | ||
65 | |||
66 | static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; | ||
67 | |||
68 | # define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) | ||
69 | # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) | ||
70 | # define I2C_KEYMAP_START offsetof(I2C_slave_buffer_t, mmatrix) | ||
71 | # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) | ||
72 | # define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) | ||
73 | # define I2C_MOUSE_X_START offsetof(I2C_slave_buffer_t, mouse_x) | ||
74 | # define I2C_MOUSE_Y_START offsetof(I2C_slave_buffer_t, mouse_y) | ||
75 | # define I2C_MOUSE_DPI_START offsetof(I2C_slave_buffer_t, device_cpi) | ||
76 | # define TIMEOUT 100 | ||
77 | |||
78 | # ifndef SLAVE_I2C_ADDRESS | ||
79 | # define SLAVE_I2C_ADDRESS 0x32 | ||
80 | # endif | ||
81 | |||
82 | // Get rows from other half over i2c | ||
83 | bool transport_master(matrix_row_t matrix[]) { | ||
84 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_START, (void *)matrix, sizeof(i2c_buffer->smatrix), TIMEOUT); | ||
85 | |||
86 | // write backlight info | ||
87 | # ifdef BACKLIGHT_ENABLE | ||
88 | uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; | ||
89 | if (level != i2c_buffer->backlight_level) { | ||
90 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) { | ||
91 | i2c_buffer->backlight_level = level; | ||
92 | } | ||
93 | } | ||
94 | # endif | ||
95 | |||
96 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
97 | if (rgblight_get_change_flags()) { | ||
98 | rgblight_syncinfo_t rgblight_sync; | ||
99 | rgblight_get_syncinfo(&rgblight_sync); | ||
100 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) { | ||
101 | rgblight_clear_change_flags(); | ||
102 | } | ||
103 | } | ||
104 | # endif | ||
105 | |||
106 | # ifdef ENCODER_ENABLE | ||
107 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT); | ||
108 | encoder_update_raw(i2c_buffer->encoder_state); | ||
109 | # endif | ||
110 | |||
111 | # ifdef WPM_ENABLE | ||
112 | uint8_t current_wpm = get_current_wpm(); | ||
113 | if (current_wpm != i2c_buffer->current_wpm) { | ||
114 | if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)¤t_wpm, sizeof(current_wpm), TIMEOUT) >= 0) { | ||
115 | i2c_buffer->current_wpm = current_wpm; | ||
116 | } | ||
117 | } | ||
118 | # endif | ||
119 | |||
120 | # ifdef POINTING_DEVICE_ENABLE | ||
121 | if (is_keyboard_left()) { | ||
122 | report_mouse_t temp_report = pointing_device_get_report(); | ||
123 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT); | ||
124 | temp_report.x = i2c_buffer->mouse_x; | ||
125 | i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT); | ||
126 | temp_report.y = i2c_buffer->mouse_y; | ||
127 | pointing_device_set_report(temp_report); | ||
128 | |||
129 | if (device_cpi != i2c_buffer->device_cpi) { | ||
130 | if(i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_DPI_START, (void *)&device_cpi, sizeof(device_cpi), TIMEOUT) >= 0) { | ||
131 | i2c_buffer->device_cpi = device_cpi | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | # endif | ||
136 | |||
137 | return true; | ||
138 | } | ||
139 | |||
140 | void transport_slave(matrix_row_t matrix[]) { | ||
141 | // Copy matrix to I2C buffer | ||
142 | memcpy((void *)i2c_buffer->smatrix, (void *)matrix, sizeof(i2c_buffer->smatrix)); | ||
143 | |||
144 | // Read Backlight Info | ||
145 | # ifdef BACKLIGHT_ENABLE | ||
146 | backlight_set(i2c_buffer->backlight_level); | ||
147 | # endif | ||
148 | |||
149 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
150 | // Update the RGB with the new data | ||
151 | if (i2c_buffer->rgblight_sync.status.change_flags != 0) { | ||
152 | rgblight_update_sync(&i2c_buffer->rgblight_sync, false); | ||
153 | i2c_buffer->rgblight_sync.status.change_flags = 0; | ||
154 | } | ||
155 | # endif | ||
156 | |||
157 | # ifdef ENCODER_ENABLE | ||
158 | encoder_state_raw(i2c_buffer->encoder_state); | ||
159 | # endif | ||
160 | |||
161 | # ifdef WPM_ENABLE | ||
162 | set_current_wpm(i2c_buffer->current_wpm); | ||
163 | # endif | ||
164 | |||
165 | # ifdef POINTING_DEVICE_ENABLE | ||
166 | if (!is_keyboard_left()) { | ||
167 | static uint16_t cpi; | ||
168 | if (cpi != i2c_buffer->device_cpi) { | ||
169 | cpi = i2c_buffer->device_cpi; | ||
170 | pmw_set_cpi(cpi); | ||
171 | } | ||
172 | i2c_buffer->mouse_x = split_mouse_x; | ||
173 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT); | ||
174 | i2c_buffer->mouse_y = split_mouse_y; | ||
175 | i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT); | ||
176 | } | ||
177 | |||
178 | # endif | ||
179 | } | ||
180 | |||
181 | void transport_master_init(void) { i2c_init(); } | ||
182 | |||
183 | void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } | ||
184 | |||
185 | #else // USE_SERIAL | ||
186 | |||
187 | # include "serial.h" | ||
188 | |||
189 | typedef struct _Serial_s2m_buffer_t { | ||
190 | // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack | ||
191 | matrix_row_t smatrix[ROWS_PER_HAND]; | ||
192 | # ifdef ENCODER_ENABLE | ||
193 | uint8_t encoder_state[NUMBER_OF_ENCODERS]; | ||
194 | # endif | ||
195 | int8_t mouse_x; | ||
196 | int8_t mouse_y; | ||
197 | } Serial_s2m_buffer_t; | ||
198 | |||
199 | typedef struct _Serial_m2s_buffer_t { | ||
200 | # ifdef BACKLIGHT_ENABLE | ||
201 | uint8_t backlight_level; | ||
202 | # endif | ||
203 | # ifdef WPM_ENABLE | ||
204 | uint8_t current_wpm; | ||
205 | # endif | ||
206 | uint16_t device_cpi; | ||
207 | } Serial_m2s_buffer_t; | ||
208 | |||
209 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
210 | // When MCUs on both sides drive their respective RGB LED chains, | ||
211 | // it is necessary to synchronize, so it is necessary to communicate RGB | ||
212 | // information. In that case, define RGBLIGHT_SPLIT with info on the number | ||
213 | // of LEDs on each half. | ||
214 | // | ||
215 | // Otherwise, if the master side MCU drives both sides RGB LED chains, | ||
216 | // there is no need to communicate. | ||
217 | |||
218 | typedef struct _Serial_rgblight_t { | ||
219 | rgblight_syncinfo_t rgblight_sync; | ||
220 | } Serial_rgblight_t; | ||
221 | |||
222 | volatile Serial_rgblight_t serial_rgblight = {}; | ||
223 | uint8_t volatile status_rgblight = 0; | ||
224 | # endif | ||
225 | |||
226 | volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; | ||
227 | volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; | ||
228 | uint8_t volatile status0 = 0; | ||
229 | |||
230 | enum serial_transaction_id { | ||
231 | GET_SLAVE_MATRIX = 0, | ||
232 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
233 | PUT_RGBLIGHT, | ||
234 | # endif | ||
235 | }; | ||
236 | |||
237 | SSTD_t transactions[] = { | ||
238 | [GET_SLAVE_MATRIX] = | ||
239 | { | ||
240 | (uint8_t *)&status0, | ||
241 | sizeof(serial_m2s_buffer), | ||
242 | (uint8_t *)&serial_m2s_buffer, | ||
243 | sizeof(serial_s2m_buffer), | ||
244 | (uint8_t *)&serial_s2m_buffer, | ||
245 | }, | ||
246 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
247 | [PUT_RGBLIGHT] = | ||
248 | { | ||
249 | (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer | ||
250 | }, | ||
251 | # endif | ||
252 | }; | ||
253 | |||
254 | void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } | ||
255 | |||
256 | void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } | ||
257 | |||
258 | # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) | ||
259 | |||
260 | // rgblight synchronization information communication. | ||
261 | |||
262 | void transport_rgblight_master(void) { | ||
263 | if (rgblight_get_change_flags()) { | ||
264 | rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync); | ||
265 | if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) { | ||
266 | rgblight_clear_change_flags(); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | void transport_rgblight_slave(void) { | ||
272 | if (status_rgblight == TRANSACTION_ACCEPTED) { | ||
273 | rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false); | ||
274 | status_rgblight = TRANSACTION_END; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | # else | ||
279 | # define transport_rgblight_master() | ||
280 | # define transport_rgblight_slave() | ||
281 | # endif | ||
282 | |||
283 | bool transport_master(matrix_row_t matrix[]) { | ||
284 | # ifndef SERIAL_USE_MULTI_TRANSACTION | ||
285 | if (soft_serial_transaction() != TRANSACTION_END) { | ||
286 | return false; | ||
287 | } | ||
288 | # else | ||
289 | transport_rgblight_master(); | ||
290 | if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) { | ||
291 | return false; | ||
292 | } | ||
293 | # endif | ||
294 | |||
295 | // TODO: if MATRIX_COLS > 8 change to unpack() | ||
296 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | ||
297 | matrix[i] = serial_s2m_buffer.smatrix[i]; | ||
298 | } | ||
299 | |||
300 | # ifdef BACKLIGHT_ENABLE | ||
301 | // Write backlight level for slave to read | ||
302 | serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0; | ||
303 | # endif | ||
304 | |||
305 | # ifdef ENCODER_ENABLE | ||
306 | encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state); | ||
307 | # endif | ||
308 | |||
309 | # ifdef WPM_ENABLE | ||
310 | // Write wpm to slave | ||
311 | serial_m2s_buffer.current_wpm = get_current_wpm(); | ||
312 | # endif | ||
313 | |||
314 | # ifdef POINTING_DEVICE_ENABLE | ||
315 | if (is_keyboard_left()) { | ||
316 | report_mouse_t temp_report = pointing_device_get_report(); | ||
317 | temp_report.x = serial_s2m_buffer.mouse_x; | ||
318 | temp_report.y = serial_s2m_buffer.mouse_y; | ||
319 | pointing_device_set_report(temp_report); | ||
320 | serial_m2s_buffer.device_cpi = device_cpi; | ||
321 | } | ||
322 | # endif | ||
323 | |||
324 | return true; | ||
325 | } | ||
326 | |||
327 | void transport_slave(matrix_row_t matrix[]) { | ||
328 | transport_rgblight_slave(); | ||
329 | |||
330 | // TODO: if MATRIX_COLS > 8 change to pack() | ||
331 | for (int i = 0; i < ROWS_PER_HAND; ++i) { | ||
332 | serial_s2m_buffer.smatrix[i] = matrix[i]; | ||
333 | } | ||
334 | |||
335 | # ifdef BACKLIGHT_ENABLE | ||
336 | backlight_set(serial_m2s_buffer.backlight_level); | ||
337 | # endif | ||
338 | |||
339 | # ifdef ENCODER_ENABLE | ||
340 | encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state); | ||
341 | # endif | ||
342 | |||
343 | # ifdef WPM_ENABLE | ||
344 | set_current_wpm(serial_m2s_buffer.current_wpm); | ||
345 | # endif | ||
346 | |||
347 | # ifdef POINTING_DEVICE_ENABLE | ||
348 | if (!is_keyboard_left()) { | ||
349 | static uint16_t cpi; | ||
350 | if (cpi != serial_m2s_buffer.device_cpi) { | ||
351 | cpi = serial_m2s_buffer.device_cpi; | ||
352 | pmw_set_cpi(cpi); | ||
353 | } | ||
354 | serial_s2m_buffer.mouse_x = split_mouse_x; | ||
355 | serial_s2m_buffer.mouse_y = split_mouse_y; | ||
356 | } | ||
357 | |||
358 | # endif | ||
359 | } | ||
360 | |||
361 | #endif | ||
362 | |||
363 | #ifdef POINTING_DEVICE_ENABLE | ||
364 | void master_mouse_send(int8_t x, int8_t y) { | ||
365 | split_mouse_x = x; | ||
366 | split_mouse_y = y; | ||
367 | } | ||
368 | void trackball_set_cpi(uint16_t cpi) { | ||
369 | if (!is_keyboard_left()) { | ||
370 | pmw_set_cpi(cpi); | ||
371 | } else { | ||
372 | device_cpi = cpi * 1.5; | ||
373 | } | ||
374 | } | ||
375 | #endif | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/post_config.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/post_config.h new file mode 100644 index 000000000..40f1029b5 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/post_config.h | |||
@@ -0,0 +1,33 @@ | |||
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 | #ifndef MOUSEKEY_WHEEL_DELTA | ||
20 | # define MOUSEKEY_WHEEL_DELTA 1 | ||
21 | #endif | ||
22 | #ifndef MOUSEKEY_WHEEL_DELAY | ||
23 | # define MOUSEKEY_WHEEL_DELAY 200 | ||
24 | #endif | ||
25 | #ifndef MOUSEKEY_WHEEL_INTERVAL | ||
26 | # define MOUSEKEY_WHEEL_INTERVAL 50 | ||
27 | #endif | ||
28 | #ifndef MOUSEKEY_WHEEL_MAX_SPEED | ||
29 | # define MOUSEKEY_WHEEL_MAX_SPEED 8 | ||
30 | #endif | ||
31 | #ifndef MOUSEKEY_WHEEL_TIME_TO_MAX | ||
32 | # define MOUSEKEY_WHEEL_TIME_TO_MAX 80 | ||
33 | #endif | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/readme.md b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/readme.md new file mode 100644 index 000000000..b6e38dc84 --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/readme.md | |||
@@ -0,0 +1,21 @@ | |||
1 | # Drashna's Dactyl Manuform (5x6) with a right side trackball | ||
2 | |||
3 |  | ||
4 | |||
5 | It's a Dactyl Manuform with an integrated thumb based trackball, using the pmw3360 optical sensor. | ||
6 | |||
7 | It's powered by 2x Teensy++ 2.0's, using Drashna's [Teensy VBUS Hack](https://docs.qmk.fm/#/feature_split_keyboard?id=hardware-considerations-and-mods) for better detection. | ||
8 | |||
9 | |||
10 | * Keyboard Maintainer: [Drashna Jael're](https://github.com/drashna) | ||
11 | * Hardware Supported: [Design files](https://gitlab.com/keyboards1/dm_r_track/-/tree/master/boolean), [Teensy++ 2.0 (2x)](https://www.pjrc.com/store/teensypp.html), [PMW3360 Optical Sensor](https://www.tindie.com/products/jkicklighter/pmw3360-motion-sensor/) | ||
12 | |||
13 | Make example for this keyboard (after setting up your build environment): | ||
14 | |||
15 | make handwired/dactyl_manuform/5x6_right_trackball:default | ||
16 | |||
17 | Flashing example for this keyboard: | ||
18 | |||
19 | make handwired/dactyl_manuform/5x6_right_trackball:default:flash | ||
20 | |||
21 | 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). | ||
diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk new file mode 100644 index 000000000..19b330cdc --- /dev/null +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/rules.mk | |||
@@ -0,0 +1,30 @@ | |||
1 | # MCU name | ||
2 | MCU = at90usb1286 | ||
3 | |||
4 | # Bootloader selection | ||
5 | BOOTLOADER = halfkay | ||
6 | |||
7 | # Build Options | ||
8 | # change yes to no to disable | ||
9 | # | ||
10 | BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration | ||
11 | MOUSEKEY_ENABLE = yes # Mouse keys | ||
12 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
13 | CONSOLE_ENABLE = no # Console for debug | ||
14 | COMMAND_ENABLE = yes # Commands for debug and configuration | ||
15 | # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | ||
16 | SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | ||
17 | # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work | ||
18 | NKRO_ENABLE = no # USB Nkey Rollover | ||
19 | BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | ||
20 | RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow | ||
21 | BLUETOOTH_ENABLE = no # Enable Bluetooth | ||
22 | AUDIO_ENABLE = no # Audio output | ||
23 | SWAP_HANDS_ENABLE = yes | ||
24 | POINTING_DEVICE_ENABLE = yes | ||
25 | |||
26 | SPLIT_KEYBOARD = yes | ||
27 | SPLIT_TRANSPORT = custom | ||
28 | |||
29 | SRC += pointer_transport.c pmw3360.c | ||
30 | QUANTUM_LIB_SRC += serial.c i2c_master.c i2c_slave.c spi_master.c | ||
diff --git a/keyboards/handwired/dactyl_manuform/dactyl_manuform.h b/keyboards/handwired/dactyl_manuform/dactyl_manuform.h index c91b247f1..7352b5e83 100644 --- a/keyboards/handwired/dactyl_manuform/dactyl_manuform.h +++ b/keyboards/handwired/dactyl_manuform/dactyl_manuform.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include "6x6.h" | 14 | #include "6x6.h" |
15 | #elif KEYBOARD_handwired_dactyl_manuform_dmote_62key | 15 | #elif KEYBOARD_handwired_dactyl_manuform_dmote_62key |
16 | #include "62key.h" | 16 | #include "62key.h" |
17 | #elif KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball | ||
18 | # include "5x6_right_trackball.h" | ||
17 | #endif | 19 | #endif |
18 | 20 | ||
19 | #include "quantum.h" | 21 | #include "quantum.h" |