Initial commit

This commit is contained in:
Daniel Flanagan 2019-12-20 13:39:50 -06:00
commit a40e674406
23 changed files with 1258 additions and 0 deletions

8
.editorconfig Normal file
View file

@ -0,0 +1,8 @@
root = true
[*]
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = false
indent_style = tab
indent_size = 2

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "planck/lib/qmk_firmware"]
path = planck/lib/qmk_firmware
url = https://github.com/lytedev/qmk_firmware.git

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Daniel Flanagan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22
planck/Makefile Normal file
View file

@ -0,0 +1,22 @@
.PHONY: default
default: build
.PHONY: build
build: submodules
@mkdir -p lib/qmk_firmware/keyboards/planck/keymaps/lytedev/
@cp -r src/* lib/qmk_firmware/keyboards/planck/keymaps/lytedev/
@pushd lib/qmk_firmware/ && make planck/rev2:lytedev
.PHONY: flash
flash: build
@pushd lib/qmk_firmware/ && sudo make planck/rev2:lytedev:dfu
.PHONY: clean
clean:
@pushd lib/qmk_firmware/ && make clean
.PHONY: submodules
submodules:
git submodule init
git submodule update
@pushd lib/qmk_firmware/ && make git-submodule

@ -0,0 +1 @@
Subproject commit 9d9d68c100fb2af4f03aa717c5ebc38be72872ae

23
planck/readme.md Normal file
View file

@ -0,0 +1,23 @@
# planck
+ **TODO**: Picture of keyboard.
This contains my planck [`qmk_firmware`][0].
# Dependencies
* See [`qmk_firmware`][0].
# Flashing
```
make flash
```
# Modifying
+ Edit files in `src/` (particularly `keymap.c`).
+ Flash using previous instructions.
[0]: https://github.com/lytedev/qmk_firmware/

307
planck/src/keymap.c Normal file
View file

@ -0,0 +1,307 @@
#include "planck.h"
#include "action_layer.h"
#include "eeconfig.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
extern keymap_config_t keymap_config;
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _PLOVER 5
#define _ADJUST 16
#define ESC_CTL LCTL_T(KC_ESC)
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV
};
#define _______ KC_TRNS
#define XXXXXXX KC_NO
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | D | F | G | H | J | K | L | ; | \" |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = {
{KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
{ESC_CTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
{KC_LCTL, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O | \" |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = {
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
{ESC_CTL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | Tab | \" | , | . | P | Y | F | G | C | R | L | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | / |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{ESC_CTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH},
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END }
},
/* Raise
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL },
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_NUBS, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Plover layer (http://opensteno.org)
* ,-----------------------------------------------------------------------------------.
* | # | # | # | # | # | # | # | # | # | # | # | # |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | S | T | P | H | * | * | F | P | L | T | D |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* |TogOut| S | K | W | R | * | * | R | B | G | S | Z |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Exit | | | A | O | | E | U | | | |
* `-----------------------------------------------------------------------------------'
*/
[_PLOVER] = {
{KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 },
{XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC},
{XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX}
},
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_plover[][2] = SONG(PLOVER_SOUND);
float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
break;
return false;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
break;
return false;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
break;
return false;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
break;
return false;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
break;
return false;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
break;
return false;
case PLOVER:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
stop_all_notes();
PLAY_NOTE_ARRAY(tone_plover, false, 0);
#endif
layer_off(_RAISE);
layer_off(_LOWER);
layer_off(_ADJUST);
layer_on(_PLOVER);
if (!eeconfig_is_enabled()) {
eeconfig_init();
}
keymap_config.raw = eeconfig_read_keymap();
keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw);
}
break;
return false;
case EXT_PLV:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_plover_gb, false, 0);
#endif
layer_off(_PLOVER);
}
break;
return false;
}
return true;
}
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif

13
planck/src/rules.mk Normal file
View file

@ -0,0 +1,13 @@
BOOTMAGIC_ENABLE = no
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
CONSOLE_ENABLE = no
COMMAND_ENABLE = no
NKRO_ENABLE = yes
BACKLIGHT_ENABLE = no
MIDI_ENABLE = no
AUDIO_ENABLE = yes
UNICODE_ENABLE = no
BLUETOOTH_ENABLE = no
RGBLIGHT_ENABLE = no
SLEEP_LED_ENABLE = no

4
readme.md Normal file
View file

@ -0,0 +1,4 @@
# keyboards
+ [Planck](planck)
+ [Splyte](splyte)

22
splyte/Makefile Normal file
View file

@ -0,0 +1,22 @@
.PHONY: default
default: build
.PHONY: build
build: submodules
@mkdir -p ../planck/lib/qmk_firmware/keyboards/handwired/splyte/
@cp -r src/* ../planck/lib/qmk_firmware/keyboards/handwired/splyte/
@pushd ../planck/lib/qmk_firmware/ && make handwired/splyte
.PHONY: submodules
submodules:
git submodule init
git submodule update
@pushd ../planck/lib/qmk_firmware/ && make git-submodule
.PHONY: flash
flash: build
@pushd ../planck/lib/qmk_firmware/ && make handwired/splyte:avrdude
.PHONY: clean
clean:
@pushd ../planck/qmk_firmware/ && make clean

52
splyte/src/config.h Normal file
View file

@ -0,0 +1,52 @@
#pragma once
#include "config_common.h"
/* USB device identification parameters */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x0000
#define DEVICE_VER 0x0001
#define MANUFACTURER lytedev
#define PRODUCT Splyteboard
#define DESCRIPTION "Splyteboard"
#define MATRIX_ROWS 5
#define MATRIX_COLS 6 * 2
// #define COL_EXPANDED { false, false, false, false, false, false, true, true, true, true, true, true}
// #define EXPANDER_COL_REGISTER GPIOA
// #define EXPANDER_ROW_REGISTER GPIOB
// #define MATRIX_EXPANDER_COL_PINS {0, 1, 2, 3, 4, 5}
// #define MATRIX_EXPANDER_ROW_PINS {0, 1, 2, 3, 4, 5}
#define DIODE_DIRECTION ROW2COL
#define UNUSED_PINS
#define SOFT_SERIAL_PIN D0
#define DEBOUNCE 5
#define LOCKING_SUPPORT_ENABLE
#define LOCKING_RESYNC_ENABLE
#define MIDI_ADVANCED
#define MIDI_BASIC
#define MIDI_TONE_KEYCODE_OCTAVES 5
/*
Copyright 2019 Daniel Flanagan
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/>.
*/

104
splyte/src/expander.c Normal file
View file

@ -0,0 +1,104 @@
#include <stdbool.h>
#include "action.h"
#include "twi_master.h"
#include "expander.h"
#include "debug.h"
static uint8_t expander_status = 0;
static uint8_t expander_input = 0;
// TODO: grok this code
uint8_t expander_write(uint8_t, uint8_t);
void expander_scan(void);
void expander_config(void) {
expander_write(EXPANDER_REG_IPOLA, 0xFF);
expander_write(EXPANDER_REG_GPPUA, 0xFF);
expander_write(EXPANDER_REG_IODIRB, 0xFF);
}
void expander_init(void) {
twi_init();
expander_scan();
}
uint8_t expander_write(uint8_t reg, uint8_t data) {
if (expander_status == 0) return 0;
uint8_t ret;
ret = twi_start(EXPANDER_ADDR | TWI_WRITE);
if (ret) goto stop;
ret = twi_write(reg);
if (ret) goto stop;
ret = twi_write(data);
stop:
twi_stop();
return ret;
}
uint8_t expander_read(uint8_t reg, uint8_t *data) {
if (expander_status == 0) return 0;
uint8_t ret;
ret = twi_start(EXPANDER_ADDR | TWI_WRITE);
if (ret) goto stop;
ret = twi_write(reg);
if (ret) goto stop;
ret = twi_rep_start(EXPANDER_ADDR | TWI_READ);
if (ret) goto stop;
*data = twi_read_nak();
stop:
twi_stop();
return ret;
}
void expander_scan(void) {
uint8_t ret = twi_start(EXPANDER_ADDR | TWI_WRITE);
if (ret == 0) {
twi_stop();
if (expander_status == 0) {
expander_status = 1;
expander_config();
clear_keyboard();
}
}
else {
if (expander_status == 1) {
expander_status = 0;
clear_keyboard();
}
}
}
void expander_read_cols(void) {
expander_read(EXPANDER_REG_GPIOA, &expander_input);
}
uint8_t expander_get_col(uint8_t col) {
if (col > (MATRIX_COLS / 2) + 1) {
col++;
}
return expander_input & (1<<col) ? 1 : 0;
}
matrix_row_t expander_read_row(void) {
expander_read_cols();
/* make cols */
matrix_row_t cols = 0;
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (expander_get_col(col)) {
cols |= (1UL << (MATRIX_COLS + 1 - col));
}
}
return cols;
}
void expander_unselect_rows(void) {
expander_write(EXPANDER_REG_IODIRB, 0xFF);
}
void expander_select_row(uint8_t row) {
expander_write(EXPANDER_REG_IODIRB, ~(1<<(row)));
}

45
splyte/src/expander.h Normal file
View file

@ -0,0 +1,45 @@
#pragma once
#include <stdint.h>
#include "matrix.h"
#define MCP23017
#define MCP23017_A0 0
#define MCP23017_A1 0
#define MCP23017_A2 0
#ifdef MCP23017
#define EXPANDER_ADDR ((0x20|(MCP23017_A0<<0)|(MCP23017_A1<<1)|(MCP23017_A2<<2)) << 1)
enum EXPANDER_REG_BANK0 {
EXPANDER_REG_IODIRA = 0,
EXPANDER_REG_IODIRB,
EXPANDER_REG_IPOLA,
EXPANDER_REG_IPOLB,
EXPANDER_REG_GPINTENA,
EXPANDER_REG_GPINTENB,
EXPANDER_REG_DEFVALA,
EXPANDER_REG_DEFVALB,
EXPANDER_REG_INTCONA,
EXPANDER_REG_INTCONB,
EXPANDER_REG_IOCONA,
EXPANDER_REG_IOCONB,
EXPANDER_REG_GPPUA,
EXPANDER_REG_GPPUB,
EXPANDER_REG_INTFA,
EXPANDER_REG_INTFB,
EXPANDER_REG_INTCAPA,
EXPANDER_REG_INTCAPB,
EXPANDER_REG_GPIOA,
EXPANDER_REG_GPIOB,
EXPANDER_REG_OLATA,
EXPANDER_REG_OLATB
};
#endif
void expander_init(void);
void expander_scan(void);
void expander_read_cols(void);
uint8_t expander_get_col(uint8_t col);
matrix_row_t expander_read_row(void);
void expander_unselect_rows(void);
void expander_select_row(uint8_t row);

View file

@ -0,0 +1,19 @@
/* Copyright 2019 Daniel Flanagan
*
* 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
// overrides here

View file

@ -0,0 +1,81 @@
/* Copyright 2019 Daniel Flanagan
*
* 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
#define XXXXXXX KC_NO
#define _______ KC_TRNS
#define ESC_CTL LCTL_T(KC_ESC)
enum layers { L_QWERTY, L_LEFT, L_RIGHT, L_CONFIG, L_BOTH };
#define TAB_ALT LALT_T(KC_TAB)
#define K_L_L MO(L_LEFT)
#define K_L_R MO(L_RIGHT)
#define K_L_C MO(L_CONFIG)
#define K_L_B MO(L_BOTH)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[L_QWERTY] = LAYOUT(
KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_BSPC,
TAB_ALT, KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_BSPC,
ESC_CTL, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT,
KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_ENT ,
KC_LGUI, KC_SPC , K_L_L , K_L_C , K_L_C , KC_LALT, K_L_R , KC_RALT
),
[L_LEFT] = LAYOUT(
KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 ,
KC_TILD, KC_EXLM, KC_AT , KC_HASH, KC_DLR , KC_PERC , KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL ,
KC_DEL , _______, _______, _______, _______, _______ , _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______ , _______, K_L_B , K_L_B, _______
),
// the insert key at M's position is for easily inputting Shift+Insert
[L_RIGHT] = LAYOUT(
KC_ESC , KC_EXLM, KC_AT , KC_HASH, KC_DLR , KC_PERC , KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL ,
KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_DEL ,
KC_GRV , _______, _______, _______, _______, _______ , _______, KC_MINS, KC_EQL , KC_LBRC, KC_RBRC, KC_BSLS,
_______, _______, _______, _______, _______, _______ , _______, KC_INS , _______, _______, _______, _______,
_______, KC_LALT, K_L_B , _______ , _______, _______, _______, _______
),
[L_CONFIG] = LAYOUT(
RESET , _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______ , _______, _______, _______, _______
),
[L_BOTH] = LAYOUT(
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______ , KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, _______,
_______, _______, _______, _______, _______, _______ , KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, _______,
_______, _______, _______, _______, _______, _______ , KC_HOME, KC_PGDN, KC_PGUP, KC_END , _______, _______,
_______, _______, _______, _______ , _______, _______, _______, _______
)
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
void matrix_init_user(void) {}
void matrix_scan_user(void) {}
void led_set_user(uint8_t usb_led) {}

View file

@ -0,0 +1 @@
# The default keymap for Splyte

237
splyte/src/matrix.c Normal file
View file

@ -0,0 +1,237 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include "wait.h"
#include "action_layer.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "expander.h"
#ifdef DEBUG_MATRIX_SCAN_RATE
#include "timer.h"
#endif
#ifdef DEBUG_MATRIX_SCAN_RATE
uint32_t matrix_timer;
uint32_t matrix_scan_count;
#endif
static matrix_row_t matrix[MATRIX_ROWS];
static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
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);
__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) {
unselect_rows();
init_cols();
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
for (uint8_t j=0; j < MATRIX_COLS; ++j) {
debounce_matrix[i * MATRIX_COLS + j] = 0;
}
}
#ifdef DEBUG_MATRIX_SCAN_RATE
matrix_timer = timer_read32();
matrix_scan_count = 0;
#endif
matrix_init_quantum();
}
void matrix_power_up(void) {
unselect_rows();
init_cols();
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
}
#ifdef DEBUG_MATRIX_SCAN_RATE
matrix_timer = timer_read32();
matrix_scan_count = 0;
#endif
}
matrix_row_t debounce_mask(uint8_t row) {
matrix_row_t result = 0;
for (uint8_t j=0; j < MATRIX_COLS; ++j) {
if (debounce_matrix[row * MATRIX_COLS + j]) {
--debounce_matrix[row * MATRIX_COLS + j];
} else {
result |= (1 << j);
}
}
return result;
}
void debounce_report(matrix_row_t change, uint8_t row) {
for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
if (change & (1 << i)) {
debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
}
}
}
uint8_t matrix_scan(void) {
expander_scan();
#ifdef DEBUG_MATRIX_SCAN_RATE
matrix_scan_count++;
uint32_t timer_now = timer_read32();
if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) {
print("matrix scan frequency: ");
pdec(matrix_scan_count);
print("\n");
matrix_print();
matrix_timer = timer_now;
matrix_scan_count = 0;
}
#endif
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
select_row(i);
wait_us(30); // necessary for stable read values
matrix_row_t mask = debounce_mask(i);
matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask);
debounce_report(cols ^ matrix[i], i);
matrix[i] = cols;
unselect_rows();
}
matrix_scan_quantum();
return 1;
}
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;
}
/* Column pin configuration
*
* Feather 32u4 Bluefruit LE:
* 5 4 3 2 1 0
* F0 F1 F4 F5 F6 F7
* Expander:
* 13 12 11 10 9 8
*/
static void init_cols(void) {
DDRF &= ~(1<<PF0 | 1<<PF1 | 1<<PF4 | 1<<PF5 | 1<<PF6 | 1<<PF7);
PORTF |= (1<<PF0 | 1<<PF1 | 1<<PF4 | 1<<PF5 | 1<<PF6 | 1<<PF7);
expander_init();
}
static matrix_row_t read_cols(uint8_t row) {
return expander_read_row() |
(PINF&(1<<PF0) ? 0 : (1<<0)) |
(PINF&(1<<PF1) ? 0 : (1<<1)) |
(PINF&(1<<PF4) ? 0 : (1<<2)) |
(PINF&(1<<PF5) ? 0 : (1<<3)) |
(PINF&(1<<PF6) ? 0 : (1<<4)) |
(PINF&(1<<PF7) ? 0 : (1<<5)) ;
}
/* Row pin configuration
*
* Feather 32u4 Bluefruit LE:
* 0 1 2 3 4
* D6 B7 B6 B5 C6
* Expander:
* 0 1 2 3 4
*/
static void unselect_rows(void) {
DDRB &= ~(1<<PB7 | 1<<PB6 | 1<<PB5);
PORTB &= ~(1<<PB7 | 1<<PB6 | 1<<PB5);
DDRD &= ~(1<<PD6);
PORTD &= ~(1<<PD6);
DDRC &= ~(1<<PC6);
PORTC &= ~(1<<PC6);
expander_unselect_rows();
}
static void select_row(uint8_t row) {
switch (row) {
case 0:
DDRD |= (1<<PD6);
PORTD &= ~(1<<PD6);
break;
case 1:
DDRB |= (1<<PB7);
PORTB &= ~(1<<PB7);
break;
case 2:
DDRB |= (1<<PB6);
PORTB &= ~(1<<PB6);
break;
case 3:
DDRB |= (1<<PB5);
PORTB &= ~(1<<PB5);
break;
case 4:
DDRC |= (1<<PC6);
PORTC &= ~(1<<PC6);
break;
}
expander_select_row(row);
}

24
splyte/src/readme.md Normal file
View file

@ -0,0 +1,24 @@
# Splyte
**TODO**: pic(s)
Splyte is a simple handwired split keyboard build with BLE capabilities.
# Dependencies
* See [`qmk_firmware`][0].
+ Maintainer: [lytedev](https://github.com/lytedev)
+ Hardware Supported: Bluefruit Feather 32u4
+ Hardware Availability: adafruit.com
# Flashing
```
make flash
```
# Modifying
+ Edit files in `src/` (particularly `keymap/default/keymap.c`).
+ Flash using previous instructions.

43
splyte/src/rules.mk Normal file
View file

@ -0,0 +1,43 @@
SRC = \
twi_master.c \
matrix.c \
expander.c \
# MCU: Feather 32u4 Bluefruit LE
# IO Expander: MCP23017
MCU ?= atmega32u4
ARCH ?= AVR8
F_CPU ?= 8000000
F_USB ?= $(F_CPU)
USE_FPU ?= yes
BOOTLOADER ?= caterina
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
CUSTOM_MATRIX ?= yes # Custom matrix file for the ErgoDone
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE ?= no # Enable keyboard RGB underglow
MIDI_ENABLE ?= no # MIDI support (+2400 to 4200, depending on config)
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= yes # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # TODO: Audio output on port C6
FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches
HD44780_ENABLE ?= no # Enable support for HD44780 based LCDs (+400)
ADAFRUIT_BLE_ENABLE ?= yes
BLUETOOTH ?= AdafruitBLE
# SPLIT_KEYBOARD ?= yes
LAYOUTS = splyte

43
splyte/src/splyte.c Normal file
View file

@ -0,0 +1,43 @@
#include <print.h>
#include "splyte.h"
void matrix_init_kb(void) {
#ifdef CONSOLE_ENABLE
uprintf("matrix_init_kb");
#endif
matrix_init_user();
}
void matrix_scan_kb(void) {
matrix_scan_user();
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
return process_record_user(keycode, record);
}
void led_set_kb(uint8_t usb_led) {
led_set_user(usb_led);
}
void keyboard_post_init_user(void) {
debug_enable = true;
// debug_matrix = true;
}
/* Copyright 2019 Daniel Flanagan
*
* 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/>.
*/

36
splyte/src/splyte.h Normal file
View file

@ -0,0 +1,36 @@
#pragma once
#include "quantum.h"
#define XXX KC_NO
#define LAYOUT( \
l00, l01, l02, l03, l04, l05 , r00, r01, r02, r03, r04, r05, \
l10, l11, l12, l13, l14, l15 , r10, r11, r12, r13, r14, r15, \
l20, l21, l22, l23, l24, l25 , r20, r21, r22, r23, r24, r25, \
l30, l31, l32, l33, l34, l35 , r30, r31, r32, r33, r34, r35, \
l42, l43, l44, l45 , r40, r41, r42, r43 \
) \
{ \
{ l00, l01, l02, l03, l04, l05 , r00, r01, r02, r03, r04, r05 }, \
{ l10, l11, l12, l13, l14, l15 , r10, r11, r12, r13, r14, r15 }, \
{ l20, l21, l22, l23, l24, l25 , r20, r21, r22, r23, r24, r25 }, \
{ l30, l31, l32, l33, l34, l35 , r30, r31, r32, r33, r34, r35 }, \
{ XXX, XXX, l42, l43, l44, l45 , r40, r41, r42, r43, XXX, XXX } \
}
/* Copyright 2019 Daniel Flanagan
*
* 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/>.
*/

78
splyte/src/twi_master.c Normal file
View file

@ -0,0 +1,78 @@
#include <inttypes.h>
#include <compat/twi.h>
#include "twi_master.h"
// inspired by Peter Fleury's code found at /keyboards/ergodone/twimaster.c
#define SCL_CLOCK SCL_CLOCK_400_MHZ
#define S(N, REG) (N<<REG)
#define S1(REG) S(1, REG)
void twi_init(void) {
STATUS_REG = 0;
// TODO: does this correspond to clock somehow?
// TODO: magic number
BIT_RATE_REG = 10;
}
unsigned char twi_start(unsigned char address) {
CONTROL_REG = S1(INTERRUPT_CB) | S1(START_CONDITION_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
if ((CURRENT_STATUS != TW_START) && (CURRENT_STATUS != TW_REP_START)) return 1;
DATA_REG = address;
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
if ((CURRENT_STATUS != TW_MT_SLA_ACK) && (CURRENT_STATUS != TW_MR_SLA_ACK)) return 1;
return 0;
}
void twi_start_wait(unsigned char address) {
twi_start_wait:
CONTROL_REG = S1(INTERRUPT_CB) | S1(START_CONDITION_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
if ((CURRENT_STATUS != TW_START) && (CURRENT_STATUS != TW_REP_START)) goto twi_start_wait;
DATA_REG = address;
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
if ((CURRENT_STATUS == TW_MT_SLA_NACK) || (CURRENT_STATUS == TW_MR_DATA_NACK))
{
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB) | S1(STOP_CONDITION_CB);
WAIT_FOR_STOP;
goto twi_start_wait;
}
}
unsigned char twi_rep_start(unsigned char address) {
return twi_start( address );
}
void twi_stop(void) {
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB) | S1(STOP_CONDITION_CB);
while(CONTROL_REG & S1(STOP_CONDITION_CB));
}
unsigned char twi_write( unsigned char data ) {
DATA_REG = data;
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
if (CURRENT_STATUS != TW_MT_DATA_ACK) return 1;
return 0;
}
unsigned char twi_read_ack(void) {
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB) | S1(ENABLE_ACK_CB);
WAIT_FOR_INTERRUPT;
return DATA_REG;
}
unsigned char twi_read_nak(void) {
CONTROL_REG = S1(INTERRUPT_CB) | S1(TWI_ENABLE_CB);
WAIT_FOR_INTERRUPT;
return DATA_REG;
}

71
splyte/src/twi_master.h Normal file
View file

@ -0,0 +1,71 @@
#pragma once
#include <avr/io.h>
// control bits
// source: https://www.exploreembedded.com/wiki/Basics_of_I2C_with_AVR
#define INTERRUPT_CB TWINT
#define ENABLE_ACK_CB TWEA
#define START_CONDITION_CB TWSTA
#define STOP_CONDITION_CB TWSTO
#define WRITE_COLLISION_CB TWWC
#define TWI_ENABLE_CB TWEN
#define INTERRUPT_ENABLE_CB TWIE
#define START_COND_CB START_CONDITION_CB
#define STOP_COND_CB STOP_COND_CB
// status bits
// source: https://www.microchip.com/webdoc/AVRLibcReferenceManual/ch20s33s01.html
// registers
#define BIT_RATE_REG TWBR
#define CONTROL_REG TWCR
#define DATA_REG TWDR
#define STATUS_REG TWSR
#define ENABLE_REG TWEN
#define MASTER_REG TWSTA
#define STOP_COND_REG TWSTO
// misc constants
#define TWI_READ 1
#define TWI_WRITE 0
#define PRESCALAR_MASK 0xF8 // I don't know where this comes from T_T
#define SCL_CLOCK_100_MHZ 100000L // TODO: which resistor?
#define SCL_CLOCK_400_MHZ 400000L // TODO: which resistor?
#define SCL_CLOCK_1700_MHZ 1700000L // TODO: which resistor?
// helpers
#define WAIT_FOR_CONTROL_FLAGS(FLAGS) while(!(CONTROL_REG & FLAGS));
#define WAIT_FOR_INTERRUPT WAIT_FOR_CONTROL_FLAGS(S1(INTERRUPT_CB))
#define WAIT_FOR_START WAIT_FOR_CONTROL_FLAGS(S1(START_CONDITION_CB))
#define WAIT_FOR_STOP WAIT_FOR_CONTROL_FLAGS(S1(STOP_CONDITION_CB))
#define CURRENT_STATUS (TW_STATUS & PRESCALAR_MASK)
extern void twi_init(void);
extern void twi_stop(void);
extern unsigned char twi_start(unsigned char addr);
extern unsigned char twi_rep_start(unsigned char addr);
extern void twi_start_wait(unsigned char addr);
extern unsigned char twi_write(unsigned char data);
extern unsigned char twi_read_ack(void);
extern unsigned char twi_read_nak(void);
extern unsigned char twi_read(unsigned char ack);
#define twi_read(ack) (ack) ? twi_readAck() : twi_readNak();
/*
modified from Peter Fleury's code
found at /keyboards/ergodone/twimaster.h
original header below
*/
/*************************************************************************
* Title: C include file for the I2C master interface
* (i2cmaster.S or twimaster.c)
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device
* Usage: see Doxygen manual
**************************************************************************/