Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write firmware for the Ferris keyboard #9634

Merged
merged 18 commits into from
Jul 18, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions keyboards/handwired/ferris/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
Copyright 2020 Pierre Chevalier <[email protected]>

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 <http://www.gnu.org/licenses/>.
*/

#pragma once

/* USB Device descriptor parameter */
#define VENDOR_ID 0xC2AB
#define PRODUCT_ID 0x0000
#define DEVICE_VER 0x0001
#define MANUFACTURER Pierre
#define PRODUCT Ferris the keeb
#define DESCRIPTION A minimalistic 34 - keys split keyboard

/* key matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 10

#define MATRIX_ROWS_PER_SIDE (MATRIX_ROWS / 2)
#define MATRIX_COLS_PER_SIDE (MATRIX_COLS / 2)

#define UNUSED_MCU 14
#define UNUSED_MCP 7

// wiring
#define MATRIX_ROW_PINS_MCU \
{ B3, B2, B1, F0 }
#define MATRIX_COL_PINS_MCU \
{ D6, D7, B4, B5, B6 }
#define UNUSED_PINS_MCU \
{ B0, B7, C6, C7, D2, D3, D4, D5, E6, F1, F4, F5, F6, F7 }
#define MATRIX_ROW_PINS_MCP \
{ B0, B1, B2, B3 }
#define MATRIX_COL_PINS_MCP \
{ A0, A1, A2, A3, A4 }
#define UNUSED_PINS_MCP \
{ B4, B5, B6, B7, A5, A6, A7 }

/* COL2ROW, ROW2COL*/
#define DIODE_DIRECTION COL2ROW

/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST

/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 5

// Set the mouse settings to a comfortable speed/accuracy trade-off,
// assuming a screen refresh rate of 60 Htz or higher
// The default is 50. This makes the mouse ~3 times faster and more accurate
#define MOUSEKEY_INTERVAL 16
// The default is 20. Since we made the mouse about 3 times faster with the previous setting,
// give it more time to accelerate to max speed to retain precise control over short distances.
#define MOUSEKEY_TIME_TO_MAX 40
// The default is 300. Let's try and make this as low as possible while keeping the cursor responsive
#define MOUSEKEY_DELAY 100
// It makes sense to use the same delay for the mouseweel
#define MOUSEKEY_WHEEL_DELAY 100
// The default is 100
#define MOUSEKEY_WHEEL_INTERVAL 50
// The default is 40
#define MOUSEKEY_WHEEL_TIME_TO_MAX 100

// Pick good defaults for enabling homerow modifiers
#define TAPPING_TERM 200
#define PERMISSIVE_HOLD
#define IGNORE_MOD_TAP_INTERRUPT
#define TAPPING_FORCE_HOLD
fauxpark marked this conversation as resolved.
Show resolved Hide resolved
79 changes: 79 additions & 0 deletions keyboards/handwired/ferris/ferris.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Copyright 2013 Oleg Kostyuk <[email protected]>
2020 Pierre Chevalier <[email protected]>

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 <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
fauxpark marked this conversation as resolved.
Show resolved Hide resolved

bool i2c_initialized = 0;
i2c_status_t mcp23017_status = I2C_ADDR;

void matrix_init_kb(void) {
// set unused pins on mcu as input with internal pull-up enabled
pin_t unused_pins_mcu[UNUSED_MCU] = UNUSED_PINS_MCU;
for (int pin_index = 0; pin_index < UNUSED_MCU; pin_index++) {
pin_t pin = unused_pins_mcu[pin_index];
setPinInputHigh(pin);
}

matrix_init_user();
}

fauxpark marked this conversation as resolved.
Show resolved Hide resolved
uint8_t init_mcp23017(void) {
print("starting init");
mcp23017_status = I2C_ADDR;

// I2C subsystem
if (i2c_initialized == 0) {
i2c_init(); // on pins D(1,0)
i2c_initialized = true;
wait_ms(I2C_TIMEOUT);
}

// set pin direction
// - unused : input : 1
// - input : input : 1
// - driving : output : 0
mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
if (mcp23017_status) goto out;
mcp23017_status = i2c_write(IODIRA, I2C_TIMEOUT);
if (mcp23017_status) goto out;
// This means: we will read all the bits on GPIOA
mcp23017_status = i2c_write(0b11111111, I2C_TIMEOUT);
if (mcp23017_status) goto out;
// This means: we will write to the pins 0-4 on GPIOB (in select_rows)
mcp23017_status = i2c_write(0b11110000, I2C_TIMEOUT);
if (mcp23017_status) goto out;
i2c_stop();

// set pull-up
// - unused : on : 1
// - input : on : 1
// - driving : off : 0
mcp23017_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT);
if (mcp23017_status) goto out;
mcp23017_status = i2c_write(GPPUA, I2C_TIMEOUT);
if (mcp23017_status) goto out;
// This means: we will read all the bits on GPIOA
mcp23017_status = i2c_write(0b11111111, I2C_TIMEOUT);
if (mcp23017_status) goto out;
// This means: we will write to the pins 0-4 on GPIOB (in select_rows)
mcp23017_status = i2c_write(0b11110000, I2C_TIMEOUT);
if (mcp23017_status) goto out;

out:
i2c_stop();
return mcp23017_status;
}
74 changes: 74 additions & 0 deletions keyboards/handwired/ferris/ferris.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Copyright 2020 Pierre Chevalier <[email protected]>

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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "quantum.h"
#include "i2c_master.h"

extern i2c_status_t mcp23017_status;
#define I2C_TIMEOUT 1000

// For a better understanding of the i2c protocol, this is a good read:
// https://www.robot-electronics.co.uk/i2c-tutorial

// I2C address:
// See the datasheet, section 3.3.1 on addressing I2C devices and figure 3-6 for an
// illustration
// http://ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf
// All address pins of the mcp23017 are connected to the ground on the ferris
// | 0 | 1 | 0 | 0 | A2 | A1 | A0 |
// | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
#define I2C_ADDR 0b0100000
#define I2C_ADDR_WRITE ((I2C_ADDR << 1) | I2C_WRITE)
#define I2C_ADDR_READ ((I2C_ADDR << 1) | I2C_READ)

// Register addresses
// See https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h
#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_mcp23017(void);

// clang-format off

/* left hand right hand */
#define LAYOUT(\
K0_0, K0_1, K0_2, K0_3, K0_4, K0_5, K0_6, K0_7, K0_8, K0_9,\
K1_0, K1_1, K1_2, K1_3, K1_4, K1_5, K1_6, K1_7, K1_8, K1_9,\
K2_0, K2_1, K2_2, K2_3, K2_4, K2_5, K2_6, K2_7, K2_8, K2_9,\
K3_3, K3_4, K3_5, K3_6)\
/* matrix positions */\
{\
{K0_0, K0_1, K0_2, K0_3, K0_4},\
{K1_0, K1_1, K1_2, K1_3, K1_4},\
{K2_0, K2_1, K2_2, K2_3, K2_4},\
{KC_NO, KC_NO, KC_NO, K3_3, K3_4},\
\
{K0_5, K0_6, K0_7, K0_8, K0_9},\
{K1_5, K1_6, K1_7, K1_8, K1_9},\
{K2_5, K2_6, K2_7, K2_8, K2_9},\
{K3_5, K3_6, KC_NO, KC_NO, KC_NO}\
}

// clang-format on
54 changes: 54 additions & 0 deletions keyboards/handwired/ferris/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"keyboard_name": "Ferris",
"url": "https://github.com/pierrechevalier83/ferris/",
"maintainer": "@pierrec83",
"width": 12,
"height": 4.75,
"layouts": {
"LAYOUT": {
"layout": [
{"x": 0, "y": 0.93},
{"x": 1, "y": 0.31},
{"x": 2, "y": 0},
{"x": 3, "y": 0.28},
{"x": 4, "y": 0.42},

{"x": 7, "y": 0.42},
{"x": 8, "y": 0.28},
{"x": 9, "y": 0},
{"x": 10, "y": 0.31},
{"x": 11, "y": 0.93},

{"x": 0, "y": 1.93},
{"x": 1, "y": 1.31},
{"x": 2, "y": 1},
{"x": 3, "y": 1.28},
{"x": 4, "y": 1.42},

{"x": 7, "y": 1.42},
{"x": 8, "y": 1.28},
{"x": 9, "y": 1},
{"x": 10, "y": 1.31},
{"x": 11, "y": 1.93},

{"x": 0, "y": 2.93},
{"x": 1, "y": 2.31},
{"x": 2, "y": 2},
{"x": 3, "y": 2.28},
{"x": 4, "y": 2.42},

{"x": 7, "y": 2.42},
{"x": 8, "y": 2.28},
{"x": 9, "y": 2},
{"x": 10, "y": 2.31},
{"x": 11, "y": 2.93},

{"x": 3.5, "y": 3.75},
{"x": 4.5, "y": 4},

{"x": 6.5, "y": 4},
{"x": 7.5, "y": 3.75}
]
}
}
}
23 changes: 23 additions & 0 deletions keyboards/handwired/ferris/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include QMK_KEYBOARD_H

// Blank template at the bottom
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Qwerty
*
* ,-----------------------------. ,-----------------------------.
* | Q | W | E | R | T | | Y | U | I | O | P |
* |-----+-----+-----+-----+-----| |-----------------------------|
* | A | S | D | F | G | | H | J | K | L | ; |
* |-----+-----+-----+-----+-----+ |-----------------------------|
* | Z | X | C | V | B | | N | M | < | > | ? |
* `-----+-----+-----+-----+-----+--. ,-+-----------------------------'
* | BSPC | SPC | | SPC | ENT |
* '------------' '-----------'
*/
[0] = LAYOUT(
KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,
KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
KC_BSPC, KC_SPC, KC_SPC, KC_ENT)

fauxpark marked this conversation as resolved.
Show resolved Hide resolved
};
Loading