aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/gergo/config.h73
-rw-r--r--keyboards/gergo/gergo.c66
-rw-r--r--keyboards/gergo/gergo.h58
-rw-r--r--keyboards/gergo/i2cmaster.h178
-rw-r--r--keyboards/gergo/info.json277
-rw-r--r--keyboards/gergo/keymaps/default/keymap.c151
-rw-r--r--keyboards/gergo/keymaps/default/readme.md10
-rw-r--r--keyboards/gergo/keymaps/default/rules.mk36
-rw-r--r--keyboards/gergo/matrix.c517
-rw-r--r--keyboards/gergo/readme.md26
-rw-r--r--keyboards/gergo/rules.mk20
11 files changed, 1412 insertions, 0 deletions
diff --git a/keyboards/gergo/config.h b/keyboards/gergo/config.h
new file mode 100644
index 000000000..a795f8dba
--- /dev/null
+++ b/keyboards/gergo/config.h
@@ -0,0 +1,73 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3Copyright 2013 Oleg Kostyuk <cub.uanic@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// Copy and worked on with love from the EZ team
20
21#pragma once
22#include "config_common.h"
23
24/* Defaults */
25#ifndef BALLSTEP
26#define BALLSTEP 20
27#endif
28
29#ifndef SCROLLSTEP
30#define SCROLLSTEP 1
31#endif
32
33#define VERBOSE
34
35/* USB Device descriptor parameter */
36#define VENDOR_ID 0xFEED
37#define PRODUCT_ID 0x1307
38#define DEVICE_VER 0x0001
39#define MANUFACTURER g Heavy Industries
40#define PRODUCT Gergo
41#define DESCRIPTION QMK keyboard firmware for Gergo
42
43/* key matrix size */
44#define MATRIX_ROWS 14
45#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
46#define MATRIX_COLS 4
47
48#define MOUSEKEY_INTERVAL 20
49#define MOUSEKEY_DELAY 0
50#define MOUSEKEY_TIME_TO_MAX 60
51#define MOUSEKEY_MAX_SPEED 7
52#define MOUSEKEY_WHEEL_DELAY 0
53#define TAPPING_TOGGLE 1
54
55/* define if matrix has ghost */
56//#define MATRIX_HAS_GHOST
57
58#define TAPPING_TERM 200
59#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.)
60
61/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
62#define LOCKING_SUPPORT_ENABLE
63/* Locking resynchronize hack */
64#define LOCKING_RESYNC_ENABLE
65
66/* key combination for command */
67#define IS_COMMAND() ( \
68 keyboard_report->mods == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)) || \
69 keyboard_report->mods == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) \
70)
71
72#define DEBOUNCE 5
73#define USB_MAX_POWER_CONSUMPTION 500
diff --git a/keyboards/gergo/gergo.c b/keyboards/gergo/gergo.c
new file mode 100644
index 000000000..c6ba91bb2
--- /dev/null
+++ b/keyboards/gergo/gergo.c
@@ -0,0 +1,66 @@
1#include QMK_KEYBOARD_H
2
3bool i2c_initialized = 0;
4i2c_status_t mcp23018_status = 0x20;
5
6void matrix_init_kb(void) {
7 // (tied to Vcc for hardware convenience)
8 //DDRB &= ~(1<<4); // set B(4) as input
9 //PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
10
11 // unused pins - C7, D4, D5, D7, E6
12 // set as input with internal pull-up enabled
13 DDRC &= ~(1<<7);
14 DDRD &= ~(1<<5 | 1<<4 | 1<<6 | 1<<7);
15 DDRE &= ~(1<<6);
16 PORTC |= (1<<7);
17 PORTD |= (1<<5 | 1<<4 | 1<<6 | 1<<7);
18 PORTE |= (1<<6);
19
20 matrix_init_user();
21}
22
23
24uint8_t init_mcp23018(void) {
25 print("starting init");
26 mcp23018_status = 0x20;
27
28 // I2C subsystem
29
30 // uint8_t sreg_prev;
31 // sreg_prev=SREG;
32 // cli();
33
34 if (i2c_initialized == 0) {
35 i2c_init(); // on pins D(1,0)
36 i2c_initialized = true;
37 _delay_ms(1000);
38 }
39 // i2c_init(); // on pins D(1,0)
40 // _delay_ms(1000);
41
42 // set pin direction
43 // - unused : input : 1
44 // - input : input : 1
45 // - driving : output : 0
46 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
47 mcp23018_status = i2c_write(IODIRA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
48 mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
49 mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
50 i2c_stop(ERGODOX_EZ_I2C_TIMEOUT);
51
52 // set pull-up
53 // - unused : on : 1
54 // - input : on : 1
55 // - driving : off : 0
56 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
57 mcp23018_status = i2c_write(GPPUA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
58 mcp23018_status = i2c_write(0b10000000, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
59 mcp23018_status = i2c_write(0b11111111, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
60
61out:
62 i2c_stop(ERGODOX_EZ_I2C_TIMEOUT);
63 // SREG=sreg_prev;
64 //uprintf("Init %x\n", mcp23018_status);
65 return mcp23018_status;
66}
diff --git a/keyboards/gergo/gergo.h b/keyboards/gergo/gergo.h
new file mode 100644
index 000000000..c0d885029
--- /dev/null
+++ b/keyboards/gergo/gergo.h
@@ -0,0 +1,58 @@
1#pragma once
2#include <util/delay.h>
3#include <stdint.h>
4#include <stdbool.h>
5#include "quantum.h"
6#include "i2c_master.h"
7#include "matrix.h"
8
9
10extern i2c_status_t mcp23018_status;
11#define ERGODOX_EZ_I2C_TIMEOUT 1000
12#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
13#define CPU_16MHz 0x00
14
15// I2C aliases and register addresses (see "mcp23018.md")
16//#define I2C_ADDR 0b0100000
17#define I2C_ADDR 0x20
18#define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE )
19#define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
20#define IODIRA 0x00 // i/o direction register
21#define IODIRB 0x01
22#define GPPUA 0x0C // GPIO pull-up resistor register
23#define GPPUB 0x0D
24#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
25#define GPIOB 0x13
26#define OLATA 0x14 // output latch register
27#define OLATB 0x15
28
29void init_ergodox(void);
30uint8_t init_mcp23018(void);
31
32/* ---------- LEFT HAND ----------- ---------- RIGHT HAND ---------- */
33#define LAYOUT_GERGO( \
34 L00,L01,L02,L03,L04,L05, R00,R01,R02,R03,R04,R05, \
35 L10,L11,L12,L13,L14,L15,L16, R10,R11,R12,R13,R14,R15,R16, \
36 L20,L21,L22,L23,L24,L25,L26, R20,R21,R22,R23,R24,R25,R26, \
37 L31,L32, R33,R34, \
38 L30, R30, \
39 L33,L34, R31,R32) \
40 \
41 /* matrix positions */ \
42 { \
43 { KC_NO, L16, L26, L30}, \
44 { L05, L15, L25, L34}, \
45 { L04, L14, L24, L33}, \
46 { L03, L13, L23, L32}, \
47 { L02, L12, L22, L31}, \
48 { L01, L11, L21, KC_NO}, \
49 { L00, L10, L20, KC_NO}, \
50 \
51 { R10, KC_NO, R20, R30}, \
52 { R00, R11, R21, R31}, \
53 { R01, R12, R22, R32}, \
54 { R02, R13, R23, R33}, \
55 { R03, R14, R24, R34}, \
56 { R04, R15, R25, KC_NO}, \
57 { R05, R16, R26, KC_NO}, \
58}
diff --git a/keyboards/gergo/i2cmaster.h b/keyboards/gergo/i2cmaster.h
new file mode 100644
index 000000000..72e050849
--- /dev/null
+++ b/keyboards/gergo/i2cmaster.h
@@ -0,0 +1,178 @@
1#ifndef _I2CMASTER_H
2#define _I2CMASTER_H 1
3/*************************************************************************
4* Title: C include file for the I2C master interface
5* (i2cmaster.S or twimaster.c)
6* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
7* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
8* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
9* Target: any AVR device
10* Usage: see Doxygen manual
11**************************************************************************/
12
13#ifdef DOXYGEN
14/**
15 @defgroup pfleury_ic2master I2C Master library
16 @code #include <i2cmaster.h> @endcode
17
18 @brief I2C (TWI) Master Software Library
19
20 Basic routines for communicating with I2C slave devices. This single master
21 implementation is limited to one bus master on the I2C bus.
22
23 This I2c library is implemented as a compact assembler software implementation of the I2C protocol
24 which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
25 Since the API for these two implementations is exactly the same, an application can be linked either against the
26 software I2C implementation or the hardware I2C implementation.
27
28 Use 4.7k pull-up resistor on the SDA and SCL pin.
29
30 Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module
31 i2cmaster.S to your target when using the software I2C implementation !
32
33 Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.
34
35 @note
36 The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted
37 to GNU assembler and AVR-GCC C call interface.
38 Replaced the incorrect quarter period delays found in AVR300 with
39 half period delays.
40
41 @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
42
43 @par API Usage Example
44 The following code shows typical usage of this library, see example test_i2cmaster.c
45
46 @code
47
48 #include <i2cmaster.h>
49
50
51 #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
52
53 int main(void)
54 {
55 unsigned char ret;
56
57 i2c_init(); // initialize I2C library
58
59 // write 0x75 to EEPROM address 5 (Byte Write)
60 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
61 i2c_write(0x05); // write address = 5
62 i2c_write(0x75); // write value 0x75 to EEPROM
63 i2c_stop(); // set stop conditon = release bus
64
65
66 // read previously written value back from EEPROM address 5
67 i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
68
69 i2c_write(0x05); // write address = 5
70 i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
71
72 ret = i2c_readNak(); // read one byte from EEPROM
73 i2c_stop();
74
75 for(;;);
76 }
77 @endcode
78
79*/
80#endif /* DOXYGEN */
81
82/**@{*/
83
84#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
85#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
86#endif
87
88#include <avr/io.h>
89
90/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
91#define I2C_READ 1
92
93/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
94#define I2C_WRITE 0
95
96
97/**
98 @brief initialize the I2C master interace. Need to be called only once
99 @param void
100 @return none
101 */
102void i2c_init(void);
103
104
105/**
106 @brief Terminates the data transfer and releases the I2C bus
107 @param void
108 @return none
109 */
110void i2c_stop(void);
111
112
113/**
114 @brief Issues a start condition and sends address and transfer direction
115
116 @param addr address and transfer direction of I2C device
117 @retval 0 device accessible
118 @retval 1 failed to access device
119 */
120unsigned char i2c_start(unsigned char addr);
121
122
123/**
124 @brief Issues a repeated start condition and sends address and transfer direction
125
126 @param addr address and transfer direction of I2C device
127 @retval 0 device accessible
128 @retval 1 failed to access device
129 */
130unsigned char i2c_rep_start(unsigned char addr);
131
132
133/**
134 @brief Issues a start condition and sends address and transfer direction
135
136 If device is busy, use ack polling to wait until device ready
137 @param addr address and transfer direction of I2C device
138 @return none
139 */
140void i2c_start_wait(unsigned char addr);
141
142
143/**
144 @brief Send one byte to I2C device
145 @param data byte to be transfered
146 @retval 0 write successful
147 @retval 1 write failed
148 */
149unsigned char i2c_write(unsigned char data);
150
151
152/**
153 @brief read one byte from the I2C device, request more data from device
154 @return byte read from I2C device
155 */
156unsigned char i2c_readAck(void);
157
158/**
159 @brief read one byte from the I2C device, read is followed by a stop condition
160 @return byte read from I2C device
161 */
162unsigned char i2c_readNak(void);
163
164/**
165 @brief read one byte from the I2C device
166
167 Implemented as a macro, which calls either i2c_readAck or i2c_readNak
168
169 @param ack 1 send ack, request more data from device<br>
170 0 send nak, read is followed by a stop condition
171 @return byte read from I2C device
172 */
173unsigned char i2c_read(unsigned char ack);
174#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
175
176
177/**@}*/
178#endif
diff --git a/keyboards/gergo/info.json b/keyboards/gergo/info.json
new file mode 100644
index 000000000..433582b54
--- /dev/null
+++ b/keyboards/gergo/info.json
@@ -0,0 +1,277 @@
1{
2 "maintainer": "germ",
3 "height": 4.75,
4 "width": 19.5,
5 "keyboard_name": "Gergo",
6 "url": "http://gboards.ca",
7 "layouts": {
8 "LAYOUT": {
9 "layout": [
10 {
11 "label": "L00",
12 "w": 1.5,
13 "x": 0,
14 "y": 0.38
15 },
16 {
17 "label": "L01",
18 "x": 1.5,
19 "y": 0.38
20 },
21 {
22 "label": "L02",
23 "x": 2.5,
24 "y": 0.13
25 },
26 {
27 "label": "L03",
28 "x": 3.5,
29 "y": 0
30 },
31 {
32 "label": "L04",
33 "x": 4.5,
34 "y": 0.13
35 },
36 {
37 "label": "L05",
38 "x": 5.5,
39 "y": 0.25
40 },
41 {
42 "label": "R00",
43 "x": 13,
44 "y": 0.25
45 },
46 {
47 "label": "R01",
48 "x": 14,
49 "y": 0.13
50 },
51 {
52 "label": "R02",
53 "x": 15,
54 "y": 0
55 },
56 {
57 "label": "R03",
58 "x": 16,
59 "y": 0.13
60 },
61 {
62 "label": "R04",
63 "x": 17,
64 "y": 0.38
65 },
66 {
67 "label": "R05",
68 "w": 1.5,
69 "x": 18,
70 "y": 0.38
71 },
72 {
73 "label": "L10",
74 "w": 1.5,
75 "x": 0,
76 "y": 1.3800000000000001
77 },
78 {
79 "label": "L11",
80 "x": 1.5,
81 "y": 1.3800000000000001
82 },
83 {
84 "label": "L12",
85 "x": 2.5,
86 "y": 1.1300000000000001
87 },
88 {
89 "label": "L13",
90 "x": 3.5,
91 "y": 1.0
92 },
93 {
94 "label": "L14",
95 "x": 4.5,
96 "y": 1.1300000000000001
97 },
98 {
99 "label": "L15",
100 "x": 5.5,
101 "y": 1.25
102 },
103 {
104 "h": 1.5,
105 "label": "L16",
106 "x": 6.5,
107 "y": 0.25
108 },
109 {
110 "h": 1.5,
111 "label": "R10",
112 "x": 12,
113 "y": 0.25
114 },
115 {
116 "label": "R11",
117 "x": 13,
118 "y": 1.25
119 },
120 {
121 "label": "R12",
122 "x": 14,
123 "y": 1.1300000000000001
124 },
125 {
126 "label": "R13",
127 "x": 15,
128 "y": 1.0
129 },
130 {
131 "label": "R14",
132 "x": 16,
133 "y": 1.1300000000000001
134 },
135 {
136 "label": "R15",
137 "x": 17,
138 "y": 1.3800000000000001
139 },
140 {
141 "label": "R16",
142 "w": 1.5,
143 "x": 18,
144 "y": 1.3800000000000001
145 },
146 {
147 "label": "L20",
148 "w": 1.5,
149 "x": 0,
150 "y": 2.38
151 },
152 {
153 "label": "L21",
154 "x": 1.5,
155 "y": 2.38
156 },
157 {
158 "label": "L22",
159 "x": 2.5,
160 "y": 2.13
161 },
162 {
163 "label": "L23",
164 "x": 3.5,
165 "y": 2
166 },
167 {
168 "label": "L24",
169 "x": 4.5,
170 "y": 2.13
171 },
172 {
173 "label": "L25",
174 "x": 5.5,
175 "y": 2.25
176 },
177 {
178 "h": 1.5,
179 "label": "L26",
180 "x": 6.5,
181 "y": 1.75
182 },
183 {
184 "h": 1.5,
185 "label": "R20",
186 "x": 12,
187 "y": 1.75
188 },
189 {
190 "label": "R21",
191 "x": 13,
192 "y": 2.25
193 },
194 {
195 "label": "R22",
196 "x": 14,
197 "y": 2.13
198 },
199 {
200 "label": "R23",
201 "x": 15,
202 "y": 2
203 },
204 {
205 "label": "R24",
206 "x": 16,
207 "y": 2.13
208 },
209 {
210 "label": "R25",
211 "x": 17,
212 "y": 2.38
213 },
214 {
215 "label": "R26",
216 "w": 1.5,
217 "x": 18,
218 "y": 2.38
219 },
220 {
221 "label": "L31",
222 "x": 4.75,
223 "y": 3.25
224 },
225 {
226 "label": "L32",
227 "x": 6,
228 "y": 3.63
229 },
230 {
231 "label": "R33",
232 "x": 12.5,
233 "y": 3.63
234 },
235 {
236 "label": "R34",
237 "x": 13.75,
238 "y": 3.25
239 },
240 {
241 "label": "L30",
242 "x": 8.25,
243 "y": 2.75
244 },
245 {
246 "label": "R30",
247 "x": 10.25,
248 "y": 2.75
249 },
250 {
251 "h": 2,
252 "label": "L33",
253 "x": 7.25,
254 "y": 3.75
255 },
256 {
257 "h": 2,
258 "label": "L34",
259 "x": 8.25,
260 "y": 3.75
261 },
262 {
263 "h": 2,
264 "label": "R31",
265 "x": 10.25,
266 "y": 3.75
267 },
268 {
269 "h": 2,
270 "label": "R32",
271 "x": 11.25,
272 "y": 3.75
273 }
274 ]
275 }
276 }
277}
diff --git a/keyboards/gergo/keymaps/default/keymap.c b/keyboards/gergo/keymaps/default/keymap.c
new file mode 100644
index 000000000..fabd945fe
--- /dev/null
+++ b/keyboards/gergo/keymaps/default/keymap.c
@@ -0,0 +1,151 @@
1/* Good on you for modifying your layout! if you don't have
2 * time to read the QMK docs, a list of keycodes can be found at
3 *
4 * https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md
5 *
6 * There's also a template for adding new layers at the bottom of this file!
7 */
8
9#include QMK_KEYBOARD_H
10
11#define IGNORE_MOD_TAP_INTERRUPT
12#define BASE 0 // default layer
13#define SYMB 1 // symbols
14#define NUMB 2 // numbers/motion
15
16// Blank template at the bottom
17
18enum customKeycodes {
19 URL = 1
20};
21
22
23const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
24/* Keymap 0: Basic layer
25 *
26 * ,-------------------------------------------. ,-------------------------------------------.
27 * | L1/ESC | Q | W | E | R | T | | Y | U | I | O | P | | \ |
28 * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
29 * |Ctrl/BS | A | S | D | F | G | RMB | | | H | J | K | L | ; : | ' " |
30 * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
31 * | LShift | Z | X | C | V | B | LMB | | | N | M | , < | . > | / ? | - _ |
32 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
33 * .----------. .-------. .------. .-----.
34 * | Super/Del| |Ent/ALT| | Tab | |BKSP |
35 * '----------' '-------' `------. '-----'
36 * ,-------. ,-------.
37 * | MMB | | PgDn |
38 * ,------|-------| |-------|------.
39 * | SYMB | NUMB | | SYMB | NUMB |
40 * | Space| Escape| | Mod |Space |
41 * | | | | | |
42 * `--------------' `--------------'
43 */
44[BASE] = LAYOUT_GERGO(
45LT(NUMB, KC_ESC), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_PIPE,
46MT(MOD_LCTL, KC_BSPC), KC_A, KC_S, KC_D, KC_F, KC_G, KC_BTN2, KC_TRNS, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
47KC_RSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_BTN1, KC_BSPC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_MINS,
48
49 MT(MOD_LGUI, KC_DEL), MT(MOD_LALT, KC_ENT), KC_TAB, KC_BSPC,
50
51 KC_BTN3, KC_PGDN,
52 LT(SYMB, KC_SPC), LT(NUMB, KC_ESC), LT(SYMB, KC_ENT), LT(NUMB, KC_SPC)),
53/* Keymap 1: Symbols layer
54 *
55 * ,-------------------------------------------. ,-------------------------------------------.
56 * | | ! | @ | { | } | | | | | | | | | \ | |
57 * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
58 * | | # | $ | ( | ) | ` | | | | + | - | / | * | % | ' " |
59 * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
60 * | | % | ^ | [ | ] | ~ | | | | & | = | , | . | / ? | - _ |
61 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
62 * .------. .------. .------. .-----.
63 * | | | | | | | DEL |
64 * '------' '------' `------. '-----'
65 * ,-------. ,-------.
66 * | | | PgUp |
67 * ,------|-------| |-------|------.
68 * | | | | | |
69 * | ; | = | | = | ; |
70 * | | | | | |
71 * `--------------' `--------------'
72 */
73[SYMB] = LAYOUT_GERGO(
74KC_TRNS, KC_EXLM, KC_AT, KC_LCBR,KC_RCBR, KC_PIPE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSLS,
75KC_TRNS, KC_HASH, KC_DLR, KC_LPRN,KC_RPRN, KC_GRV, KC_TRNS, KC_TRNS, KC_PLUS, KC_MINS, KC_SLSH, KC_ASTR, KC_PERC, KC_QUOT,
76KC_TRNS, KC_PERC, KC_CIRC,KC_LBRC,KC_RBRC, KC_TILD, KC_TRNS, KC_TRNS, KC_AMPR, KC_EQL, KC_COMM, KC_DOT, KC_SLSH, KC_MINS,
77
78 KC_TRNS, KC_TRNS, KC_PGUP, KC_DEL,
79 KC_TRNS, KC_TRNS,
80 KC_SCLN, KC_EQL, KC_EQL, KC_SCLN),
81/* Keymap 2: Pad/Function layer
82 *
83 * ,-------------------------------------------. ,-------------------------------------------.
84 * | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
85 * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
86 * | F1 | F2 | F3 | F4 | F5 | F6 | BTN1 | | | LEFT | DOWN | UP | RIGHT|VolDn | VolUp |
87 * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
88 * | F7 | F8 | F9 | F10 | F11 | F12 | BTN2 | | | MLFT | MDWN | MUP | MRGHT|Ply/Pa| Skip |
89 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
90 * .------. .------. .------. .-----.
91 * | | | | | | | |
92 * '------' '------' `------. '-----'
93 * ,-------. ,-------.
94 * | | | PgUp |
95 * ,------|-------| |-------|------.
96 * | | | | | |
97 * | | | | | |
98 * | | | | | |
99 * `--------------' `--------------'
100 */
101[NUMB] = LAYOUT_GERGO(
102KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
103KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_VOLD, KC_VOLU,
104KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_MPLY, KC_MNXT,
105
106 KC_TRNS, KC_TRNS, KC_PGUP, KC_TRNS,
107 KC_TRNS, KC_TRNS,
108 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
109};
110
111/* Keymap template
112 *
113 * ,-------------------------------------------. ,-------------------------------------------.
114 * | | | | | | | | | | | | | |
115 * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
116 * | | | | | | | | | | | | | | | |
117 * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
118 * | | | | | | | | | | | | | | | |
119 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
120 * .------. .------. .------. .-----.
121 * | | | | | | | |
122 * '------' '------' `------. '-----'
123 * ,-------. ,-------.
124 * | | | |
125 * ,------|-------| |-------|------.
126 * | | | | | |
127 * | | | | | |
128 * | | | | | |
129 * `--------------' `--------------'
130[SYMB] = LAYOUT_GERGO(
131KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
132KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
133KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
134
135 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
136 KC_TRNS, KC_TRNS,
137 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
138 */
139
140// Runs just one time when the keyboard initializes.
141void matrix_init_user(void) {
142
143};
144
145// Runs constantly in the background, in a loop.
146void matrix_scan_user(void) {
147 //uint8_t layer = biton32(layer_state);
148 biton32(layer_state);
149};
150
151
diff --git a/keyboards/gergo/keymaps/default/readme.md b/keyboards/gergo/keymaps/default/readme.md
new file mode 100644
index 000000000..471a20fbd
--- /dev/null
+++ b/keyboards/gergo/keymaps/default/readme.md
@@ -0,0 +1,10 @@
1# [Gergo! By g Heavy Industries](http://gboards.ca)
2
3![Gergo image](https://4.bp.blogspot.com/-889nMXxgSM0/XCNxwnO5kUI/AAAAAAAA6mI/tZbWgZVCBW0dyZOCGJDkjN06DVax7j8XwCLcBGAs/s1600/48422820_967732713413298_485744639215665152_n.jpg)
4
5This is the default keymap for Gergo, it's based heavily off of the naps62 ErgoDox layout and is aimed at a programmer friendly keymap.
6
7## Settings
8To edit various settings, enable the 1u trackball and whatnot please modify /keyboards/gergo/keymaps/default/rules.mk
9
10Ideally you should copy this directory and make your changes there. If you come up with a good layout submit a PR!
diff --git a/keyboards/gergo/keymaps/default/rules.mk b/keyboards/gergo/keymaps/default/rules.mk
new file mode 100644
index 000000000..2f825a766
--- /dev/null
+++ b/keyboards/gergo/keymaps/default/rules.mk
@@ -0,0 +1,36 @@
1#----------------------------------------------------------------------------
2# make gergo:germ:dfu
3# Make sure you have dfu-programmer installed!
4#----------------------------------------------------------------------------
5# Firmware options
6BALLER = yes # Enable to ball out
7BALLSTEP = 20 # Multiple in px to move, multiplied by layer number
8SCROLLSTEP = 1 # Lines to scroll with ball
9MOUSEKEY_ENABLE = yes # Mouse keys(+4700), needed for baller
10
11#Debug options
12VERBOSE = yes
13DEBUG_MATRIX_SCAN_RATE = no
14DEBUG_BALLER = no
15DEBUG_MATRIX = no
16
17# A bunch of stuff that you shouldn't touch unless you
18# know what you're doing.
19#
20# No touchy, capiche?
21SRC += matrix.c i2c_master.c
22ifneq ($(strip $(BALLSTEP)),)
23 OPT_DEFS += -DTRKSTEP=$(strip $(BALLSTEP))
24endif
25ifneq ($(strip $(SCROLLSTEP)),)
26 OPT_DEFS += -DSCROLLSTEP=$(strip $(SCROLLSTEP))
27endif
28ifeq ($(strip $(BALLER)), yes)
29 OPT_DEFS += -DBALLER
30endif
31ifeq ($(strip $(DEBUG_BALLER)), yes)
32 OPT_DEFS += -DDEBUG_BALLER
33endif
34ifeq ($(strip $(DEBUG_MATRIX)), yes)
35 OPT_DEFS += -DDEBUG_MATRIX
36endif
diff --git a/keyboards/gergo/matrix.c b/keyboards/gergo/matrix.c
new file mode 100644
index 000000000..29fe48ccb
--- /dev/null
+++ b/keyboards/gergo/matrix.c
@@ -0,0 +1,517 @@
1/*
2Note for ErgoDox EZ customizers: Here be dragons!
3This is not a file you want to be messing with.
4All of the interesting stuff for you is under keymaps/ :)
5Love, Erez
6
7Copyright 2013 Oleg Kostyuk <cub.uanic@gmail.com>
8
9This program is free software: you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation, either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "matrix.h"
24#include <stdint.h>
25#include <stdbool.h>
26#include <avr/io.h>
27#include "wait.h"
28#include "action_layer.h"
29#include "print.h"
30#include "debug.h"
31#include "util.h"
32#include "pointing_device.h"
33#include QMK_KEYBOARD_H
34#ifdef DEBUG_MATRIX_SCAN_RATE
35#include "timer.h"
36#endif
37
38#ifdef BALLER
39#include <avr/interrupt.h>
40#endif
41
42#ifndef DEBOUNCE
43# define DEBOUNCE 5
44#endif
45
46// MCP Pin Defs
47#define RROW1 (1<<3)
48#define RROW2 (1<<2)
49#define RROW3 (1<<1)
50#define RROW4 (1<<0)
51#define COL0 (1<<0)
52#define COL1 (1<<1)
53#define COL2 (1<<2)
54#define COL3 (1<<3)
55#define COL4 (1<<4)
56#define COL5 (1<<5)
57#define COL6 (1<<6)
58
59// ATmega pin defs
60#define ROW1 (1<<6)
61#define ROW2 (1<<5)
62#define ROW3 (1<<4)
63#define ROW4 (1<<1)
64#define COL7 (1<<0)
65#define COL8 (1<<1)
66#define COL9 (1<<2)
67#define COL10 (1<<3)
68#define COL11 (1<<2)
69#define COL12 (1<<3)
70#define COL13 (1<<6)
71
72//Trackball pin defs
73#define TRKUP (1<<4)
74#define TRKDN (1<<5)
75#define TRKLT (1<<6)
76#define TRKRT (1<<7)
77#define TRKBTN (1<<6)
78
79
80// Multiple for mouse moves
81#ifndef TRKSTEP
82#define TRKSTEP 20
83#endif
84
85// multiple for mouse scroll
86#ifndef SCROLLSTEP
87#define SCROLLSTEP 5
88#endif
89
90// bit masks
91#define BMASK (COL7 | COL8 | COL9 | COL10)
92#define CMASK (COL13)
93#define DMASK (COL11 | COL12)
94#define FMASK (ROW1 | ROW2 | ROW3 | ROW4)
95#define RROWMASK (RROW1 | RROW2 | RROW3 | RROW4)
96#define MCPMASK (COL0 | COL1 | COL2 | COL3 | COL4 | COL5 | COL6)
97#define TRKMASK (TRKUP | TRKDN | TRKRT | TRKLT)
98
99// Trackball interrupts accumulate over here. Processed on scan
100// Stores prev state of mouse, high bits store direction
101uint8_t trkState = 0;
102uint8_t trkBtnState = 0;
103
104volatile uint8_t tbUpCnt = 0;
105volatile uint8_t tbDnCnt = 0;
106volatile uint8_t tbLtCnt = 0;
107volatile uint8_t tbRtCnt = 0;
108
109/* matrix state(1:on, 0:off) */
110static matrix_row_t matrix[MATRIX_ROWS];
111/*
112 * matrix state(1:on, 0:off)
113 * contains the raw values without debounce filtering of the last read cycle.
114 */
115static matrix_row_t raw_matrix[MATRIX_ROWS];
116
117// Debouncing: store for each key the number of scans until it's eligible to
118// change. When scanning the matrix, ignore any changes in keys that have
119// already changed in the last DEBOUNCE scans.
120static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
121
122static matrix_row_t read_cols(uint8_t row);
123static void init_cols(void);
124static void unselect_rows(void);
125static void select_row(uint8_t row);
126static void enableInterrupts(void);
127
128static uint8_t mcp23018_reset_loop;
129// static uint16_t mcp23018_reset_loop;
130
131#ifdef DEBUG_MATRIX_SCAN_RATE
132uint32_t matrix_timer;
133uint32_t matrix_scan_count;
134#endif
135
136
137__attribute__ ((weak))
138void matrix_init_user(void) {}
139
140__attribute__ ((weak))
141void matrix_scan_user(void) {}
142
143__attribute__ ((weak))
144void matrix_init_kb(void) {
145 matrix_init_user();
146}
147
148__attribute__ ((weak))
149void matrix_scan_kb(void) {
150 matrix_scan_user();
151}
152
153inline
154uint8_t matrix_rows(void)
155{
156 return MATRIX_ROWS;
157}
158
159inline
160uint8_t matrix_cols(void)
161{
162 return MATRIX_COLS;
163}
164
165
166void matrix_init(void)
167{
168 // initialize row and col
169 mcp23018_status = init_mcp23018();
170 unselect_rows();
171 init_cols();
172
173 // initialize matrix state: all keys off
174 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
175 matrix[i] = 0;
176 raw_matrix[i] = 0;
177 for (uint8_t j=0; j < MATRIX_COLS; ++j) {
178 debounce_matrix[i * MATRIX_COLS + j] = 0;
179 }
180 }
181
182#ifdef DEBUG_MATRIX_SCAN_RATE
183 matrix_timer = timer_read32();
184 matrix_scan_count = 0;
185#endif
186 matrix_init_quantum();
187}
188
189void matrix_power_up(void) {
190 mcp23018_status = init_mcp23018();
191
192 unselect_rows();
193 init_cols();
194
195 // initialize matrix state: all keys off
196 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
197 matrix[i] = 0;
198 }
199
200#ifdef DEBUG_MATRIX_SCAN_RATE
201 matrix_timer = timer_read32();
202 matrix_scan_count = 0;
203#endif
204
205}
206
207// Returns a matrix_row_t whose bits are set if the corresponding key should be
208// eligible to change in this scan.
209matrix_row_t debounce_mask(matrix_row_t rawcols, uint8_t row) {
210 matrix_row_t result = 0;
211 matrix_row_t change = rawcols ^ raw_matrix[row];
212 raw_matrix[row] = rawcols;
213 for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
214 if (debounce_matrix[row * MATRIX_COLS + i]) {
215 --debounce_matrix[row * MATRIX_COLS + i];
216 } else {
217 result |= (1 << i);
218 }
219 if (change & (1 << i)) {
220 debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
221 }
222 }
223 return result;
224}
225
226matrix_row_t debounce_read_cols(uint8_t row) {
227 // Read the row without debouncing filtering and store it for later usage.
228 matrix_row_t cols = read_cols(row);
229 // Get the Debounce mask.
230 matrix_row_t mask = debounce_mask(cols, row);
231 // debounce the row and return the result.
232 return (cols & mask) | (matrix[row] & ~mask);;
233}
234
235uint8_t matrix_scan(void)
236{
237 // TODO: Find what is trashing interrupts
238 enableInterrupts();
239
240 // First we handle the mouse inputs
241 #ifdef BALLER
242 uint8_t pBtn = PINE & TRKBTN;
243
244 #ifdef DEBUG_BALLER
245 // Compare to previous, mod report
246 if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0)
247 xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6));
248 #endif
249
250 // Modify the report
251 report_mouse_t pRprt = pointing_device_get_report();
252
253 // Scroll by default, move on layer
254 if (layer_state == 0) {
255 pRprt.h += tbLtCnt * SCROLLSTEP; tbLtCnt = 0;
256 pRprt.h -= tbRtCnt * SCROLLSTEP; tbRtCnt = 0;
257 pRprt.v -= tbUpCnt * SCROLLSTEP; tbUpCnt = 0;
258 pRprt.v += tbDnCnt * SCROLLSTEP; tbDnCnt = 0;
259 } else {
260 pRprt.x -= tbLtCnt * TRKSTEP * (layer_state - 1); tbLtCnt = 0;
261 pRprt.x += tbRtCnt * TRKSTEP * (layer_state - 1); tbRtCnt = 0;
262 pRprt.y -= tbUpCnt * TRKSTEP * (layer_state - 1); tbUpCnt = 0;
263 pRprt.y += tbDnCnt * TRKSTEP * (layer_state - 1); tbDnCnt = 0;
264 }
265
266 #ifdef DEBUG_BALLER
267 if (pRprt.x != 0 || pRprt.y != 0)
268 xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y);
269 #endif
270
271 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 0)) pRprt.buttons |= MOUSE_BTN1;
272 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1;
273
274 // Save state, push update
275 if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn))
276 pointing_device_set_report(pRprt);
277
278 trkBtnState = pBtn;
279 #endif
280
281 // Then the keyboard
282 if (mcp23018_status) { // if there was an error
283 if (++mcp23018_reset_loop == 0) {
284 // if (++mcp23018_reset_loop >= 1300) {
285 // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
286 // this will be approx bit more frequent than once per second
287 print("trying to reset mcp23018\n");
288 mcp23018_status = init_mcp23018();
289 if (mcp23018_status) {
290 print("left side not responding\n");
291 } else {
292 print("left side attached\n");
293 }
294 }
295 }
296
297#ifdef DEBUG_MATRIX_SCAN_RATE
298 matrix_scan_count++;
299 uint32_t timer_now = timer_read32();
300 if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) {
301 print("matrix scan frequency: ");
302 pdec(matrix_scan_count);
303 print("\n");
304
305 matrix_timer = timer_now;
306 matrix_scan_count = 0;
307 }
308#endif
309 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) {
310 select_row(i);
311 // and select on left hand
312 select_row(i + MATRIX_ROWS_PER_SIDE);
313 // we don't need a 30us delay anymore, because selecting a
314 // left-hand row requires more than 30us for i2c.
315
316 // grab cols from left hand
317 matrix[i] = debounce_read_cols(i);
318 // grab cols from right hand
319 matrix[i + MATRIX_ROWS_PER_SIDE] = debounce_read_cols(i + MATRIX_ROWS_PER_SIDE);
320
321 unselect_rows();
322 }
323
324 matrix_scan_quantum();
325 enableInterrupts();
326
327#ifdef DEBUG_MATRIX
328 for (uint8_t c = 0; c < MATRIX_COLS; c++)
329 for (uint8_t r = 0; r < MATRIX_ROWS; r++)
330 if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c);
331#endif
332
333 return 1;
334}
335
336bool matrix_is_modified(void) // deprecated and evidently not called.
337{
338 return true;
339}
340
341inline
342bool matrix_is_on(uint8_t row, uint8_t col)
343{
344 return (matrix[row] & ((matrix_row_t)1<<col));
345}
346
347inline
348matrix_row_t matrix_get_row(uint8_t row)
349{
350 return matrix[row];
351}
352
353void matrix_print(void)
354{
355 print("\nr/c 0123456789ABCDEF\n");
356 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
357 phex(row); print(": ");
358 pbin_reverse16(matrix_get_row(row));
359 print("\n");
360 }
361}
362
363uint8_t matrix_key_count(void)
364{
365 uint8_t count = 0;
366 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
367 count += bitpop16(matrix[i]);
368 }
369 return count;
370}
371
372// Remember this means ROWS
373static void init_cols(void)
374{
375 // init on mcp23018
376 // not needed, already done as part of init_mcp23018()
377
378 // Input with pull-up(DDR:0, PORT:1)
379 DDRF &= ~FMASK;
380 PORTF |= FMASK;
381}
382
383static matrix_row_t read_cols(uint8_t row)
384{
385 if (row < 7) {
386 if (mcp23018_status) { // if there was an error
387 return 0;
388 } else {
389 uint8_t data = 0;
390 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
391 mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
392 mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
393 mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out;
394 data = ~((uint8_t)mcp23018_status);
395 mcp23018_status = I2C_STATUS_SUCCESS;
396 out:
397 i2c_stop(ERGODOX_EZ_I2C_TIMEOUT);
398
399#ifdef DEBUG_MATRIX
400 if (data != 0x00) xprintf("I2C: %d\n", data);
401#endif
402 return data;
403 }
404 } else {
405 /* read from teensy
406 * bitmask is 0b0111001, but we want the lower four
407 * we'll return 1s for the top two, but that's harmless.
408 */
409 // So I need to confuckulate all this
410 //return ~(((PIND & DMASK) >> 1 | ((PINC & CMASK) >> 6) | (PIN)));
411 //return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2));
412 return ~(
413 (((PINF & ROW4) >> 1)
414 | ((PINF & (ROW1 | ROW2 | ROW3)) >> 3))
415 & 0xF);
416 }
417}
418
419// Row pin configuration
420static void unselect_rows(void)
421{
422 // no need to unselect on mcp23018, because the select step sets all
423 // the other row bits high, and it's not changing to a different
424 // direction
425 // Hi-Z(DDR:0, PORT:0) to unselect
426 DDRB &= ~(BMASK | TRKMASK);
427 PORTB &= ~(BMASK);
428 DDRC &= ~CMASK;
429 PORTC &= ~CMASK;
430 DDRD &= ~DMASK;
431 PORTD &= ~DMASK;
432
433 // Fix trashing of DDRB for TB
434 PORTB |= TRKMASK;
435}
436
437static void select_row(uint8_t row)
438{
439 if (row < 7) {
440 // select on mcp23018
441 if (mcp23018_status) { // do nothing on error
442 } else { // set active row low : 0 // set other rows hi-Z : 1
443 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
444 mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
445 mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out;
446 out:
447 i2c_stop(ERGODOX_EZ_I2C_TIMEOUT);
448 }
449 } else {
450 // Output low(DDR:1, PORT:0) to select
451 switch (row) {
452 case 7:
453 DDRB |= COL7;
454 PORTB &= ~COL7;
455 break;
456 case 8:
457 DDRB |= COL8;
458 PORTB &= ~COL8;
459 break;
460 case 9:
461 DDRB |= COL9;
462 PORTB &= ~COL9;
463 break;
464 case 10:
465 DDRB |= COL10;
466 PORTB &= ~COL10;
467 break;
468 case 11:
469 DDRD |= COL11;
470 PORTD &= ~COL11;
471 break;
472 case 12:
473 DDRD |= COL12;
474 PORTD &= ~COL12;
475 break;
476 case 13:
477 DDRC |= COL13;
478 PORTC &= ~COL13;
479 break;
480 }
481 }
482}
483
484
485// Trackball Interrupts
486static void enableInterrupts(void) {
487 #ifdef BALLER
488 // Set interrupt mask
489 // Set port defs
490 DDRB &= ~TRKMASK;
491 PORTB |= TRKMASK;
492 DDRE &= ~TRKBTN;
493 PORTE |= TRKBTN;
494
495 // Interrupt shenanigans
496 //EIMSK |= (1 << PCIE0);
497 PCMSK0 |= TRKMASK;
498 PCICR |= (1 << PCIE0);
499 sei();
500 #endif
501
502 return;
503}
504#ifdef BALLER
505ISR (PCINT0_vect) {
506 // Don't get fancy, we're in a interrupt here
507 // PCINT reports a interrupt for a change on the bus
508 // We hand the button at scantime for debounce
509 volatile uint8_t pState = PINB & TRKMASK;
510 if ((pState & TRKUP) != (trkState & TRKUP)) tbUpCnt++;
511 if ((pState & TRKDN) != (trkState & TRKDN)) tbDnCnt++;
512 if ((pState & TRKLT) != (trkState & TRKLT)) tbLtCnt++;
513 if ((pState & TRKRT) != (trkState & TRKRT)) tbRtCnt++;
514 trkState = pState;
515
516}
517#endif
diff --git a/keyboards/gergo/readme.md b/keyboards/gergo/readme.md
new file mode 100644
index 000000000..8fefcfe8d
--- /dev/null
+++ b/keyboards/gergo/readme.md
@@ -0,0 +1,26 @@
1# Gergo
2
3![Gergo](https://cdn.pbrd.co/images/HVglSWD.jpg)
4
5A compact 50% (14x4) Split Keyboard compatible with i2c modules and a trackball.
6
7[More info on qmk.fm](http://qmk.fm/gergo/)
8
9Keyboard Maintainer: [Jeremy Bernhardt](https://github.com/germ)
10Hardware Supported: Gergo (Kit, Partial, Ready)
11Hardware Availability: [gboards.ca](http://gboards.ca)
12
13## Firmware building
14After cloning the QMK repo and installing dfu-programmer build and flash with. Be sure to reset your keyboard!
15
16 make gergo:germ:dfu
17
18To just test your build with the default keymap
19
20 make gergo:germ
21
22Gadgets and options can be enabled/disabled in keyboards/gergo/keymaps/default/rules.mk . Copy the default directory and make any changes to your layout, if you think they're worth sharing submit a PR!
23
24See 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).
25
26## Have an idea for a gadget? [Reach out to me!](mailto:bernhardtjeremy@gmail.com)
diff --git a/keyboards/gergo/rules.mk b/keyboards/gergo/rules.mk
new file mode 100644
index 000000000..aadc1c2ce
--- /dev/null
+++ b/keyboards/gergo/rules.mk
@@ -0,0 +1,20 @@
1#----------------------------------------------------------------------------
2# make gergo:germ:dfu
3# Make sure you have dfu-programmer installed!
4# Do not edit this file! Make a copy of keymaps/default and modify that!
5#----------------------------------------------------------------------------
6# Source includes
7SRC += matrix.c i2c_master.c
8
9# Hardware info
10MCU = atmega32u4
11F_CPU = 16000000
12ARCH = AVR8
13BOOTLOADER = atmel-dfu
14F_USB = $(F_CPU)
15
16CUSTOM_MATRIX = yes
17POINTING_DEVICE_ENABLE = yes
18EXTRAKEY_ENABLE = yes
19CONSOLE_ENABLE = yes
20COMMAND_ENABLE = yes