diff --git a/keyboards/gboards/gergoplex/config.h b/keyboards/gboards/gergoplex/config.h new file mode 100644 index 000000000000..bbb862d6ea39 --- /dev/null +++ b/keyboards/gboards/gergoplex/config.h @@ -0,0 +1,55 @@ +/* +Copyright 2012 Jun Wako +Copyright 2013 Oleg Kostyuk + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +// Copy and worked on with love from the EZ team + +#pragma once +#include "config_common.h" + +#define BOOTMAGIC_LITE_ROW 9 +#define BOOTMAGIC_LITE_COLUMN 2 + +#define VERBOSE + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x0007 +#define PRODUCT_ID 0x0002 +#define DEVICE_VER 0x0001 +#define MANUFACTURER g Heavy Industries +#define PRODUCT GergoPlex +#define DESCRIPTION More ErgoGergo + +/* key matrix size */ +#define MATRIX_ROWS 10 +#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2) +#define MATRIX_COLS 4 + +#define MOUSEKEY_INTERVAL 20 +#define MOUSEKEY_DELAY 0 +#define MOUSEKEY_TIME_TO_MAX 60 +#define MOUSEKEY_MAX_SPEED 7 +#define MOUSEKEY_WHEEL_DELAY 0 +#define TAPPING_TOGGLE 1 +#define TAPPING_TERM 200 +#define IGNORE_MOD_TAP_INTERRUPT +#define LOCKING_SUPPORT_ENABLE +#define LOCKING_RESYNC_ENABLE +#define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)) || get_mods() == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT))) + +#define DEBOUNCE 5 +#define COMBO_TERM 40 diff --git a/keyboards/gboards/gergoplex/gergoplex.c b/keyboards/gboards/gergoplex/gergoplex.c new file mode 100644 index 000000000000..c9f547129bd5 --- /dev/null +++ b/keyboards/gboards/gergoplex/gergoplex.c @@ -0,0 +1,80 @@ +#include QMK_KEYBOARD_H + +bool i2c_initialized = 0; +i2c_status_t mcp23018_status = 0x20; + +void matrix_init_kb(void) { + // (tied to Vcc for hardware convenience) + // DDRB &= ~(1<<4); // set B(4) as input + // PORTB &= ~(1<<4); // set B(4) internal pull-up disabled + + // unused pins - C7, D4, D5, D7, E6 + // set as input with internal pull-up enabled + DDRB &= ~(1 << 0 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7); + PORTB |= (1 << 0 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7); + + DDRC &= ~(1 << 6); + PORTC |= (1 << 6); + + PORTD |= (1 << 5 | 1 << 4 | 1 << 6 | 1 << 7); + DDRD &= ~(1 << 5 | 1 << 4 | 1 << 6 | 1 << 7); + + DDRE &= ~(1 << 6); + PORTE |= (1 << 6); + + DDRF &= ~(1 << 0 | 1 << 7); + PORTF |= (1 << 0 | 1 << 7); + + matrix_init_user(); +} +uint8_t init_mcp23018(void) { + print("starting init"); + mcp23018_status = 0x20; + + // I2C subsystem + + // uint8_t sreg_prev; + // sreg_prev=SREG; + // cli(); + + if (i2c_initialized == 0) { + i2c_init(); // on pins D(1,0) + i2c_initialized = true; + _delay_ms(1000); + } + // i2c_init(); // on pins D(1,0) + // _delay_ms(1000); + + // set pin direction + // - unused : input : 1 + // - input : input : 1 + // - driving : output : 0 + mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(IODIRA, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0b11000001, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); + if (mcp23018_status) goto out; + i2c_stop(); + + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPPUA, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0b11000001, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0b11111111, I2C_TIMEOUT); + if (mcp23018_status) goto out; + +out: + i2c_stop(); + // SREG=sreg_prev; + // uprintf("Init %x\n", mcp23018_status); + return mcp23018_status; +} diff --git a/keyboards/gboards/gergoplex/gergoplex.h b/keyboards/gboards/gergoplex/gergoplex.h new file mode 100644 index 000000000000..58ba6777ba54 --- /dev/null +++ b/keyboards/gboards/gergoplex/gergoplex.h @@ -0,0 +1,37 @@ +#pragma once + +#include "quantum.h" +#include +#include +#include "i2c_master.h" +#include + +extern i2c_status_t mcp23018_status; +#define I2C_TIMEOUT 1000 +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 + +// I2C aliases and register addresses (see "mcp23018.md") +//#define I2C_ADDR 0b0100000 +#define I2C_ADDR 0x20 +#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE) +#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ) +#define IODIRA 0x00 // i/o direction register +#define IODIRB 0x01 +#define GPPUA 0x0C // GPIO pull-up resistor register +#define GPPUB 0x0D +#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT) +#define GPIOB 0x13 +#define OLATA 0x14 // output latch register +#define OLATB 0x15 + +uint8_t init_mcp23018(void); + +/* -------- LEFT HAND------RIGHT HAND ---------- */ +#define LAYOUT_gergoplex(L00, L01, L02, L03, L04, R00, R01, R02, R03, R04, L10, L11, L12, L13, L14, R10, R11, R12, R13, R14, L20, L21, L22, L23, L24, R20, R21, R22, R23, R24, L30, L31, L32, R30, R31, R32) \ + /* matrix positions */ \ + { \ + {L04, L14, L24, KC_NO}, {L03, L13, L23, L32}, {L02, L12, L22, L31}, {L01, L11, L21, L30}, {L00, L10, L20, KC_NO}, \ + \ + {R00, R10, R20, KC_NO}, {R01, R11, R21, R30}, {R02, R12, R22, R31}, {R03, R13, R23, R32}, {R04, R14, R24, KC_NO}, \ + } diff --git a/keyboards/gboards/gergoplex/keymaps/default/combos.def b/keyboards/gboards/gergoplex/keymaps/default/combos.def new file mode 100644 index 000000000000..c866eb0c3ad3 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/combos.def @@ -0,0 +1,12 @@ +// List any combo dictionaries you want loaded to +// your device below! + +// QMK wide includes +#include "combos/germ-vim-helpers.def" +#include "combos/germ-mouse-keys.def" + +// User includes +#include "gergoplex.def" + +// Word completion +// #include "combos/eng-combos.def" diff --git a/keyboards/gboards/gergoplex/keymaps/default/config.h b/keyboards/gboards/gergoplex/keymaps/default/config.h new file mode 100644 index 000000000000..6ff4bbf71309 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/config.h @@ -0,0 +1,2 @@ +#define COMBO_ALLOW_ACTION_KEYS +#define COMBO_VARIABLE_LEN diff --git a/keyboards/gboards/gergoplex/keymaps/default/gergoplex.def b/keyboards/gboards/gergoplex/keymaps/default/gergoplex.def new file mode 100644 index 000000000000..7a16c7dc808b --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/gergoplex.def @@ -0,0 +1,12 @@ +// Gergoplex specfic combos + +COMB(opBacksl, KC_BSLS, KC_O, KC_P) +COMB(hjLess, KC_LT, KC_H, KC_J) +COMB(klGreat, KC_GT, KC_K, KC_L) +COMB(xcDash, KC_MINS, KC_X, KC_C) +COMB(mcUnds, KC_UNDS, KC_M, KC_COMM) +COMB(nmQuot, KC_QUOT, KC_N, KC_M) +COMB(gbClic, KC_BTN1, KC_G, KC_B) +COMB(fvClic, KC_BTN2, KC_F, KC_V) + +SUBS(pasta, "I'd just like to interject for a moment.", KC_H, KC_J, KC_K, KC_L) diff --git a/keyboards/gboards/gergoplex/keymaps/default/keymap.c b/keyboards/gboards/gergoplex/keymaps/default/keymap.c new file mode 100644 index 000000000000..8bcb54bd4c10 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/keymap.c @@ -0,0 +1,75 @@ +/* Good on you for modifying your layout! if you don't have + * time to read the QMK docs, a list of keycodes can be found at + * + * https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md + * + * There's also a template for adding new layers at the bottom of this file! + */ + +#include QMK_KEYBOARD_H +#include "g/keymap_combo.h" + +#define BASE 0 // default layer +#define SYMB 1 // symbols +#define NUMB 2 // numbers/motion + +/* Combomap + * + * ,-----------------------------. ,--------------------------------. + * | | ESC | | | | | ESC | BSLH | + * |-----+-----+-----+-----+------| |--------------------------------| + * | | BSPC ENT | | | LES COLN GRT | | + * |-----+-----+-----+--RMB+-LMB--+ |--------------------------------| + * | | MINS | | | | QUO UNDR | | | + * `------+-----+-----+------+----' `--------------------------------' + * .-------------------------. .-----------------. + * | | | | | | | | + * '-------------------------' '-----------------' + */ + +// Blank template at the bottom +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Keymap 0: Basic layer + * + * ,-----------------------------. ,--------------------------------. + * | Q | W | E | R | T | | Y | U | I | O | P | + * |-----+-----+-----+-----+------| |--------------------------------| + * |CTRL/A| S | D | F | G | | H | J | K | L | CTRL/; | + * |-----+-----+-----+-----+------+ |--------------------------------| + * |SHFT/Z| X | C | V | B | | N | M | < | > | SHFT/? | + * `------+-----+-----+------+----' `--------------------------------' + * .-------------------------. .-----------------. + * |ESC/META|ENT/ALT|SPC(SYM)| |SPC(NUM)|BSPC|TAB| + * '-------------------------' '-----------------' + */ + [BASE] = LAYOUT_gergoplex(KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, MT(MOD_LCTL, KC_A), KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, MT(MOD_LCTL, KC_SCLN), MT(MOD_RSFT, KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, MT(MOD_RSFT, KC_SLSH), + + MT(MOD_LGUI, KC_ESC), MT(MOD_LALT, KC_ENT), LT(SYMB, KC_SPC), // Left + LT(NUMB, KC_SPC), KC_LSFT, MT(MOD_RSFT, KC_TAB) // Right + ), + /* Keymap 1: Symbols layer + * ,-----------------------------. ,--------------------------------. + * | ! | @ | { | } | | ` | ~ | | | \ | + * |-----+-----+-----+-----+------| |--------------------------------| + * | # | $ | ( | ) | LMB | | + | - | / | * | ' | + * |-----+-----+-----+-----+------+ |--------------------------------| + * | % | ^ | [ | ] | RMB | | & | = | , | . | - | + * `------+-----+-----+------+----' `--------------------------------' + * .-----------------. .------------------. + * |MMB | ; | = | | = | ; | DEL | + * '-----------------' '------------------' + */ + [SYMB] = LAYOUT_gergoplex(KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_GRV, KC_TILD, KC_TRNS, KC_TRNS, KC_BSLS, KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_BTN2, KC_PLUS, KC_MINS, KC_SLSH, KC_ASTR, KC_QUOT, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_BTN1, KC_AMPR, KC_EQL, KC_COMM, KC_DOT, KC_MINS, CMB_TOG, KC_SCLN, KC_EQL, KC_EQL, KC_SCLN, KC_DEL), + /* Keymap 2: Pad/Function layer + * ,-----------------------------. ,-------------------------------. + * | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | + * |-----+-----+-----+-----+------| |-------------------------------| + * | F1 | F2 | F3 | F4 | F5 | | LFT | DWN | UP | RGT | VOLUP | + * |-----+-----+-----+-----+------+ |-------------------------------| + * | F6 | F7 | F8 | F9 | F10 | |MLFT | MDWN| MUP | MRGT| VOLDN | + * `------+-----+-----+------+----' `-------------------------------' + * .-----------------. .-----------------. + * | F11 | F12| | | | PLY | SKP | + * '-----------------' '-----------------' + */ + [NUMB] = LAYOUT_gergoplex(KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_VOLU, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_VOLD, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT)}; diff --git a/keyboards/gboards/gergoplex/keymaps/default/rules.mk b/keyboards/gboards/gergoplex/keymaps/default/rules.mk new file mode 100644 index 000000000000..149fe7847a3b --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/rules.mk @@ -0,0 +1,24 @@ +#---------------------------------------------------------------------------- +# make gergo:germ:dfu +# Make sure you have dfu-programmer installed! +#---------------------------------------------------------------------------- +# Firmware options +MOUSEKEY_ENABLE = no + +#Debug options +VERBOSE = yes +DEBUG_MATRIX_SCAN_RATE = no +DEBUG_MATRIX = yes +CONSOLE_ENABLE = yes + +#Combos! +VPATH += keyboards/gboards/ + +# A bunch of stuff that you shouldn't touch unless you +# know what you're doing. +# +# No touchy, capiche? +SRC += matrix.c i2c_master.c +ifeq ($(strip $(DEBUG_MATRIX)), yes) + OPT_DEFS += -DDEBUG_MATRIX +endif diff --git a/keyboards/gboards/gergoplex/keymaps/default/testing.def b/keyboards/gboards/gergoplex/keymaps/default/testing.def new file mode 100644 index 000000000000..ff0afe3393e7 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/default/testing.def @@ -0,0 +1,4 @@ +// Gergoplex specfic combos + +COMB(overlap1, KC_Q, KC_B, KC_V) +COMB(overlap2, KC_R, KC_C, KC_V, KC_B) diff --git a/keyboards/gboards/gergoplex/keymaps/via/config.h b/keyboards/gboards/gergoplex/keymaps/via/config.h new file mode 100644 index 000000000000..87d5d68c6423 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/via/config.h @@ -0,0 +1,3 @@ +#define COMBO_COUNT 16 +#define COMBO_ALLOW_ACTION_KEYS +#define COMBO_TERM 50 diff --git a/keyboards/gboards/gergoplex/keymaps/via/keymap.c b/keyboards/gboards/gergoplex/keymaps/via/keymap.c new file mode 100644 index 000000000000..a8712112a1c4 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/via/keymap.c @@ -0,0 +1,55 @@ +// This is a via keymap! It lacks decent QMK features like combos! + +#include QMK_KEYBOARD_H + +#define BASE 0 // default layer +#define SYMB 1 // symbols +#define NUMB 2 // numbers/motion +#define FREE 3 // + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Keymap 0: Basic layer + * + * ,-----------------------------. ,--------------------------------. + * | Q | W | E | R | T | | Y | U | I | O | P | + * |-----+-----+-----+-----+------| |--------------------------------| + * |CTRL/A| S | D | F | G | | H | J | K | L | CTRL/; | + * |-----+-----+-----+-----+------+ |--------------------------------| + * |SHFT/Z| X | C | V | B | | N | M | < | > | SHFT/? | + * `------+-----+-----+------+----' `--------------------------------' + * .-------------------------. .-----------------. + * |ESC/META|ENT/ALT|SPC(SYM)| |SPC(NUM)|BSPC|TAB| + * '-------------------------' '-----------------' + */ + [BASE] = LAYOUT_gergoplex(KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, MT(MOD_LCTL, KC_A), KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, MT(MOD_LCTL, KC_SCLN), MT(MOD_RSFT, KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, MT(MOD_RSFT, KC_SLSH), + + MT(MOD_LGUI, KC_ESC), MT(MOD_LALT, KC_ENT), LT(SYMB, KC_SPC), // Left + LT(NUMB, KC_SPC), KC_LSFT, MT(MOD_RSFT, KC_TAB) // Right + ), + /* Keymap 1: Symbols layer + * ,-----------------------------. ,--------------------------------. + * | ! | @ | { | } | | ` | ~ | | | \ | + * |-----+-----+-----+-----+------| |--------------------------------| + * | # | $ | ( | ) | LMB | | + | - | / | * | ' | + * |-----+-----+-----+-----+------+ |--------------------------------| + * | % | ^ | [ | ] | RMB | | & | = | , | . | - | + * `------+-----+-----+------+----' `--------------------------------' + * .-----------------. .------------------. + * |MMB | ; | = | | = | ; | DEL | + * '-----------------' '------------------' + */ + [SYMB] = LAYOUT_gergoplex(KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_GRV, KC_TILD, KC_TRNS, KC_TRNS, KC_BSLS, KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_BTN2, KC_PLUS, KC_MINS, KC_SLSH, KC_ASTR, KC_QUOT, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_BTN1, KC_AMPR, KC_EQL, KC_COMM, KC_DOT, KC_MINS, KC_BTN3, KC_SCLN, KC_EQL, KC_EQL, KC_SCLN, KC_DEL), + /* Keymap 2: Pad/Function layer + * ,-----------------------------. ,-------------------------------. + * | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | + * |-----+-----+-----+-----+------| |-------------------------------| + * | F1 | F2 | F3 | F4 | F5 | | LFT | DWN | UP | RGT | VOLUP | + * |-----+-----+-----+-----+------+ |-------------------------------| + * | F6 | F7 | F8 | F9 | F10 | |MLFT | MDWN| MUP | MRGT| VOLDN | + * `------+-----+-----+------+----' `-------------------------------' + * .-----------------. .-----------------. + * | F11 | F12| | | | PLY | SKP | + * '-----------------' '-----------------' + */ + [NUMB] = LAYOUT_gergoplex(KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_VOLU, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_VOLD, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT), + [FREE] = LAYOUT_gergoplex(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, 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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)}; diff --git a/keyboards/gboards/gergoplex/keymaps/via/rules.mk b/keyboards/gboards/gergoplex/keymaps/via/rules.mk new file mode 100644 index 000000000000..65aa0aa6599b --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/via/rules.mk @@ -0,0 +1,24 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = atmel-dfu + +CUSTOM_MATRIX = yes +COMBO_ENABLE = yes +EXTRAKEY_ENABLE = yes +CONSOLE_ENABLE = yes +COMMAND_ENABLE = yes +BOOTMAGIC_ENABLE = lite +VIA_ENABLE = yes + +DEBOUNCE_TYPE = eager_pr +SRC += matrix.c +QUANTUM_LIB_SRC += i2c_master.c diff --git a/keyboards/gboards/gergoplex/matrix.c b/keyboards/gboards/gergoplex/matrix.c new file mode 100644 index 000000000000..2a30ef8fbc3b --- /dev/null +++ b/keyboards/gboards/gergoplex/matrix.c @@ -0,0 +1,288 @@ +/* + +Copyright 2013 Oleg Kostyuk + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "matrix.h" +#include +#include +#include +#include "wait.h" +#include "action_layer.h" +#include "print.h" +#include "debug.h" +#include "util.h" +#include "debounce.h" +#include QMK_KEYBOARD_H + +#ifdef BALLER +# include +# include "pointing_device.h" +#endif + +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif + +// MCP Pin Defs +#define RROW1 (1 << 3) +#define RROW2 (1 << 2) +#define RROW3 (1 << 1) +#define RROW4 (1 << 0) +#define COL1 (1 << 1) +#define COL2 (1 << 2) +#define COL3 (1 << 3) +#define COL4 (1 << 4) +#define COL5 (1 << 5) + +// ATmega pin defs +#define ROW1 (1 << 6) +#define ROW2 (1 << 5) +#define ROW3 (1 << 4) +#define ROW4 (1 << 1) +#define COL8 (1 << 1) +#define COL9 (1 << 2) +#define COL10 (1 << 3) +#define COL11 (1 << 2) +#define COL12 (1 << 3) + +// bit masks +#define BMASK (COL8 | COL9 | COL10) +#define DMASK (COL11 | COL12) +#define FMASK (ROW1 | ROW2 | ROW3 | ROW4) +#define RROWMASK (RROW1 | RROW2 | RROW3 | RROW4) +#define MCPMASK (COL0 | COL1 | COL2 | COL3 | COL4 | COL5 | COL6) + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +/* + * matrix state(1:on, 0:off) + * contains the raw values without debounce filtering of the last read cycle. + */ +static matrix_row_t raw_matrix[MATRIX_ROWS]; + +// Debouncing: store for each key the number of scans until it's eligible to +// change. When scanning the matrix, ignore any changes in keys that have +// already changed in the last DEBOUNCE scans. + +static matrix_row_t read_cols(uint8_t row); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + +static uint8_t mcp23018_reset_loop; +// static uint16_t mcp23018_reset_loop; + +__attribute__((weak)) void matrix_init_user(void) {} +__attribute__((weak)) void matrix_scan_user(void) {} +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } + +void matrix_init(void) { + // initialize row and col + mcp23018_status = init_mcp23018(); + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + raw_matrix[i] = 0; + } + + debounce_init(MATRIX_ROWS); + matrix_init_quantum(); +} +void matrix_power_up(void) { + mcp23018_status = init_mcp23018(); + + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + } +} + +// Reads and stores a row, returning +// whether a change occurred. +static inline bool store_raw_matrix_row(uint8_t index) { + matrix_row_t temp = read_cols(index); + if (raw_matrix[index] != temp) { + raw_matrix[index] = temp; + return true; + } + return false; +} +uint8_t matrix_scan(void) { + if (mcp23018_status) { // if there was an error + if (++mcp23018_reset_loop == 0) { + // if (++mcp23018_reset_loop >= 1300) { + // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans + // this will be approx bit more frequent than once per second + print("trying to reset mcp23018\n"); + mcp23018_status = init_mcp23018(); + if (mcp23018_status) { + print("left side not responding\n"); + } else { + print("left side attached\n"); + } + } + } + + bool changed = false; + for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { + // select rows from left and right hands + uint8_t left_index = i; + uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; + select_row(left_index); + select_row(right_index); + + // we don't need a 30us delay anymore, because selecting a + // left-hand row requires more than 30us for i2c. + + changed |= store_raw_matrix_row(left_index); + changed |= store_raw_matrix_row(right_index); + + unselect_rows(); + } + + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + matrix_scan_quantum(); + +#ifdef DEBUG_MATRIX + for (uint8_t c = 0; c < MATRIX_COLS; c++) + for (uint8_t r = 0; r < MATRIX_ROWS; r++) + if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c); +#endif + + return 1; +} + +bool matrix_is_modified(void) // deprecated and evidently not called. +{ + return true; +} + +inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } +inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } + +void matrix_print(void) { + print("\nr/c 0123456789ABCDEF\n"); + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + phex(row); + print(": "); + pbin_reverse16(matrix_get_row(row)); + print("\n"); + } +} +uint8_t matrix_key_count(void) { + uint8_t count = 0; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + count += bitpop16(matrix[i]); + } + return count; +} + +// Remember this means ROWS +static void init_cols(void) { + // init on mcp23018 + // not needed, already done as part of init_mcp23018() + + // Input with pull-up(DDR:0, PORT:1) + DDRF &= ~FMASK; + PORTF |= FMASK; +} +static matrix_row_t read_cols(uint8_t row) { + if (row < 5) { + if (mcp23018_status) { // if there was an error + return 0; + } else { + uint8_t data = 0; + mcp23018_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_read_nack(I2C_TIMEOUT); + if (mcp23018_status < 0) goto out; + data = ~((uint8_t)mcp23018_status); + mcp23018_status = I2C_STATUS_SUCCESS; + out: + i2c_stop(); + +#ifdef DEBUG_MATRIX + if (data != 0x00) xprintf("I2C: %d\n", data); +#endif + return data; + } + } else { + return ~((((PINF & ROW4) >> 1) | ((PINF & (ROW1 | ROW2 | ROW3)) >> 3)) & 0xF); + } +} + +// Row pin configuration +static void unselect_rows(void) { + // no need to unselect on mcp23018, because the select step sets all + // the other row bits high, and it's not changing to a different + // direction + // Hi-Z(DDR:0, PORT:0) to unselect + DDRB &= ~BMASK; + PORTB &= ~BMASK; + DDRD &= ~DMASK; + PORTD &= ~DMASK; +} + +static void select_row(uint8_t row) { + if (row < 5) { + // select on mcp23018 + if (mcp23018_status) { // do nothing on error + } else { // set active row low : 0 // set other rows hi-Z : 1 + mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(0xFF & ~(1 << (row + 1)), I2C_TIMEOUT); + if (mcp23018_status) goto out; + out: + i2c_stop(); + } + } else { + // Output low(DDR:1, PORT:0) to select + switch (row) { + case 5: + DDRB |= COL8; + PORTB &= ~COL8; + break; + case 6: + DDRB |= COL9; + PORTB &= ~COL9; + break; + case 7: + DDRB |= COL10; + PORTB &= ~COL10; + break; + case 8: + DDRD |= COL11; + PORTD &= ~COL11; + break; + case 9: + DDRD |= COL12; + PORTD &= ~COL12; + break; + } + } +} diff --git a/keyboards/gboards/gergoplex/readme.md b/keyboards/gboards/gergoplex/readme.md new file mode 100644 index 000000000000..627524b02eb3 --- /dev/null +++ b/keyboards/gboards/gergoplex/readme.md @@ -0,0 +1,22 @@ +# GergoPlex + +![GergoPlex](https://assets.bigcartel.com/product_images/248890490/IMG_20191114_1406385-01-01.jpeg) + +A compact 30% (5x3+3) Split Keyboard from g Heavy Industries + +* Keyboard Maintainer: [Jeremy Bernhardt](https://github.com/germ) +* Hardware Supported: GergoPlex (Kit, Partial, Ready) +* Hardware Availability: [gboards.ca](http://gboards.ca) + +## Firmware building +After cloning the QMK repo and installing dfu-programmer build and flash with. Be sure to reset your keyboard! + + make gboards/gergoplex:default:flash + +To just test your build with the default keymap + + make gboards/gergoplex:default + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Have an idea for a gadget or a keymap? [Reach out to me!](mailto:bernhardtjeremy@gmail.com) or submit a PR! diff --git a/keyboards/gboards/gergoplex/rules.mk b/keyboards/gboards/gergoplex/rules.mk new file mode 100644 index 000000000000..b8a3642e71c1 --- /dev/null +++ b/keyboards/gboards/gergoplex/rules.mk @@ -0,0 +1,23 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +# Teensy halfkay +# Pro Micro caterina +# Atmel DFU atmel-dfu +# LUFA DFU lufa-dfu +# QMK DFU qmk-dfu +# ATmega32A bootloadHID +# ATmega328P USBasp +BOOTLOADER = atmel-dfu + +CUSTOM_MATRIX = yes +COMBO_ENABLE = yes +EXTRAKEY_ENABLE = yes +CONSOLE_ENABLE = yes +COMMAND_ENABLE = yes +BOOTMAGIC_ENABLE = lite + +DEBOUNCE_TYPE = eager_pr +SRC += matrix.c +QUANTUM_LIB_SRC += i2c_master.c