aboutsummaryrefslogtreecommitdiff
path: root/keyboards/ferris
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/ferris')
-rw-r--r--keyboards/ferris/0_1/0_1.c17
-rw-r--r--keyboards/ferris/0_1/0_1.h43
-rw-r--r--keyboards/ferris/0_1/config.h60
-rw-r--r--keyboards/ferris/0_1/matrix.c282
-rw-r--r--keyboards/ferris/0_1/rules.mk28
-rw-r--r--keyboards/ferris/info.json54
-rw-r--r--keyboards/ferris/keymaps/default/config.h39
-rw-r--r--keyboards/ferris/keymaps/default/keymap.json106
-rw-r--r--keyboards/ferris/keymaps/default/readme.md122
-rwxr-xr-xkeyboards/ferris/keymaps/json2crab.py76
-rw-r--r--keyboards/ferris/keymaps/pierrec83/config.h39
-rw-r--r--keyboards/ferris/keymaps/pierrec83/keymap.json118
-rw-r--r--keyboards/ferris/keymaps/pierrec83/readme.md43
-rw-r--r--keyboards/ferris/readme.md19
-rw-r--r--keyboards/ferris/sweep/config.h74
-rw-r--r--keyboards/ferris/sweep/rules.mk24
-rw-r--r--keyboards/ferris/sweep/sweep.c16
-rw-r--r--keyboards/ferris/sweep/sweep.h47
18 files changed, 1207 insertions, 0 deletions
diff --git a/keyboards/ferris/0_1/0_1.c b/keyboards/ferris/0_1/0_1.c
new file mode 100644
index 000000000..dbdb0b4bd
--- /dev/null
+++ b/keyboards/ferris/0_1/0_1.c
@@ -0,0 +1,17 @@
1/*
2Copyright 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "0_1.h"
diff --git a/keyboards/ferris/0_1/0_1.h b/keyboards/ferris/0_1/0_1.h
new file mode 100644
index 000000000..4602637ca
--- /dev/null
+++ b/keyboards/ferris/0_1/0_1.h
@@ -0,0 +1,43 @@
1/*
2Copyright 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include "quantum.h"
21
22// clang-format off
23
24/* left hand right hand */
25#define LAYOUT(\
26 K0_0, K0_1, K0_2, K0_3, K0_4, K0_5, K0_6, K0_7, K0_8, K0_9,\
27 K1_0, K1_1, K1_2, K1_3, K1_4, K1_5, K1_6, K1_7, K1_8, K1_9,\
28 K2_0, K2_1, K2_2, K2_3, K2_4, K2_5, K2_6, K2_7, K2_8, K2_9,\
29 K3_3, K3_4, K3_5, K3_6)\
30/* matrix positions */\
31{\
32 {K0_0, K0_1, K0_2, K0_3, K0_4},\
33 {K1_0, K1_1, K1_2, K1_3, K1_4},\
34 {K2_0, K2_1, K2_2, K2_3, K2_4},\
35 {KC_NO, KC_NO, KC_NO, K3_3, K3_4},\
36 \
37 {K0_5, K0_6, K0_7, K0_8, K0_9},\
38 {K1_5, K1_6, K1_7, K1_8, K1_9},\
39 {K2_5, K2_6, K2_7, K2_8, K2_9},\
40 {K3_5, K3_6, KC_NO, KC_NO, KC_NO}\
41}
42
43// clang-format on
diff --git a/keyboards/ferris/0_1/config.h b/keyboards/ferris/0_1/config.h
new file mode 100644
index 000000000..33494d927
--- /dev/null
+++ b/keyboards/ferris/0_1/config.h
@@ -0,0 +1,60 @@
1/*
2Copyright 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20/* USB Device descriptor parameter */
21#define VENDOR_ID 0xC2AB
22#define PRODUCT_ID 0x0000
23#define DEVICE_VER 0x0001
24#define MANUFACTURER Pierre
25#define PRODUCT Ferris the keeb
26#define DESCRIPTION A minimalistic 34 - keys split keyboard
27
28/* key matrix size */
29#define MATRIX_ROWS 8
30#define MATRIX_COLS 10
31
32#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
33#define MATRIX_COLS_PER_SIDE (MATRIX_COLS / 2)
34
35#define UNUSED_MCU 14
36#define UNUSED_MCP 7
37
38// wiring
39#define MATRIX_ROW_PINS_MCU \
40 { B3, B2, B1, F0 }
41#define MATRIX_COL_PINS_MCU \
42 { D6, D7, B4, B5, B6 }
43#define UNUSED_PINS_MCU \
44 { B0, B7, C6, C7, D2, D3, D4, D5, E6, F1, F4, F5, F6, F7 }
45#define MATRIX_ROW_PINS_MCP \
46 { B0, B1, B2, B3 }
47#define MATRIX_COL_PINS_MCP \
48 { A0, A1, A2, A3, A4 }
49#define UNUSED_PINS_MCP \
50 { B4, B5, B6, B7, A5, A6, A7 }
51
52/* COL2ROW, ROW2COL*/
53#define DIODE_DIRECTION COL2ROW
54
55/* define if matrix has ghost (lacks anti-ghosting diodes) */
56//#define MATRIX_HAS_GHOST
57
58/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
59#define DEBOUNCE 5
60
diff --git a/keyboards/ferris/0_1/matrix.c b/keyboards/ferris/0_1/matrix.c
new file mode 100644
index 000000000..e13c35d35
--- /dev/null
+++ b/keyboards/ferris/0_1/matrix.c
@@ -0,0 +1,282 @@
1/*
2Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
3 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/*
20 * This code was heavily inspired by the ergodox_ez keymap, and modernized
21 * to take advantage of the quantum.h microcontroller agnostics gpio control
22 * abstractions and use the macros defined in config.h for the wiring as opposed
23 * to repeating that information all over the place.
24 */
25
26#include QMK_KEYBOARD_H
27#include "i2c_master.h"
28
29extern i2c_status_t mcp23017_status;
30#define I2C_TIMEOUT 1000
31
32// For a better understanding of the i2c protocol, this is a good read:
33// https://www.robot-electronics.co.uk/i2c-tutorial
34
35// I2C address:
36// See the datasheet, section 3.3.1 on addressing I2C devices and figure 3-6 for an
37// illustration
38// http://ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf
39// All address pins of the mcp23017 are connected to the ground on the ferris
40// | 0 | 1 | 0 | 0 | A2 | A1 | A0 |
41// | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
42#define I2C_ADDR 0b0100000
43#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE)
44#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ)
45
46// Register addresses
47// See https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h
48#define IODIRA 0x00 // i/o direction register
49#define IODIRB 0x01
50#define GPPUA 0x0C // GPIO pull-up resistor register
51#define GPPUB 0x0D
52#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
53#define GPIOB 0x13
54#define OLATA 0x14 // output latch register
55#define OLATB 0x15
56
57bool i2c_initialized = 0;
58i2c_status_t mcp23017_status = I2C_ADDR;
59
60uint8_t init_mcp23017(void) {
61 print("starting init");
62 mcp23017_status = I2C_ADDR;
63
64 // I2C subsystem
65 if (i2c_initialized == 0) {
66 i2c_init(); // on pins D(1,0)
67 i2c_initialized = true;
68 wait_ms(I2C_TIMEOUT);
69 }
70
71 // set pin direction
72 // - unused : input : 1
73 // - input : input : 1
74 // - driving : output : 0
75 mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
76 if (mcp23017_status) goto out;
77 mcp23017_status = i2c_write(IODIRA, I2C_TIMEOUT);
78 if (mcp23017_status) goto out;
79 // This means: we will read all the bits on GPIOA
80 mcp23017_status = i2c_write(0b11111111, I2C_TIMEOUT);
81 if (mcp23017_status) goto out;
82 // This means: we will write to the pins 0-4 on GPIOB (in select_rows)
83 mcp23017_status = i2c_write(0b11110000, I2C_TIMEOUT);
84 if (mcp23017_status) goto out;
85 i2c_stop();
86
87 // set pull-up
88 // - unused : on : 1
89 // - input : on : 1
90 // - driving : off : 0
91 mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
92 if (mcp23017_status) goto out;
93 mcp23017_status = i2c_write(GPPUA, I2C_TIMEOUT);
94 if (mcp23017_status) goto out;
95 // This means: we will read all the bits on GPIOA
96 mcp23017_status = i2c_write(0b11111111, I2C_TIMEOUT);
97 if (mcp23017_status) goto out;
98 // This means: we will write to the pins 0-4 on GPIOB (in select_rows)
99 mcp23017_status = i2c_write(0b11110000, I2C_TIMEOUT);
100 if (mcp23017_status) goto out;
101
102out:
103 i2c_stop();
104 return mcp23017_status;
105}
106
107/* matrix state(1:on, 0:off) */
108static matrix_row_t matrix[MATRIX_ROWS]; // debounced values
109
110static matrix_row_t read_cols(uint8_t row);
111static void init_cols(void);
112static void unselect_rows(void);
113static void select_row(uint8_t row);
114
115static uint8_t mcp23017_reset_loop;
116
117void matrix_init_custom(void) {
118 // initialize row and col
119
120 mcp23017_status = init_mcp23017();
121
122 unselect_rows();
123 init_cols();
124
125 // initialize matrix state: all keys off
126 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
127 matrix[i] = 0;
128 }
129}
130
131void matrix_power_up(void) {
132 mcp23017_status = init_mcp23017();
133
134 unselect_rows();
135 init_cols();
136
137 // initialize matrix state: all keys off
138 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
139 matrix[i] = 0;
140 }
141}
142
143// Reads and stores a row, returning
144// whether a change occurred.
145static inline bool store_matrix_row(matrix_row_t current_matrix[], uint8_t index) {
146 matrix_row_t temp = read_cols(index);
147 if (current_matrix[index] != temp) {
148 current_matrix[index] = temp;
149 return true;
150 }
151 return false;
152}
153
154bool matrix_scan_custom(matrix_row_t current_matrix[]) {
155 if (mcp23017_status) { // if there was an error
156 if (++mcp23017_reset_loop == 0) {
157 // if (++mcp23017_reset_loop >= 1300) {
158 // since mcp23017_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
159 // this will be approx bit more frequent than once per second
160 dprint("trying to reset mcp23017\n");
161 mcp23017_status = init_mcp23017();
162 if (mcp23017_status) {
163 dprint("right side not responding\n");
164 } else {
165 dprint("right side attached\n");
166 }
167 }
168 }
169
170 bool changed = false;
171 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) {
172 // select rows from left and right hands
173 uint8_t left_index = i;
174 uint8_t right_index = i + MATRIX_ROWS_PER_SIDE;
175 select_row(left_index);
176 select_row(right_index);
177
178 // we don't need a 30us delay anymore, because selecting a
179 // left-hand row requires more than 30us for i2c.
180
181 changed |= store_matrix_row(current_matrix, left_index);
182 changed |= store_matrix_row(current_matrix, right_index);
183
184 unselect_rows();
185 }
186
187 return changed;
188}
189
190static void init_cols(void) {
191 // init on mcp23017
192 // not needed, already done as part of init_mcp23017()
193
194 // init on mcu
195 pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_MCU;
196 for (int pin_index = 0; pin_index < MATRIX_COLS_PER_SIDE; pin_index++) {
197 pin_t pin = matrix_col_pins_mcu[pin_index];
198 setPinInput(pin);
199 writePinHigh(pin);
200 }
201}
202
203static matrix_row_t read_cols(uint8_t row) {
204 if (row < MATRIX_ROWS_PER_SIDE) {
205 pin_t matrix_col_pins_mcu[MATRIX_COLS_PER_SIDE] = MATRIX_COL_PINS_MCU;
206 matrix_row_t current_row_value = 0;
207 // For each col...
208 for (uint8_t col_index = 0; col_index < MATRIX_COLS_PER_SIDE; col_index++) {
209 // Select the col pin to read (active low)
210 uint8_t pin_state = readPin(matrix_col_pins_mcu[col_index]);
211
212 // Populate the matrix row with the state of the col pin
213 current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
214 }
215 return current_row_value;
216 } else {
217 if (mcp23017_status) { // if there was an error
218 return 0;
219 } else {
220 uint8_t data = 0;
221 mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
222 if (mcp23017_status) goto out;
223 mcp23017_status = i2c_write(GPIOA, I2C_TIMEOUT);
224 if (mcp23017_status) goto out;
225 mcp23017_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT);
226 if (mcp23017_status) goto out;
227 mcp23017_status = i2c_read_nack(I2C_TIMEOUT);
228 if (mcp23017_status < 0) goto out;
229 // We read all the pins on GPIOA.
230 // The initial state was all ones and any depressed key at a given column for the currently selected row will have its bit flipped to zero.
231 // The return value is a row as represented in the generic matrix code were the rightmost bits represent the lower columns and zeroes represent non-depressed keys while ones represent depressed keys.
232 // Since the pins connected to eact columns are sequential, and counting from zero up (col 5 -> GPIOA0, col 6 -> GPIOA1 and so on), the only transformation needed is a bitwise not to swap all zeroes and ones.
233 data = ~((uint8_t)mcp23017_status);
234 mcp23017_status = I2C_STATUS_SUCCESS;
235 out:
236 i2c_stop();
237 // return reverse_bits(data, MATRIX_COLS_PER_SIDE);
238 return data;
239 }
240 }
241}
242
243static void unselect_rows(void) {
244 // no need to unselect on mcp23017, because the select step sets all
245 // the other row bits high, and it's not changing to a different
246 // direction
247
248 // unselect rows on microcontroller
249 pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_MCU;
250 for (int pin_index = 0; pin_index < MATRIX_ROWS_PER_SIDE; pin_index++) {
251 pin_t pin = matrix_row_pins_mcu[pin_index];
252 setPinInput(pin);
253 writePinLow(pin);
254 }
255}
256
257static void select_row(uint8_t row) {
258 if (row < MATRIX_ROWS_PER_SIDE) {
259 // select on atmega32u4
260 pin_t matrix_row_pins_mcu[MATRIX_ROWS_PER_SIDE] = MATRIX_ROW_PINS_MCU;
261 pin_t pin = matrix_row_pins_mcu[row];
262 setPinOutput(pin);
263 writePinLow(pin);
264 } else {
265 // select on mcp23017
266 if (mcp23017_status) { // if there was an error
267 // do nothing
268 } else {
269 mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
270 if (mcp23017_status) goto out;
271 mcp23017_status = i2c_write(GPIOB, I2C_TIMEOUT);
272 if (mcp23017_status) goto out;
273 // Select the desired row by writing a byte for the entire GPIOB bus where only the bit representing the row we want to select is a zero (write instruction) and every other bit is a one.
274 // Note that the row - MATRIX_ROWS_PER_SIDE reflects the fact that being on the right hand, the columns are numbered from MATRIX_ROWS_PER_SIDE to MATRIX_ROWS, but the pins we want to write to are indexed from zero up on the GPIOB bus.
275 mcp23017_status = i2c_write(0xFF & ~(1 << (row - MATRIX_ROWS_PER_SIDE)), I2C_TIMEOUT);
276
277 if (mcp23017_status) goto out;
278 out:
279 i2c_stop();
280 }
281 }
282}
diff --git a/keyboards/ferris/0_1/rules.mk b/keyboards/ferris/0_1/rules.mk
new file mode 100644
index 000000000..8645dbba0
--- /dev/null
+++ b/keyboards/ferris/0_1/rules.mk
@@ -0,0 +1,28 @@
1# MCU name
2MCU = atmega32u4
3
4# Bootloader selection
5BOOTLOADER = atmel-dfu
6
7# change yes to no to disable
8#
9BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
10MOUSEKEY_ENABLE = yes # Mouse keys
11EXTRAKEY_ENABLE = yes # Audio control and System control
12CONSOLE_ENABLE = no # Console for debug
13COMMAND_ENABLE = no # Commands for debug and configuration
14# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
15SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
16# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
17NKRO_ENABLE = no # USB Nkey Rollover
18BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
19RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
20BLUETOOTH_ENABLE = no # Enable Bluetooth
21AUDIO_ENABLE = no # Audio output
22UNICODE_ENABLE = yes
23CUSTOM_MATRIX = lite
24NO_USB_STARTUP_CHECK = yes
25LTO_ENABLE = yes
26
27SRC += matrix.c
28QUANTUM_LIB_SRC += i2c_master.c
diff --git a/keyboards/ferris/info.json b/keyboards/ferris/info.json
new file mode 100644
index 000000000..ffffb58ec
--- /dev/null
+++ b/keyboards/ferris/info.json
@@ -0,0 +1,54 @@
1{
2 "keyboard_name": "Ferris",
3 "url": "https://github.com/pierrechevalier83/ferris/",
4 "maintainer": "@pierrec83",
5 "width": 12,
6 "height": 4.75,
7 "layouts": {
8 "LAYOUT": {
9 "layout": [
10 {"x": 0, "y": 0.93},
11 {"x": 1, "y": 0.31},
12 {"x": 2, "y": 0},
13 {"x": 3, "y": 0.28},
14 {"x": 4, "y": 0.42},
15
16 {"x": 7, "y": 0.42},
17 {"x": 8, "y": 0.28},
18 {"x": 9, "y": 0},
19 {"x": 10, "y": 0.31},
20 {"x": 11, "y": 0.93},
21
22 {"x": 0, "y": 1.93},
23 {"x": 1, "y": 1.31},
24 {"x": 2, "y": 1},
25 {"x": 3, "y": 1.28},
26 {"x": 4, "y": 1.42},
27
28 {"x": 7, "y": 1.42},
29 {"x": 8, "y": 1.28},
30 {"x": 9, "y": 1},
31 {"x": 10, "y": 1.31},
32 {"x": 11, "y": 1.93},
33
34 {"x": 0, "y": 2.93},
35 {"x": 1, "y": 2.31},
36 {"x": 2, "y": 2},
37 {"x": 3, "y": 2.28},
38 {"x": 4, "y": 2.42},
39
40 {"x": 7, "y": 2.42},
41 {"x": 8, "y": 2.28},
42 {"x": 9, "y": 2},
43 {"x": 10, "y": 2.31},
44 {"x": 11, "y": 2.93},
45
46 {"x": 3.5, "y": 3.75},
47 {"x": 4.5, "y": 4},
48
49 {"x": 6.5, "y": 4},
50 {"x": 7.5, "y": 3.75}
51 ]
52 }
53 }
54}
diff --git a/keyboards/ferris/keymaps/default/config.h b/keyboards/ferris/keymaps/default/config.h
new file mode 100644
index 000000000..cf0fb7478
--- /dev/null
+++ b/keyboards/ferris/keymaps/default/config.h
@@ -0,0 +1,39 @@
1/*
2Copyright 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19// Set the mouse settings to a comfortable speed/accuracy trade-off,
20// assuming a screen refresh rate of 60 Htz or higher
21// The default is 50. This makes the mouse ~3 times faster and more accurate
22#define MOUSEKEY_INTERVAL 16
23// The default is 20. Since we made the mouse about 3 times faster with the previous setting,
24// give it more time to accelerate to max speed to retain precise control over short distances.
25#define MOUSEKEY_TIME_TO_MAX 40
26// The default is 300. Let's try and make this as low as possible while keeping the cursor responsive
27#define MOUSEKEY_DELAY 100
28// It makes sense to use the same delay for the mouseweel
29#define MOUSEKEY_WHEEL_DELAY 100
30// The default is 100
31#define MOUSEKEY_WHEEL_INTERVAL 50
32// The default is 40
33#define MOUSEKEY_WHEEL_TIME_TO_MAX 100
34
35// Pick good defaults for enabling homerow modifiers
36#define TAPPING_TERM 200
37#define PERMISSIVE_HOLD
38#define IGNORE_MOD_TAP_INTERRUPT
39#define TAPPING_FORCE_HOLD
diff --git a/keyboards/ferris/keymaps/default/keymap.json b/keyboards/ferris/keymaps/default/keymap.json
new file mode 100644
index 000000000..7f7d614e2
--- /dev/null
+++ b/keyboards/ferris/keymaps/default/keymap.json
@@ -0,0 +1,106 @@
1{ "version": 1,
2 "notes": "My awesome keymap",
3 "documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n",
4 "keyboard": "handwired/ferris",
5 "keymap": "default",
6 "layout": "LAYOUT",
7 "layers": [
8 ["KC_Q" , "KC_W" , "KC_E" , "KC_R" , "KC_T",
9 "KC_Y" , "KC_U" , "KC_I" , "KC_O" , "KC_P",
10
11 "LSFT_T(KC_A)", "LT(5,KC_S)" , "LT(1,KC_D)" , "LT(3,KC_F)" , "KC_G",
12 "KC_H" , "LT(4,KC_J)" , "LT(2,KC_K)" , "LT(6,KC_L)" , "LSFT_T(KC_SCLN)",
13
14 "KC_Z" , "LCTL_T(KC_X)", "LALT_T(KC_C)" , "KC_V" , "KC_B",
15 "KC_N" , "KC_M" , "LALT_T(KC_COMM)", "LCTL_T(KC_DOT)", "KC_SLSH",
16
17 "KC_P0" , "KC_BSPC",
18 "LT(7,KC_SPC)", "KC_P1"
19 ],
20 ["KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
21 "KC_TRNS" , "KC_BTN1" , "KC_WH_U" , "KC_BTN2" , "KC_TRNS",
22
23 "KC_TRNS" , "KC_BTN2" , "KC_NO" , "KC_BTN1" , "KC_TRNS",
24 "KC_TRNS" , "KC_MS_L" , "KC_MS_D" , "KC_MS_U" , "KC_MS_R",
25
26 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
27 "KC_TRNS" , "KC_WH_L" , "KC_WH_D" , "KC_WH_R" , "KC_TRNS",
28
29 "KC_TRNS" , "KC_TRNS",
30 "KC_TRNS" , "KC_TRNS"
31 ],
32 ["KC_TRNS" , "KC_TRNS" , "KC_PGUP" , "KC_TRNS" , "KC_TRNS",
33 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
34
35 "KC_LEFT" , "KC_UP" , "KC_DOWN" , "KC_RGHT" , "KC_TRNS",
36 "KC_TRNS" , "KC_LGUI" , "KC_NO" , "LCTL(KC_LALT)" , "LCA(KC_LSFT)",
37
38 "KC_TRNS" , "KC_HOME" , "KC_PGDN" , "KC_END" , "KC_TRNS",
39 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
40
41 "KC_TRNS" , "KC_TRNS",
42 "KC_TRNS" , "KC_TRNS"
43 ],
44 ["KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
45 "KC_TRNS" , "KC_UNDS" , "KC_PIPE" , "KC_QUOT" , "KC_TRNS",
46
47 "KC_CIRC" , "KC_ASTR" , "KC_AMPR" , "KC_NO" , "KC_TRNS",
48 "KC_HASH" , "KC_TILD" , "KC_SLSH" , "KC_DQUO" , "KC_DLR",
49
50 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
51 "KC_TRNS" , "KC_MINS" , "KC_BSLS" , "KC_GRV" , "KC_TRNS",
52
53 "KC_TRNS" , "KC_TRNS",
54 "KC_TRNS" , "KC_TRNS"
55 ],
56 ["KC_TRNS" , "KC_COLN" , "KC_LT" , "KC_GT" , "KC_SCLN",
57 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
58
59 "KC_LCBR" , "KC_RCBR" , "KC_LPRN" , "KC_RPRN" , "KC_AT",
60 "KC_TRNS" , "KC_NO" , "KC_EQL" , "KC_PLUS" , "KC_PERC",
61
62 "KC_TRNS" , "KC_EXLM" , "KC_LBRC" , "KC_RBRC" , "KC_TRNS",
63 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
64
65 "KC_VOLD" , "KC_TRNS",
66 "KC_TRNS" , "KC_VOLU"
67 ],
68 ["KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
69 "KC_TRNS" , "KC_F7" , "KC_F8" , "KC_F9" , "KC_F10",
70
71 "KC_TRNS" , "KC_NO" , "LCTL(KC_LALT)" , "KC_TRNS" , "KC_TRNS",
72 "KC_TRNS" , "KC_F4" , "KC_F5" , "KC_F6" , "KC_F11",
73
74 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
75 "KC_TRNS" , "KC_F1" , "KC_F2" , "KC_F3" , "KC_F12",
76
77 "KC_TRNS" , "KC_TRNS",
78 "KC_TRNS" , "KC_TRNS"
79 ],
80 ["KC_PSLS" , "KC_7" , "KC_8" , "KC_9" , "KC_PPLS",
81 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
82
83 "KC_0" , "KC_1" , "KC_2" , "KC_3" , "KC_PMNS",
84 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_NO" , "KC_TRNS",
85
86 "KC_PAST" , "KC_4" , "KC_5" , "KC_6" , "KC_PEQL",
87 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
88
89 "KC_TRNS" , "KC_TRNS",
90 "KC_TRNS" , "KC_TRNS"
91 ],
92 ["KC_TRNS" , "KC_TRNS" , "KC_COLN" , "KC_ESC" , "KC_TRNS",
93 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_DEL",
94
95 "KC_TRNS" , "KC_PERC" , "KC_SLSH" , "KC_ENT" , "KC_TRNS",
96 "DF(1)" , "KC_LGUI" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
97
98 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_EXLM" , "KC_TRNS",
99 "DF(0)" , "KC_TRNS" , "RALT_T(KC_COMM)", "RCTL_T(KC_DOT)", "RESET",
100
101 "KC_TRNS" , "KC_TAB",
102 "KC_NO" , "KC_TRNS"
103 ]
104 ],
105 "author": "@pierrec83"
106}
diff --git a/keyboards/ferris/keymaps/default/readme.md b/keyboards/ferris/keymaps/default/readme.md
new file mode 100644
index 000000000..252f886f5
--- /dev/null
+++ b/keyboards/ferris/keymaps/default/readme.md
@@ -0,0 +1,122 @@
1A usable default keymap for the Ferris keyboard
2===============================================
3
4Keymaps in general are quite personal, so it is difficult to come up with a default that will suit every user.
5
6This keymap makes heavy use of keys behaving differently when tapped and held, so that all the keys one may need remain accessible despite the low number of thumb keys.
7
8It comes with a number of layers to give access to most of the keys one may need on a keyboard. It is not meant to be the best possible keymap, but rather a good base on which to build a keymap that works for you.
9
10This is not the only way to make 34 keys a comfortable typing experience, but it is one way to do so. If you don't already know of a better way, this may be as good a starting point as any :)
11
12Note that this keymap was built from the perspective that it is OK to take a steep learning curve if it results in a keymap that is easier to use in the long run. This means that it may take more effort to learn this keymap than some alternatives. "Easy to use" was assessed against the workflow of the author, so your mileage may vary on some of the details.
13
14What do all these layers do?
15----------------------------
16
17### Layer 0: Base layer
18
19![Layer 0](https://i.imgur.com/HjNHUPL.png)
20
21On tapping the keys, our base layer is qwerty with space on the right homing thumb and backspace on the left homing thumb.
22
23In this layer, the non-homing-thumb positions have 0 and 1. I recommend modifying this to some frequently accessed shortcut such as copy/paste, previous/next tab or anything that makes most sense in your own workflow. O and 1 are place-holders and make it easy to troubleshoot that all keys are working properly before soldering in the switches.
24The reason I recommend convenience shortcuts instead of more commonly used keys like tab or meta is that unhoming of the thumbs was a frequent source of typos for me when I used more than one thumb key frequently in the context of typing.
25
26Despite being missing on this layer, "meta", "tab", "esc" and such are accessible from any other layer: see Layer 7.
27
28The behaviour of some keys differ when held:
29* Both homing pinkies behave as shift.
30* Both bottom-row ring fingers behave as ctrl.
31* Both bottom-row middle fingers behave as alt.
32
33* The homing left ring finger gives access to the Function keys layer
34* The homing right ring finger gives access to the Numbers layer
35* The homing left middle finger gives access to the Mouse layer
36* The homing right middle finger gives access to the Navigation layer
37* The homing left index finger gives access to the Right symbols layer
38* The homing right index finger gives access to the Left symbols layer
39* The homing right thumb gives access to the Always accessible layer
40
41### Layer 1: Mouse
42
43![Layer 1](https://i.imgur.com/0fvTuB9.png)
44
45Layer 1 is a mouse layer: it can be used one-handed or two-handed. The most common way to use it is two handed, with left and right click on the homerow of the left hand and directions on the homerow of the right hand.
46Scrolling is available on the right hand with mid finger up and down for vertical scroll and index and ring finger down for horizontal scroll.
47On the right hand, left click and right click are also available with index and ring finger up to allow one handed operation. This can be particularly handy when enabling the mouse layer permanently (no need to hold the left middle finger), which can be done from Layer 7.
48
49Note that thanks to the transparency, shift, ctrl and alt are all accessible on the left hand while operating the mouse.
50
51### Layer 2: Navigation
52
53![Layer 2](https://i.imgur.com/ZquQJRq.png)
54
55The navigation layer somewhat mirrors the mouse layer. It is accessed by holding the right middle finger and gives access to arrow keys on the left homerow. Page up and down, Home and End mirror the vertical scrolling and horizontal scrolling on the mouse layer.
56
57On the right hand, in addition to ctrl and alt which are available through transparency, ctrl + alt, ctrl + alt + shift and meta are accessible on the homerow to enable common shortcuts in some window managers. This part is quite workflow dependent, so make sure to adapt it to your own workflow as appropriate.
58
59### Layer 3: Right symbols
60
61![Layer 3](https://i.imgur.com/9tLAUqG.png)
62
63When holding down the left index, one may access about half of the symbols. The pinkies store `^` and `$` symbols that represent begin and end in vim. The left homerow hosts `*` and `&`, symbols which are related in the way that they represent some form of indirection in programming languages such as rust. On the right hand, most symbols used when navigating the command line are stored together, organized by columns of related symbols.
64
65### Layer 4: Left symbols
66
67![Layer 4](https://i.imgur.com/CkjUSW6.png)
68
69When holding down the right index, one may access the other symbols. On the left hand, most of the different brackets are laid out. The most frequent ones (round brackets and curly brackets) get a spot on the homerow. The rest of the layer hosts the remaining symbols that are easier to access here than on any other layers.
70
71### Layer 5: Function keys
72
73![Layer 5](https://i.imgur.com/fWgVqc4.png)
74
75By holding down the left ring finger, one may access the function keys, roughly in a numpad layout.
76This means that alt+F4 is easy to type, with F4 being on the homerow.
77There is a shortcut for ctrl+alt on the left hand to enable convenient switching between virtual terminals on Linux.
78
79### Layer 6: Numbers
80
81![Layer 6](https://i.imgur.com/S8gq9Kj.png)
82
83The number layer is accessed by holding the right ring finger. It hosts the numbers and some duplicated symbols that are commonly accessed next to numbers, such as mathematical operators.
84The number are layed out similarly to a numpad, but with the middle row and the homerow swapped so that the most used numbers: 0, 1, 2 and 3 are all available in homing positions.
85
86### Layer 7: Always accessible
87
88![Layer 7](https://i.imgur.com/twqBeBb.png)
89
90Layer 7 is accessed by holding the right homing thumb down. Because this position is left transparent from every other layer, this layer is always accessible.
91It gives access to some essential keys that would typically be accessed on a thumb cluster or pinkies, such as meta, enter, tab, esc and delete.
92
93As the layer hosting esc, we duplicated some symbols here to allow for fast navigation in vim. For instance, esc, :, w, q can be done in a single roll.
94
95Where is the keymap.c?
96----------------------
97
98The keymap.c file is not published to the repository. It is generated from `keymap.json` by the build system.
99
100This avoids duplicating information and allow users to edit their keymap from the qmk configurator web interface.
101
102How do I edit and update the keymap?
103------------------------------------
104
105The `keymap.json` file is generated from the qmk configurator interface and formatted for better readability in the context of the Ferris keyboard.
106
107To edit it, you may:
108* Edit it directly from a text editor.
109* Edit it from the qmk configurator.
110
111If you decide to use the latter workflow, here are the steps to follow:
112
113* From the qmk configurator, hit the "import QMK keymap json file" button (it has a drawing with an up arrow on it).
114* Browse to the location of your keymap (for example, `<your qmk repo>/keyboards/handwired/ferris/keymaps/default/keymap.json`)
115* Perform any modification to the keymap in the web UI
116* Export the keymap to your downloads folder, by hitting the "Export QMK keymap json file" button (it has a drawing with a down arrow on it)
117* Override your original keymap with the output of formatting the exported keymap by running a command such as this one from the root of your qmk repo:
118 ```
119 ./keyboards/handwired/ferris/keymaps/json2crab.py --input <Your download directory>/default.json > ./keyboards/handwired/ferris/keymaps/default/keymap.json
120 ```
121 Note that you may first need to make json2crab executable by using `chmod +x` on it.
122 Also note that you may then want to remove the exported keymap from your dowload directory.
diff --git a/keyboards/ferris/keymaps/json2crab.py b/keyboards/ferris/keymaps/json2crab.py
new file mode 100755
index 000000000..a32429fae
--- /dev/null
+++ b/keyboards/ferris/keymaps/json2crab.py
@@ -0,0 +1,76 @@
1#!/usr/bin/env python3
2
3import argparse
4import sys
5import json
6
7indent_level=4
8
9def parse_cli():
10 parser = argparse.ArgumentParser(description='Ferris keymap formatter')
11 parser.add_argument("--input", type=argparse.FileType('r'),
12 default=sys.stdin, help="Input keymap (json file produced by qmk configurator)")
13 return parser.parse_args()
14
15def col_index(key_index):
16 if key_index < 30:
17 col = key_index % 5
18 else:
19 col = key_index % 2
20 return col
21
22def format_layers(layers):
23 formatted = indent_level * " " + "\"layers\": [\n"
24 max_key_length = {}
25 for layer in layers:
26 for (index, keycode) in enumerate(layer):
27 col = col_index(index)
28 max_length = max_key_length.get(col)
29 if (not max_length) or len(keycode) > max_length:
30 max_key_length.update({col: len(keycode)})
31 for (layer_index, layer) in enumerate(layers):
32 formatted += 2 * indent_level * " "
33 formatted += "["
34 for (index, keycode) in enumerate(layer):
35 if index > 30 and index % 2 == 0 or index % 5 == 0 and index != 0:
36 formatted += (1 + 2 * indent_level) * " "
37 formatted += json.dumps(keycode)
38 if index == 33:
39 formatted += "\n"
40 elif index > 30 and index % 2 == 1 or index % 5 == 4:
41 formatted += ",\n"
42 else:
43 n_spaces = max_key_length[col_index(index)] - len(keycode)
44 formatted += n_spaces * " "
45 formatted += ", "
46 if index % 10 == 9:
47 formatted += "\n"
48 formatted += 2 * indent_level * " "
49 if layer_index < len(layers) - 1:
50 formatted += "],\n"
51 else:
52 formatted += "]\n"
53 formatted += indent_level * " "
54 formatted += "]"
55
56 return formatted
57
58def format_keymap(keymap_json):
59 formatted = "{"
60 for (index, k) in enumerate(keymap_json):
61 if k == "layers":
62 formatted += format_layers(keymap_json[k])
63 else:
64 formatted += f"{indent_level * ' '}{json.dumps(k)}: {json.dumps(keymap_json[k])}"
65 if index < len(keymap_json) - 1:
66 formatted += ","
67 formatted += "\n"
68 formatted += "}"
69 return formatted
70
71def main():
72 args=parse_cli()
73 keymap_json = json.loads(args.input.read())
74 print(format_keymap(keymap_json))
75
76main()
diff --git a/keyboards/ferris/keymaps/pierrec83/config.h b/keyboards/ferris/keymaps/pierrec83/config.h
new file mode 100644
index 000000000..cf0fb7478
--- /dev/null
+++ b/keyboards/ferris/keymaps/pierrec83/config.h
@@ -0,0 +1,39 @@
1/*
2Copyright 2020 Pierre Chevalier <pierrechevalier83@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19// Set the mouse settings to a comfortable speed/accuracy trade-off,
20// assuming a screen refresh rate of 60 Htz or higher
21// The default is 50. This makes the mouse ~3 times faster and more accurate
22#define MOUSEKEY_INTERVAL 16
23// The default is 20. Since we made the mouse about 3 times faster with the previous setting,
24// give it more time to accelerate to max speed to retain precise control over short distances.
25#define MOUSEKEY_TIME_TO_MAX 40
26// The default is 300. Let's try and make this as low as possible while keeping the cursor responsive
27#define MOUSEKEY_DELAY 100
28// It makes sense to use the same delay for the mouseweel
29#define MOUSEKEY_WHEEL_DELAY 100
30// The default is 100
31#define MOUSEKEY_WHEEL_INTERVAL 50
32// The default is 40
33#define MOUSEKEY_WHEEL_TIME_TO_MAX 100
34
35// Pick good defaults for enabling homerow modifiers
36#define TAPPING_TERM 200
37#define PERMISSIVE_HOLD
38#define IGNORE_MOD_TAP_INTERRUPT
39#define TAPPING_FORCE_HOLD
diff --git a/keyboards/ferris/keymaps/pierrec83/keymap.json b/keyboards/ferris/keymaps/pierrec83/keymap.json
new file mode 100644
index 000000000..2372e7e37
--- /dev/null
+++ b/keyboards/ferris/keymaps/pierrec83/keymap.json
@@ -0,0 +1,118 @@
1{ "version": 1,
2 "notes": "My awesome keymap",
3 "documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n",
4 "keyboard": "handwired/ferris",
5 "keymap": "pierrec83",
6 "layout": "LAYOUT",
7 "layers": [
8 ["KC_Q" , "KC_D" , "KC_R" , "KC_W" , "KC_B",
9 "KC_J" , "KC_F" , "KC_U" , "KC_P" , "KC_SCLN",
10
11 "LSFT_T(KC_A)" , "LT(6,KC_S)" , "LT(2,KC_H)" , "LT(4,KC_T)" , "KC_G",
12 "KC_Y" , "LT(5,KC_N)" , "LT(3,KC_E)" , "LT(7,KC_O)" , "LSFT_T(KC_I)",
13
14 "KC_Z" , "LCTL_T(KC_X)" , "LALT_T(KC_M)" , "KC_C" , "KC_V",
15 "KC_K" , "KC_L" , "LALT_T(KC_COMM)", "LCTL_T(KC_DOT)" , "KC_SLSH",
16
17 "LCA(KC_UP)" , "KC_BSPC",
18 "LT(8,KC_SPC)" , "LCA(KC_DOWN)"
19 ],
20 ["KC_Q" , "KC_C" , "KC_M" , "KC_Y" , "KC_COLN",
21 "KC_Z" , "KC_W" , "KC_COMM" , "KC_U" , "KC_J",
22
23 "LSFT_T(KC_R)" , "LT(6,KC_S)" , "LT(2,KC_T)" , "LT(4,KC_H)" , "KC_X",
24 "KC_TRNS" , "LT(5,KC_N)" , "LT(3,KC_A)" , "LT(7,KC_I)" , "LSFT_T(KC_O)",
25
26 "KC_B" , "LCTL_T(KC_F)" , "LALT_T(KC_G)" , "KC_D" , "KC_V",
27 "KC_ESC" , "KC_L" , "LALT_T(KC_DOT)" , "LCTL_T(KC_BSPC)" , "KC_K",
28
29 "LCA(KC_UP)" , "KC_E",
30 "LT(8,KC_SPC)" , "LCA(KC_DOWN)"
31 ],
32 ["KC_TRNS" , "ANY(LCTL(LSFT(KC_C)))", "KC_TRNS" , "ANY(LCTL(LSFT(KC_V)))", "KC_TRNS",
33 "KC_TRNS" , "KC_BTN1" , "KC_WH_U" , "KC_BTN2" , "KC_TRNS",
34
35 "KC_TRNS" , "KC_BTN2" , "KC_NO" , "KC_BTN1" , "KC_TRNS",
36 "KC_TRNS" , "KC_MS_L" , "KC_MS_D" , "KC_MS_U" , "KC_MS_R",
37
38 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
39 "KC_TRNS" , "KC_WH_L" , "KC_WH_D" , "KC_WH_R" , "KC_TRNS",
40
41 "ANY(LCTL(LSFT(KC_TAB)))", "KC_TRNS",
42 "KC_TRNS" , "LCTL(KC_TAB)"
43 ],
44 ["KC_TRNS" , "KC_TRNS" , "KC_PGUP" , "KC_TRNS" , "KC_TRNS",
45 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
46
47 "KC_LEFT" , "KC_UP" , "KC_DOWN" , "KC_RGHT" , "KC_TRNS",
48 "KC_TRNS" , "KC_LGUI" , "KC_NO" , "LCTL(KC_LALT)" , "LCA(KC_LSFT)",
49
50 "KC_TRNS" , "KC_HOME" , "KC_PGDN" , "KC_END" , "KC_TRNS",
51 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
52
53 "LGUI(KC_LEFT)" , "KC_TRNS",
54 "KC_TRNS" , "LGUI(KC_RGHT)"
55 ],
56 ["KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
57 "KC_TRNS" , "KC_UNDS" , "KC_PIPE" , "KC_QUOT" , "KC_TRNS",
58
59 "KC_CIRC" , "KC_ASTR" , "KC_AMPR" , "KC_NO" , "KC_TRNS",
60 "KC_HASH" , "KC_TILD" , "KC_SLSH" , "KC_DQUO" , "KC_DLR",
61
62 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
63 "KC_TRNS" , "KC_MINS" , "KC_BSLS" , "KC_GRV" , "KC_TRNS",
64
65 "KC_BRID" , "KC_TRNS",
66 "KC_TRNS" , "KC_BRIU"
67 ],
68 ["KC_TRNS" , "KC_COLN" , "KC_LT" , "KC_GT" , "KC_SCLN",
69 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
70
71 "KC_LCBR" , "KC_RCBR" , "KC_LPRN" , "KC_RPRN" , "KC_AT",
72 "KC_TRNS" , "KC_NO" , "KC_EQL" , "KC_PLUS" , "KC_PERC",
73
74 "KC_TRNS" , "KC_EXLM" , "KC_LBRC" , "KC_RBRC" , "KC_TRNS",
75 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
76
77 "KC_VOLD" , "KC_TRNS",
78 "KC_TRNS" , "KC_VOLU"
79 ],
80 ["KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
81 "KC_TRNS" , "KC_F7" , "KC_F8" , "KC_F9" , "KC_F10",
82
83 "KC_TRNS" , "KC_TRNS" , "LCTL(KC_LALT)" , "KC_TRNS" , "KC_TRNS",
84 "KC_TRNS" , "KC_F4" , "KC_F5" , "KC_F6" , "KC_F11",
85
86 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
87 "KC_TRNS" , "KC_F1" , "KC_F2" , "KC_F3" , "KC_F12",
88
89 "KC_TRNS" , "KC_TRNS",
90 "KC_TRNS" , "KC_TRNS"
91 ],
92 ["KC_PSLS" , "KC_7" , "KC_8" , "KC_9" , "KC_PPLS",
93 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
94
95 "KC_0" , "KC_1" , "KC_2" , "KC_3" , "KC_PMNS",
96 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_NO" , "KC_TRNS",
97
98 "KC_PAST" , "KC_4" , "KC_5" , "KC_6" , "KC_PEQL",
99 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
100
101 "KC_TRNS" , "KC_TRNS",
102 "KC_TRNS" , "KC_TRNS"
103 ],
104 ["KC_TRNS" , "KC_ESC" , "KC_COLN" , "KC_TRNS" , "KC_TRNS",
105 "DF(2)" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_DEL",
106
107 "KC_TRNS" , "KC_PERC" , "KC_SLSH" , "KC_ENT" , "KC_EXLM",
108 "DF(1)" , "KC_LGUI" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
109
110 "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS" , "KC_TRNS",
111 "DF(0)" , "KC_TRNS" , "RALT_T(KC_COMM)", "RCTL_T(KC_DOT)" , "RESET",
112
113 "KC_TRNS" , "KC_TAB",
114 "KC_NO" , "KC_TRNS"
115 ]
116 ],
117 "author": "@pierrec83"
118}
diff --git a/keyboards/ferris/keymaps/pierrec83/readme.md b/keyboards/ferris/keymaps/pierrec83/readme.md
new file mode 100644
index 000000000..d96a3bb81
--- /dev/null
+++ b/keyboards/ferris/keymaps/pierrec83/readme.md
@@ -0,0 +1,43 @@
1@pierrec83's personal keymap for the Ferris keyboard
2====================================================
3
4This keymap shares many commonalities with the default keymap.
5See its readme for a write-up on many of the decisions, including
6how to generate the formatted json file with json2crab.py and the
7general philosophy for each layer.
8
9Because this is my own keymap, I didn't refrain from using shortcuts
10that make sense for me and may not make sense for most.
11
12Key differences from the default keymap include:
13
14Alpha layers:
15-------------
16
17Because I only learned to touch type when I switched from qwerty to workman,
18my base layer is workman and my layout doesn't contain a qwerty layer.
19
20My layer 1 hosts a variant of RSTHD that I am developing, inspired from workman's
21focus on reducing side-index-motion. It should become my end game keymap eventually,
22but I still haven't found the time to learn it to a working proficiency.
23
24Secondary thumbs:
25-----------------
26
27Instead of a placeholder 0 and 1, the secondary thumbs on my keymap
28perform the following actions:
29* Navigate to previous and next workspace the base layer
30* Navigate to previous and next tab on the mouse layer
31* Volume control on layer
32* Brightness control on layer
33
34Mouse layer:
35------------
36
37* Copy/Paste shortcuts on the left hand, on the upper row.
38
39Always available layer:
40-----------------------
41
42* Esc and column are placed differently to allow easy vim navigation with the positions of w and q in the workman base layer
43* Enable permanent switch to the RSTHD layer in addition to the mouse layer
diff --git a/keyboards/ferris/readme.md b/keyboards/ferris/readme.md
new file mode 100644
index 000000000..74a08a38f
--- /dev/null
+++ b/keyboards/ferris/readme.md
@@ -0,0 +1,19 @@
1# Ferris
2
3![Ferris, top view](https://imgur.com/V4QuaGs.jpg)
4![Ferris, bottom view](https://i.imgur.com/7DJYME8.jpg)
5
6A split 34 keys column staggered keyboard named and decorated after the rustlang mascott. All PCB files and some thoughts on the design are available on the [project's github page](https://github.com/pierrechevalier83/ferris)
7
8* Keyboard Maintainer: [Pierre Chevalier](https://github.com/pierrechevalier83)
9* Hardware Supported:
10 * Ferris 0.1 (With atmega32u4 chip. Comes in 4 variants: base, low, high and compact)
11 * Ferris sweep (With pro-micro. Comes in a couple of PCB edge cuts shapes, but with identical pinout)
12* Hardware Availability: Pierre Chevalier has been selling keyboard kits (see the #ferris channel in the 40% discord chat). Wider availability is on the horizon.
13
14Make examples for this keyboard (after setting up your build environment):
15
16 make ferris/0_1:default
17 make ferris/sweep:default:avrdude-split-right
18
19See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/ferris/sweep/config.h b/keyboards/ferris/sweep/config.h
new file mode 100644
index 000000000..ad960610d
--- /dev/null
+++ b/keyboards/ferris/sweep/config.h
@@ -0,0 +1,74 @@
1/* Copyright 2018-2020 ENDO Katsuhiro <ka2hiro@curlybracket.co.jp> David Philip Barr <@davidphilipbarr> Pierre Chevalier <pierrechevalier83@gmail.com>
2
3This program is free software: you can redistribute it and/or modify
4it under the terms of the GNU General Public License as published by
5the Free Software Foundation, either version 2 of the License, or
6(at your option) any later version.
7
8This program is distributed in the hope that it will be useful,
9but WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License
14along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#pragma once
18
19#include "config_common.h"
20
21/* USB Device descriptor parameter */
22#define VENDOR_ID 0xC2AB
23#define PRODUCT_ID 0x3939
24#define DEVICE_VER 0x0001
25#define MANUFACTURER DPB
26#define PRODUCT Ferris sweep
27
28/* key matrix size */
29#define MATRIX_ROWS 8
30#define MATRIX_COLS 5
31
32/*
33 * Keyboard Matrix Assignments
34 *
35 * Change this to how you wired your keyboard
36 * COLS: AVR pins used for columns, left to right
37 * ROWS: AVR pins used for rows, top to bottom
38 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
39 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
40 * NO_DIODE = switches are directly connected to AVR pins
41 *
42*/
43#define DIRECT_PINS { \
44 { E6, F7, F6, F5, F4 }, \
45 { B1, B3, B2, B6, D3 }, \
46 { D1, D0, D4, C6, D7 }, \
47 { B4, B5, NO_PIN, NO_PIN, NO_PIN } \
48}
49
50#define DIRECT_PINS_RIGHT { \
51 { F4, F5, F6, F7, E6 }, \
52 { D3,B6,B2,B3,B1 }, \
53 { D7,C6,D4,D0,D1}, \
54 { B5, B4, NO_PIN, NO_PIN, NO_PIN } \
55}
56
57
58
59#define UNUSED_PINS
60
61/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
62#define DEBOUNCE 5
63
64/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
65#define LOCKING_SUPPORT_ENABLE
66/* Locking resynchronize hack */
67#define LOCKING_RESYNC_ENABLE
68
69/* Serial settings */
70#define USE_SERIAL
71/* serial.c configuration for split keyboard */
72#define SOFT_SERIAL_PIN D2
73
74#define EE_HANDS
diff --git a/keyboards/ferris/sweep/rules.mk b/keyboards/ferris/sweep/rules.mk
new file mode 100644
index 000000000..ce4d52156
--- /dev/null
+++ b/keyboards/ferris/sweep/rules.mk
@@ -0,0 +1,24 @@
1# MCU name
2MCU = atmega32u4
3
4# Bootloader selection
5BOOTLOADER = caterina
6
7# Build Options
8# change yes to no to disable
9#
10BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
11MOUSEKEY_ENABLE = yes # Mouse keys
12EXTRAKEY_ENABLE = yes # Audio control and System control
13CONSOLE_ENABLE = no # Console for debug
14COMMAND_ENABLE = no # Commands for debug and configuration
15# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
16SLEEP_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
18NKRO_ENABLE = no # USB Nkey Rollover
19BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
20RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
21UNICODE_ENABLE = yes # Unicode
22BLUETOOTH_ENABLE = no # Enable Bluetooth
23AUDIO_ENABLE = no # Audio output
24SPLIT_KEYBOARD = yes # Use shared split_common code
diff --git a/keyboards/ferris/sweep/sweep.c b/keyboards/ferris/sweep/sweep.c
new file mode 100644
index 000000000..5b41bad84
--- /dev/null
+++ b/keyboards/ferris/sweep/sweep.c
@@ -0,0 +1,16 @@
1/* Copyright 2018-2020 ENDO Katsuhiro <ka2hiro@curlybracket.co.jp> David Philip Barr <@davidphilipbarr> Pierre Chevalier <pierrechevalier83@gmail.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#include "sweep.h"
diff --git a/keyboards/ferris/sweep/sweep.h b/keyboards/ferris/sweep/sweep.h
new file mode 100644
index 000000000..e8d66ebc6
--- /dev/null
+++ b/keyboards/ferris/sweep/sweep.h
@@ -0,0 +1,47 @@
1/* Copyright 2018-2020 ENDO Katsuhiro <ka2hiro@curlybracket.co.jp> David Philip Barr <@davidphilipbarr> Pierre Chevalier <pierrechevalier83@gmail.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 "quantum.h"
18
19/* This a shortcut to help you visually see your layout.
20 *
21 * The first section contains all of the arguments representing the physical
22 * layout of the board and position of the keys.
23 *
24 * The second converts the arguments into a two-dimensional array which
25 * represents the switch matrix.
26 */
27
28// readability
29#define ___ KC_NO
30
31#define LAYOUT( \
32 L01, L02, L03, L04, L05, R01, R02, R03, R04, R05, \
33 L06, L07, L08, L09, L10, R06, R07, R08, R09, R10, \
34 L11, L12, L13, L14, L15, R11, R12, R13, R14, R15, \
35 L16, L17, R16, R17 \
36 ) \
37 { \
38 { L01, L02, L03, L04, L05 }, \
39 { L06, L07, L08, L09, L10 }, \
40 { L11, L12, L13, L14, L15 }, \
41 { L16, L17, ___, ___ , ___}, \
42 { R01, R02, R03, R04, R05 }, \
43 { R06, R07, R08, R09, R10 }, \
44 { R11, R12, R13, R14, R15 }, \
45 { R16, R17, ___, ___, ___ } \
46 }
47