Merged from upstream

pull/990/head
Joshua T 9 years ago
commit 8f8d104759

3
.gitignore vendored

@ -30,4 +30,5 @@ CMakeLists.txt
.browse.VC.db*
*.stackdump
util/Win_Check_Output.txt
.vscode
.vscode
.stfolder

@ -21,8 +21,8 @@ RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
ENV keyboard=ergodox
ENV subproject=ez
ENV keymap=default
VOLUME /qmk
WORKDIR /qmk
CMD make clean ; make keyboard=${keyboard} keymap=${keymap}
WORKDIR /qmk

@ -32,11 +32,13 @@ ABS_ROOT_MAKEFILE := $(abspath $(ROOT_MAKEFILE))
ABS_STARTING_DIR := $(dir $(ABS_STARTING_MAKEFILE))
ABS_ROOT_DIR := $(dir $(ABS_ROOT_MAKEFILE))
STARTING_DIR := $(subst $(ABS_ROOT_DIR),,$(ABS_STARTING_DIR))
TEST_DIR := $(ROOT_DIR)/.build/test
BUILD_DIR := $(ROOT_DIR)/.build
TEST_DIR := $(BUILD_DIR)/test
ERROR_FILE := $(BUILD_DIR)/error_occured
MAKEFILE_INCLUDED=yes
# Helper function to process the newt element of a space separated path
# Helper function to process the newt element of a space separated path
# It works a bit like the traditional functional head tail
# so the CURRENT_PATH_ELEMENT will beome the new head
# and the PATH_ELEMENTS are the rest that are still unprocessed
@ -45,16 +47,16 @@ define NEXT_PATH_ELEMENT
$$(eval PATH_ELEMENTS := $$(wordlist 2,9999,$$(PATH_ELEMENTS)))
endef
# We change the / to spaces so that we more easily can work with the elements
# We change the / to spaces so that we more easily can work with the elements
# separately
PATH_ELEMENTS := $(subst /, ,$(STARTING_DIR))
# Initialize the path elements list for further processing
$(eval $(call NEXT_PATH_ELEMENT))
# This function sets the KEYBOARD; KEYMAP and SUBPROJECT to the correct
# This function sets the KEYBOARD; KEYMAP and SUBPROJECT to the correct
# variables depending on which directory you stand in.
# It's really a very simple if else chain, if you squint enough,
# but the makefile syntax makes it very verbose.
# It's really a very simple if else chain, if you squint enough,
# but the makefile syntax makes it very verbose.
# If we are in a subfolder of keyboards
ifeq ($(CURRENT_PATH_ELEMENT),keyboards)
$(eval $(call NEXT_PATH_ELEMENT))
@ -109,7 +111,7 @@ endif
.DEFAULT_GOAL := all
ifneq ($(KEYMAP),)
ifeq ($(SUBPROJECT),)
# Inside a keymap folder, just build the keymap, with the
# Inside a keymap folder, just build the keymap, with the
# default subproject
.DEFAULT_GOAL := $(KEYBOARD)-$(KEYMAP)
else
@ -161,7 +163,7 @@ define TRY_TO_MATCH_RULE_FROM_LIST_HELPER3
ifneq ($1,)
ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,$$(firstword $1)),true)
MATCHED_ITEM := $$(firstword $1)
else
else
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$$(wordlist 2,9999,$1)))
endif
endif
@ -169,10 +171,10 @@ endef
# A recursive helper function for finding the longest match
# $1 The list to be checed
# It works by always removing the currently matched item from the list
# It works by always removing the currently matched item from the list
# and call itself recursively, until a match is found
define TRY_TO_MATCH_RULE_FROM_LIST_HELPER2
# Stop the recursion when the list is empty
# Stop the recursion when the list is empty
ifneq ($1,)
RULE_BEFORE := $$(RULE)
$$(eval $$(call TRY_TO_MATCH_RULE_FROM_LIST_HELPER3,$1))
@ -268,7 +270,7 @@ define PARSE_KEYBOARD
$$(eval $$(call PARSE_SUBPROJECT,$$(SUBPROJECT)))
# If there's no matching subproject, we assume it's the default
# This will allow you to leave the subproject part of the target out
else
else
$$(eval $$(call PARSE_SUBPROJECT,))
endif
endef
@ -283,7 +285,7 @@ endef
# When entering this, the keyboard and subproject are known, so now we need
# to determine which keymaps are going to get compiled
define PARSE_SUBPROJECT
# If we want to compile the default subproject, then we need to
# If we want to compile the default subproject, then we need to
# include the correct makefile to determine the actual name of it
CURRENT_SP := $1
ifeq ($$(CURRENT_SP),)
@ -302,7 +304,7 @@ define PARSE_SUBPROJECT
endif
endif
# The special allsp is handled later
ifneq ($$(CURRENT_SP),allsp)
ifneq ($$(CURRENT_SP),allsp)
# get a list of all keymaps
KEYMAPS := $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(CURRENT_KB)/keymaps/*/.)))
ifneq ($$(CURRENT_SP),)
@ -341,7 +343,7 @@ define PARSE_SUBPROJECT
endif
endef
# If we want to parse all subprojects, but the keyboard doesn't have any,
# If we want to parse all subprojects, but the keyboard doesn't have any,
# then use defaultsp instead
define PARSE_ALL_SUBPROJECTS
ifeq ($$(SUBPROJECTS),)
@ -446,7 +448,7 @@ endef
# Set the silent mode depending on if we are trying to compile multiple keyboards or not
# By default it's on in that case, but it can be overriden by specifying silent=false
# By default it's on in that case, but it can be overriden by specifying silent=false
# from the command line
define SET_SILENT_MODE
ifdef SUB_IS_SILENT
@ -460,20 +462,34 @@ endef
include $(ROOT_DIR)/message.mk
RUN_COMMAND = \
$(COMMAND_$(SILENT_MODE)_$(COMMAND))
# The empty line is important here, as it will force a new shell to be created for each command
# Otherwise the command line will become too long with a lot of keyboards and keymaps
define RUN_COMMAND
+error_occured=0;\
$(COMMAND_$(SILENT_MODE)_$(COMMAND))\
if [ $$error_occured -gt 0 ]; then echo $$error_occured > $(ERROR_FILE); fi;
endef
define RUN_TEST
+error_occured=0;\
$($(TEST)_COMMAND)\
if [ $$error_occured -gt 0 ]; then echo $$error_occured > $(ERROR_FILE); fi;
endef
# Allow specifying just the subproject, in the keyboard directory, which will compile all keymaps
SUBPROJECTS := $(notdir $(patsubst %/Makefile,%,$(wildcard ./*/Makefile)))
.PHONY: $(SUBPROJECTS)
$(SUBPROJECTS): %: %-allkm
$(SUBPROJECTS): %: %-allkm
# Let's match everything, we handle all the rule parsing ourselves
.PHONY: %
%:
%:
# Check if we have the CMP tool installed
cmp --version >/dev/null 2>&1; if [ $$? -gt 0 ]; then printf "$(MSG_NO_CMP)"; exit 1; fi;
# Check if the submodules are dirty, and display a warning if they are
ifndef SKIP_GIT
git submodule status --recursive 2>/dev/null | \
while IFS= read -r x; do \
case "$$x" in \
@ -481,17 +497,18 @@ $(SUBPROJECTS): %: %-allkm
*) printf "$(MSG_SUBMODULE_DIRTY)";break;; \
esac \
done
endif
rm -f $(ERROR_FILE) > /dev/null 2>&1
$(eval $(call PARSE_RULE,$@))
$(eval $(call SET_SILENT_MODE))
# Run all the commands in the same shell, notice the + at the first line
# it has to be there to allow parallel execution of the submake
# This always tries to compile everything, even if error occurs in the middle
# But we return the error code at the end, to trigger travis failures
+error_occured=0; \
$(foreach COMMAND,$(COMMANDS),$(RUN_COMMAND)) \
if [ $$error_occured -gt 0 ]; then printf "$(MSG_ERRORS)" & exit $$error_occured; fi;\
$(foreach TEST,$(TESTS),$($(TEST)_COMMAND)) \
if [ $$error_occured -gt 0 ]; then printf "$(MSG_ERRORS)" & exit $$error_occured; fi;\
$(foreach COMMAND,$(COMMANDS),$(RUN_COMMAND))
if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
$(foreach TEST,$(TESTS),$(RUN_TEST))
if [ -f $(ERROR_FILE) ]; then printf "$(MSG_ERRORS)" & exit 1; fi;
# All should compile everything
.PHONY: all
@ -511,7 +528,11 @@ test: test-all
test-clean: test-all-clean
# Generate the version.h file
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
ifndef SKIP_GIT
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
else
GIT_VERSION := NA
endif
BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S")
$(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(ROOT_DIR)/quantum/version.h)
$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(ROOT_DIR)/quantum/version.h)

@ -131,6 +131,14 @@ ifndef CUSTOM_MATRIX
SRC += $(QUANTUM_DIR)/matrix.c
endif
ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
OPT_DEFS += -DAPI_SYSEX_ENABLE
SRC += $(QUANTUM_DIR)/api/api_sysex.c
OPT_DEFS += -DAPI_ENABLE
SRC += $(QUANTUM_DIR)/api.c
MIDI_ENABLE=yes
endif
ifeq ($(strip $(MIDI_ENABLE)), yes)
OPT_DEFS += -DMIDI_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
@ -153,6 +161,11 @@ ifeq ($(strip $(UCIS_ENABLE)), yes)
UNICODE_ENABLE = yes
endif
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
OPT_DEFS += -DUNICODEMAP_ENABLE
UNICODE_ENABLE = yes
endif
ifeq ($(strip $(UNICODE_ENABLE)), yes)
OPT_DEFS += -DUNICODE_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
@ -169,12 +182,26 @@ ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
endif
ifeq ($(strip $(PRINTING_ENABLE)), yes)
OPT_DEFS += -DPRINTING_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_printer.c
SRC += $(TMK_DIR)/protocol/serial_uart.c
endif
ifeq ($(strip $(SERIAL_LINK_ENABLE)), yes)
SRC += $(patsubst $(QUANTUM_PATH)/%,%,$(SERIAL_SRC))
OPT_DEFS += $(SERIAL_DEFS)
VAPTH += $(SERIAL_PATH)
endif
ifneq ($(strip $(VARIABLE_TRACE)),)
SRC += $(QUANTUM_DIR)/variable_trace.c
OPT_DEFS += -DNUM_TRACED_VARIABLES=$(strip $(VARIABLE_TRACE))
ifneq ($(strip $(MAX_VARIABLE_TRACE_SIZE)),)
OPT_DEFS += -DMAX_VARIABLE_TRACE_SIZE=$(strip $(MAX_VARIABLE_TRACE_SIZE))
endif
endif
# Optimize size but this may cause error "relocation truncated to fit"
#EXTRALDFLAGS = -Wl,--relax
@ -186,6 +213,7 @@ endif
VPATH += $(KEYBOARD_PATH)
VPATH += $(COMMON_VPATH)
include $(TMK_PATH)/protocol.mk
include $(TMK_PATH)/common.mk
SRC += $(TMK_COMMON_SRC)

@ -23,4 +23,5 @@ COMMON_VPATH += $(QUANTUM_PATH)
COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
COMMON_VPATH += $(QUANTUM_PATH)/audio
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
COMMON_VPATH += $(QUANTUM_PATH)/api
COMMON_VPATH += $(SERIAL_PATH)

@ -84,7 +84,7 @@ KC_PAUSE KC_PAUS 48 Keyboard Pause1
KC_INSERT KC_INS 49 Keyboard Insert1
KC_HOME 4A Keyboard Home1
KC_PGUP 4B Keyboard PageUp1
KC_DELETE KC_DELETE 4C Keyboard Delete Forward
KC_DELETE KC_DEL 4C Keyboard Delete Forward
KC_END 4D Keyboard End1
KC_PGDOWN KC_PGDN 4E Keyboard PageDown1
KC_RIGHT KC_RGHT 4F Keyboard RightArrow1

@ -67,7 +67,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define RGB_DI_PIN E2
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,30 @@
#include "amjpad.h"
#include "led.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
led_init_ports();
};
void matrix_scan_kb(void) {
// put your looping keyboard code here
// runs every cycle (a lot)
matrix_scan_user();
};
void led_init_ports(void) {
// * Set our LED pins as output
DDRD |= (1<<6);
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK)) {
// Turn numlock on
PORTD &= ~(1<<6);
} else {
// Turn numlock off
PORTD |= (1<<6);
}
}

@ -0,0 +1,46 @@
#ifndef AMJPAD_H
#define ADMJPAD_H
#include "quantum.h"
// readability
#define XXX KC_NO
/* AMJPAD matrix layout
* ,-------------------.
* | 00 | 01 | 02 | 03 |
* |----|----|----|----|
* | 10 | 11 | 12 | 13 |
* |----|----|----|----|
* | 20 | 21 | 22 | |
* |----|----|----| 23 |
* | 30 | 31 | 32 | |
* |----|----|----|----|
* | 40 | 41 | 42 | |
* |----|----|----| 43 |
* | 50 | 52 | |
* `-------------------'
*/
// The first section contains all of the arguments
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, \
k10, k11, k12, k13, \
k20, k21, k22, k23, \
k30, k31, k32, \
k40, k41, k42, k43, \
k50, k52 \
) \
{ \
{k00, k01, k02, k03}, \
{k10, k11, k12, k13}, \
{k20, k21, k22, k23}, \
{k30, k31, k32, XXX}, \
{k40, k41, k42, k43}, \
{k50, XXX, k52, XXX} \
}
void matrix_init_user(void);
void matrix_scan_user(void);
#endif

@ -0,0 +1,94 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0003
#define MANUFACTURER AMJ
#define PRODUCT PAD
#define DESCRIPTION QMK keyboard firmware for AMJ PAD
/* key matrix size */
#define MATRIX_ROWS 6
#define MATRIX_COLS 4
// ROWS: Top to bottom, COLS: Left to right
#define MATRIX_ROW_PINS { F7, F6, F5, F4, D5, D0 }
#define MATRIX_COL_PINS { F1, F0, E6, C7 }
#define UNUSED_PINS
#define BACKLIGHT_PIN B6
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* Backlight configuration
*/
#define BACKLIGHT_LEVELS 4
/* Underlight configuration
*/
#define RGB_DI_PIN E2
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,101 @@
#include "amjpad.h"
#ifdef RGBLIGHT_ENABLE
#include "rgblight.h"
#endif
// Used for SHIFT_ESC
#define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _BL 0
#define _FL 1
#define _______ KC_TRNS
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _BL: (Base Layer) Default Layer
* ,-------------------.
* |Esc |TAB |BS | = |
* |----|----|----|----|
* | NL | / | * | - |
* |----|----|----|----|
* | 7 | 8 | 9 | |
* |----|----|----| + |
* | 4 | 5 | 6 | |
* |----|----|----|----|
* | 1 | 2 | 3 | |
* |----|----|----| En |
* | 0 |./FN| |
* `-------------------'
*/
[_BL] = KEYMAP(
KC_ESC,KC_TAB,KC_BSPC,KC_PEQL, \
KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, \
KC_P7, KC_P8, KC_P9, KC_PPLS, \
KC_P4, KC_P5, KC_P6, \
KC_P1, KC_P2, KC_P3, KC_PENT, \
KC_P0, LT(_FL,KC_PDOT)),
/* Keymap _FL: Function Layer
* ,-------------------.
* |Esc |TAB |BS | = |
* |----|----|----|----|
* | NL | / | * | - |
* |----|----|----|----|
* | 7 | 8 | 9 | |
* |----|----|----|RST |
* | 4 | 5 | 6 | |
* |----|----|----|----|
* | 1 | 2 | 3 | |
* |----|----|----| En |
* | 0 |./FN| |
* `-------------------'
*/
[_FL] = KEYMAP(
KC_ESC,KC_TAB,KC_BSPC,KC_PEQL, \
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
KC_P7, KC_P8, KC_P9, RESET, \
KC_P4, KC_P5, KC_P6, \
KC_P1, KC_P2, KC_P3, KC_PENT, \
KC_P0, LT(_FL,KC_PDOT)),
};
enum function_id {
SHIFT_ESC,
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(SHIFT_ESC),
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t shift_esc_shift_mask;
switch (id) {
case SHIFT_ESC:
shift_esc_shift_mask = get_mods()&MODS_CTRL_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_GRV);
send_keyboard_report();
} else {
add_key(KC_ESC);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_GRV);
send_keyboard_report();
} else {
del_key(KC_ESC);
send_keyboard_report();
}
}
break;
}
}

@ -0,0 +1,66 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
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 ?= yes # Commands for debug and configuration
NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
RGBLIGHT_ENABLE ?= no # Enable keyboard underlight functionality (+4870)
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality (+1150)
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID

@ -0,0 +1,80 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER Arbitrary Definitions
#define PRODUCT Planckeus
#define DESCRIPTION q.m.k. keyboard firmware for Planckeus
/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 11
#define MATRIX_ROW_PINS { D0, D1, D2, D3 }
#define MATRIX_COL_PINS { F6, F5, F4, F1, F0, F7, B0, B1, B2, B3, B7 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
//#define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,45 @@
#include "atreus.h"
#define BASE 0
#define SYMB 1
#define ETC 2
enum macro_id {
TEENSY,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[BASE] = KEYMAP(
KC_Q, KC_W, KC_D, KC_F, KC_K, KC_J, KC_U, KC_R, KC_L, KC_SCLN,
LT(ETC,KC_A), KC_S, KC_E, KC_T, KC_G, KC_Y, KC_N, KC_I, KC_O, KC_H,
SFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_P, KC_M, KC_COMM, KC_DOT, SFT_T(KC_SLSH),
KC_GRV, KC_DEL, KC_LALT, GUI_T(KC_TAB), LT(SYMB,KC_BSPC), CTL_T(KC_ESC), SFT_T(KC_ENT), LT(SYMB,KC_SPC), GUI_T(KC_LEFT), KC_DOWN, KC_UP, LCAG_T(KC_RGHT)
),
[SYMB] = KEYMAP(
KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_EQL, KC_7, KC_8, KC_9, KC_PLUS,
KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_BSLS, KC_MINS, KC_4, KC_5, KC_6, KC_QUOT,
KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_ASTR, KC_UNDS, KC_1, KC_2, KC_3, KC_DQUO,
KC_TILD, KC_AMPR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_NO, KC_DOT, KC_TRNS
),
[ETC] = KEYMAP(
RESET, KC_NO, KC_NO, KC_NO, KC_PGUP, KC_VOLU, KC_F7, KC_F8, KC_F9, KC_HOME,
LT(ETC,KC_A), KC_NO, KC_NO, KC_NO, KC_PGDN, KC_VOLD, KC_F4, KC_F5, KC_F6, KC_END,
KC_NO, KC_NO, KC_NO, KC_NO, KC_DEL, KC_MUTE, KC_F1, KC_F2, KC_F3, KC_INS,
KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO
),
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch(id) {
case TEENSY:
break;
}
return MACRO_NONE;
};

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1 @@
#include "atreus62.h"

@ -0,0 +1,26 @@
#ifndef ATREUS62_H
#define ATREUS62_H
#include "quantum.h"
void promicro_bootloader_jmp(bool program);
// This a shortcut to help you visually see your layout.
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
) \
{ \
{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
{ k20, k21, k22, k23, k24, k25, KC_NO, k26, k27, k28, k29, k2a, k2b }, \
{ k30, k31, k32, k33, k34, k35, k46, k36, k37, k38, k39, k3a, k3b }, \
{ k40, k41, k42, k43, k44, k45, k47, k48, k49, k4a, k4b, k4c, k4d } \
}
#endif

@ -0,0 +1,83 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6062
#define DEVICE_VER 0x0001
#define MANUFACTURER Profet
#define PRODUCT Atreus62
#define DESCRIPTION q.m.k. keyboard firmware for Atreus62
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 5
#define MATRIX_COLS 13
// wiring of each half
#define MATRIX_ROW_PINS { D2, D3, D1, D0, D4 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2, B6, B5, B4, E6, D7, C6 }
#define CATERINA_BOOTLOADER
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION ROW2COL
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
// #define NO_DEBUG
/* disable print */
// #define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,71 @@
// this is the style you want to emulate.
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
#include "atreus62.h"
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _DEFAULT 0
#define _NAV 1
#define _RESET 2
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_DEFAULT] = { /* qwerty */
{ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS },
{ KC_BSLS, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_TRNS, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_RBRC },
{ KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_TRNS, 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_DELT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LBRC },
{ KC_LCTL, KC_LGUI, KC_LALT, KC_GRV, MO(_NAV),KC_BSPC, KC_ENT, KC_SPC, KC_EQL, KC_MINS, KC_QUOT, KC_ENT, KC_RGUI }
},
[_NAV] = {
{ TO(_DEFAULT), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11 },
{ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_F12, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS },
{ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS },
{ TO(_RESET), 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 }
},
[_RESET] = {
{ TO(_DEFAULT), KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO },
{ KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO },
{ KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO },
{ KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO },
{ KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , KC_NO , RESET }
}
/*
[_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, 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 }
},
*/
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch (id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
}
else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};

@ -0,0 +1,362 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <avr/pgmspace.h>
// Workaround for wrong definitions in "iom32u4.h".
// This should be fixed in the AVR toolchain.
#undef UHCON
#undef UHINT
#undef UHIEN
#undef UHADDR
#undef UHFNUM
#undef UHFNUML
#undef UHFNUMH
#undef UHFLEN
#undef UPINRQX
#undef UPINTX
#undef UPNUM
#undef UPRST
#undef UPCONX
#undef UPCFG0X
#undef UPCFG1X
#undef UPSTAX
#undef UPCFG2X
#undef UPIENX
#undef UPDATX
#undef TCCR2A
#undef WGM20
#undef WGM21
#undef COM2B0
#undef COM2B1
#undef COM2A0
#undef COM2A1
#undef TCCR2B
#undef CS20
#undef CS21
#undef CS22
#undef WGM22
#undef FOC2B
#undef FOC2A
#undef TCNT2
#undef TCNT2_0
#undef TCNT2_1
#undef TCNT2_2
#undef TCNT2_3
#undef TCNT2_4
#undef TCNT2_5
#undef TCNT2_6
#undef TCNT2_7
#undef OCR2A
#undef OCR2_0
#undef OCR2_1
#undef OCR2_2
#undef OCR2_3
#undef OCR2_4
#undef OCR2_5
#undef OCR2_6
#undef OCR2_7
#undef OCR2B
#undef OCR2_0
#undef OCR2_1
#undef OCR2_2
#undef OCR2_3
#undef OCR2_4
#undef OCR2_5
#undef OCR2_6
#undef OCR2_7
#define NUM_DIGITAL_PINS 30
#define NUM_ANALOG_INPUTS 12
#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
#define TXLED0 PORTD |= (1<<5)
#define TXLED1 PORTD &= ~(1<<5)
#define RXLED0 PORTB |= (1<<0)
#define RXLED1 PORTB &= ~(1<<0)
static const uint8_t SDA = 2;
static const uint8_t SCL = 3;
#define LED_BUILTIN 13
// Map SPI port to 'new' pins D14..D17
static const uint8_t SS = 17;
static const uint8_t MOSI = 16;
static const uint8_t MISO = 14;
static const uint8_t SCK = 15;
// Mapping of analog pins as digital I/O
// A6-A11 share with digital pins
static const uint8_t ADC0 = 18;
static const uint8_t ADC1 = 19;
static const uint8_t ADC2 = 20;
static const uint8_t ADC3 = 21;
static const uint8_t ADC4 = 22;
static const uint8_t ADC5 = 23;
static const uint8_t ADC6 = 24; // D4
static const uint8_t ADC7 = 25; // D6
static const uint8_t ADC8 = 26; // D8
static const uint8_t ADC9 = 27; // D9
static const uint8_t ADC10 = 28; // D10
static const uint8_t ADC11 = 29; // D12
#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) 0
#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
#ifdef ARDUINO_MAIN
// On the Arduino board, digital pins are also used
// for the analog output (software PWM). Analog input
// pins are a separate set.
// ATMEL ATMEGA32U4 / ARDUINO LEONARDO
//
// D0 PD2 RXD1/INT2
// D1 PD3 TXD1/INT3
// D2 PD1 SDA SDA/INT1
// D3# PD0 PWM8/SCL OC0B/SCL/INT0
// D4 A6 PD4 ADC8
// D5# PC6 ??? OC3A/#OC4A
// D6# A7 PD7 FastPWM #OC4D/ADC10
// D7 PE6 INT6/AIN0
//
// D8 A8 PB4 ADC11/PCINT4
// D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5
// D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6
// D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7
// D12 A11 PD6 T1/#OC4D/ADC9
// D13# PC7 PWM10 CLK0/OC4A
//
// A0 D18 PF7 ADC7
// A1 D19 PF6 ADC6
// A2 D20 PF5 ADC5
// A3 D21 PF4 ADC4
// A4 D22 PF1 ADC1
// A5 D23 PF0 ADC0
//
// New pins D14..D17 to map SPI port to digital pins
//
// MISO D14 PB3 MISO,PCINT3
// SCK D15 PB1 SCK,PCINT1
// MOSI D16 PB2 MOSI,PCINT2
// SS D17 PB0 RXLED,SS/PCINT0
//
// Connected LEDs on board for TX and RX
// TXLED D24 PD5 XCK1
// RXLED D17 PB0
// HWB PE2 HWB
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &DDRB,
(uint16_t) &DDRC,
(uint16_t) &DDRD,
(uint16_t) &DDRE,
(uint16_t) &DDRF,
};
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
(uint16_t) &PORTE,
(uint16_t) &PORTF,
};
const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PINB,
(uint16_t) &PINC,
(uint16_t) &PIND,
(uint16_t) &PINE,
(uint16_t) &PINF,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, // D0 - PD2
PD, // D1 - PD3
PD, // D2 - PD1
PD, // D3 - PD0
PD, // D4 - PD4
PC, // D5 - PC6
PD, // D6 - PD7
PE, // D7 - PE6
PB, // D8 - PB4
PB, // D9 - PB5
PB, // D10 - PB6
PB, // D11 - PB7
PD, // D12 - PD6
PC, // D13 - PC7
PB, // D14 - MISO - PB3
PB, // D15 - SCK - PB1
PB, // D16 - MOSI - PB2
PB, // D17 - SS - PB0
PF, // D18 - A0 - PF7
PF, // D19 - A1 - PF6
PF, // D20 - A2 - PF5
PF, // D21 - A3 - PF4
PF, // D22 - A4 - PF1
PF, // D23 - A5 - PF0
PD, // D24 - PD5
PD, // D25 / D6 - A7 - PD7
PB, // D26 / D8 - A8 - PB4
PB, // D27 / D9 - A9 - PB5
PB, // D28 / D10 - A10 - PB6
PD, // D29 / D12 - A11 - PD6
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
_BV(2), // D0 - PD2
_BV(3), // D1 - PD3
_BV(1), // D2 - PD1
_BV(0), // D3 - PD0
_BV(4), // D4 - PD4
_BV(6), // D5 - PC6
_BV(7), // D6 - PD7
_BV(6), // D7 - PE6
_BV(4), // D8 - PB4
_BV(5), // D9 - PB5
_BV(6), // D10 - PB6
_BV(7), // D11 - PB7
_BV(6), // D12 - PD6
_BV(7), // D13 - PC7
_BV(3), // D14 - MISO - PB3
_BV(1), // D15 - SCK - PB1
_BV(2), // D16 - MOSI - PB2
_BV(0), // D17 - SS - PB0
_BV(7), // D18 - A0 - PF7
_BV(6), // D19 - A1 - PF6
_BV(5), // D20 - A2 - PF5
_BV(4), // D21 - A3 - PF4
_BV(1), // D22 - A4 - PF1
_BV(0), // D23 - A5 - PF0
_BV(5), // D24 - PD5
_BV(7), // D25 / D6 - A7 - PD7
_BV(4), // D26 / D8 - A8 - PB4
_BV(5), // D27 / D9 - A9 - PB5
_BV(6), // D28 / D10 - A10 - PB6
_BV(6), // D29 / D12 - A11 - PD6
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER0B, /* 3 */
NOT_ON_TIMER,
TIMER3A, /* 5 */
TIMER4D, /* 6 */
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER1A, /* 9 */
TIMER1B, /* 10 */
TIMER0A, /* 11 */
NOT_ON_TIMER,
TIMER4A, /* 13 */
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
7, // A0 PF7 ADC7
6, // A1 PF6 ADC6
5, // A2 PF5 ADC5
4, // A3 PF4 ADC4
1, // A4 PF1 ADC1
0, // A5 PF0 ADC0
8, // A6 D4 PD4 ADC8
10, // A7 D6 PD7 ADC10
11, // A8 D8 PB4 ADC11
12, // A9 D9 PB5 ADC12
13, // A10 D10 PB6 ADC13
9 // A11 D12 PD6 ADC9
};
#endif /* ARDUINO_MAIN */
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_MONITOR Serial
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* Pins_Arduino_h */

@ -0,0 +1,10 @@
atreus62 keyboard firmware
======================
This firmware is for the atreus62 keyboard.
This version utilizes a Pro Micro for its controller and has a 62 key layout.
https://github.com/profet23/atreus62
TODO: More information

@ -0,0 +1,66 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
#BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
#MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= yes # Unicode
#BLUETOOTH_ENABLE ?= yes # Enable Bluetooth with the Adafruit EZ-Key HID
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -26,7 +26,7 @@
/* Underlight configuration
*/
#define RGB_DI_PIN B2
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 14 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -30,7 +30,7 @@
/* Underlight configuration
*/
#define RGB_DI_PIN D7
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 14 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -140,7 +140,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Underlight configuration
*/
#define RGB_DI_PIN E6
//#define RGBLIGHT_TIMER
//#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 4 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -4,7 +4,7 @@
#include "../../config.h"
// place overrides here
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLIGHT_EFFECT_SNAKE_LENGTH 3
#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 2
#define RGBLIGHT_EFFECT_KNIGHT_OFFSET 2

@ -70,7 +70,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Underlight configuration
*/
#define RGB_DI_PIN F6
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 4 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1 @@
#include "converter.h"

@ -0,0 +1 @@
#include "quantum.h"

@ -0,0 +1,40 @@
Keyboard converter for IBM terminal keyboard
============================================
This is a port of TMK's converter/terminal_usb to QMK.
It supports PS/2 Scan Code Set 3 and runs on USB AVR chips such like PJRC Teensy.
I tested the converter on ATMega32U4 with 1392595(102keys) and 6110345(122keys).
Source code: https://github.com/tmk/tmk_keyboard
Article: http://geekhack.org/index.php?topic=27272.0
CONNECTION
----------
Keyboard ATMega32U4
----------------------
Data: PD2
Clock: PD5
And VCC and GND, of course. See RESOURCE for keyboard connector pin assign.
BUILD
-----
$ git clone https://github.com/tmk/tmk_keyboard.git
$ cd converter/terminal_usb
$ make
RESOURCE
--------
Soarer's Converter: http://geekhack.org/index.php?topic=17458.0
102keys(1392595): http://geekhack.org/index.php?topic=10737.0
122keys(1390876): http://www.seasip.info/VintagePC/ibm_1390876.html
KbdBabel: http://www.kbdbabel.org/
RJ45 Connector: http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
DIN Connector: http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
WinAVR: http://winavr.sourceforge.net/
EOF

@ -0,0 +1,138 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2016 Priyadi Iman Nurcahyo <priyadi@priyadi.net>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6535
#define DEVICE_VER 0x0100
#define MANUFACTURER QMK
#define PRODUCT IBM Terminal Keyboard
#define DESCRIPTION USB converter for IBM Terminal Keyboard
/* matrix size */
#define MATRIX_ROWS 17 // keycode bit: 3-0
#define MATRIX_COLS 8 // keycode bit: 6-4
/* legacy keymap support */
#define USE_LEGACY_KEYMAP
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_RALT) | MOD_BIT(KC_RCTL)) \
)
/*
* PS/2 USART configuration for ATMega32U4
*/
#ifdef PS2_USE_USART
/* XCK for clock line */
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 5
/* RXD for data line */
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 2
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
/* set DDR of CLOCK as input to be slave */
#define PS2_USART_INIT() do { \
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
UCSR1C = ((1 << UMSEL10) | \
(3 << UPM10) | \
(0 << USBS1) | \
(3 << UCSZ10) | \
(0 << UCPOL1)); \
UCSR1A = 0; \
UBRR1H = 0; \
UBRR1L = 0; \
} while (0)
#define PS2_USART_RX_INT_ON() do { \
UCSR1B = ((1 << RXCIE1) | \
(1 << RXEN1)); \
} while (0)
#define PS2_USART_RX_POLL_ON() do { \
UCSR1B = (1 << RXEN1); \
} while (0)
#define PS2_USART_OFF() do { \
UCSR1C = 0; \
UCSR1B &= ~((1 << RXEN1) | \
(1 << TXEN1)); \
} while (0)
#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
#define PS2_USART_RX_DATA UDR1
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
#define PS2_USART_RX_VECT USART1_RX_vect
#endif
/*
* PS/2 Interrupt configuration
*/
#ifdef PS2_USE_INT
/* uses INT1 for clock line(ATMega32U4) */
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 1
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 0
#define PS2_INT_INIT() do { \
EICRA |= ((1<<ISC11) | \
(0<<ISC10)); \
} while (0)
#define PS2_INT_ON() do { \
EIMSK |= (1<<INT1); \
} while (0)
#define PS2_INT_OFF() do { \
EIMSK &= ~(1<<INT1); \
} while (0)
#define PS2_INT_VECT INT1_vect
#endif
/*
* PS/2 Busywait configuration
*/
#ifdef PS2_USE_BUSYWAIT
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 1
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 0
#endif
#endif

@ -0,0 +1,6 @@
#include "ibm_terminal.h"
// void matrix_init_kb(void) {
// matrix_init_user();
// }

@ -0,0 +1,82 @@
#ifndef IBM_TERMINAL_H
#define IBM_TERMINAL_H
#include "quantum.h"
void matrix_init_user(void);
/*
* IBM Terminal keyboard 6110345(122keys)/1392595(102keys)
* http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M
* http://www.seasip.info/VintagePC/ibm_1391406.html
*
* Keymap array:
* 8 bytes
* +---------+
* 0| |
* :| | 0x00-0x87
* ;| |
* 17| |
* +---------+
*/
#define KEYMAP( \
K08,K10,K18,K20,K28,K30,K38,K40,K48,K50,K57,K5F, \
K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, \
\
K05,K06, K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
K04,K0C, K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \
K03,K0B, K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K63, K6B,K73,K74,K7B, \
K83,K0A, K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K61,K62,K6A, K69,K72,K7A,K79, \
K01,K09, K11, K19, K29, K39, K58, K60, K68,K70,K71,K78 \
) { \
{ KC_NO, K01, KC_NO, K03, K04, K05, K06, K07 }, \
{ K08, K09, K0A, K0B, K0C, K0D, K0E, K0F }, \
{ K10, K11, K12, K13, K14, K15, K16, K17 }, \
{ K18, K19, K1A, K1B, K1C, K1D, K1E, K1F }, \
{ K20, K21, K22, K23, K24, K25, K26, K27 }, \
{ K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \
{ K30, K31, K32, K33, K34, K35, K36, K37 }, \
{ K38, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \
{ K40, K41, K42, K43, K44, K45, K46, K47 }, \
{ K48, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
{ K50, K51, K52, K53, K54, K55, K56, K57 }, \
{ K58, K59, K5A, K5B, K5C, K5D, K5E, K5F }, \
{ K60, K61, K62, K63, K64, K65, K66, K67 }, \
{ K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
{ K70, K71, K72, K73, K74, K75, K76, K77 }, \
{ K78, K79, K7A, K7B, K7C, K7D, K7E, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, K83, K84, KC_NO, KC_NO, KC_NO,}, \
}
/*
* IBM Terminal keyboard 1399625, 101-key
*/
#define KEYMAP_101( \
K08, K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, K57,K5F,K62, \
\
K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5C, K64,K65,K6D, K6C,K75,K7D, \
K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K7C, \
K12, K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, K63, K69,K72,K7A, \
K11, K19, K29, K39, K58, K61,K60,K6A, K70, K71,K79 \
) { \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K07 }, \
{ K08, KC_NO, KC_NO, KC_NO, KC_NO, K0D, K0E, K0F }, \
{ KC_NO, K11, K12, KC_NO, K14, K15, K16, K17 }, \
{ KC_NO, K19, K1A, K1B, K1C, K1D, K1E, K1F }, \
{ KC_NO, K21, K22, K23, K24, K25, K26, K27 }, \
{ KC_NO, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \
{ KC_NO, K31, K32, K33, K34, K35, K36, K37 }, \
{ KC_NO, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \
{ KC_NO, K41, K42, K43, K44, K45, K46, K47 }, \
{ KC_NO, K49, K4A, K4B, K4C, K4D, K4E, K4F }, \
{ KC_NO, KC_NO, K52, KC_NO, K54, K55, K56, K57 }, \
{ K58, K59, K5A, K5B, K5C, KC_NO, K5E, K5F }, \
{ K60, K61, K62, K63, K64, K65, K66, K67 }, \
{ KC_NO, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \
{ K70, K71, K72, K73, K74, K75, K76, K77 }, \
{ KC_NO, K79, K7A, KC_NO, K7C, K7D, K7E, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, K84, KC_NO, KC_NO, KC_NO,}, \
}
#endif

@ -0,0 +1,27 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
UNICODEMAP_ENABLE ?= yes
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PS2_USE_USART ?= yes
API_SYSEX_ENABLE ?= no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../../Makefile
endif

@ -0,0 +1,6 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#endif

@ -0,0 +1,69 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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 <stdint.h>
#include <stdbool.h>
#include "keycode.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "ibm_terminal.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Layer 0
KEYMAP(
KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24,
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_PSCR,KC_ESC, KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL, KC_NO, KC_BSPC, KC_INS, KC_HOME,KC_PGUP, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS,
KC_SLCK,KC_INT4, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC, KC_NO, KC_DEL, KC_END, KC_PGDN, KC_P7, KC_P8, KC_P9, KC_PPLS,
KC_PAUS,KC_INT5, KC_LCTL,KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_BSLS,KC_ENT, KC_UP, KC_P4, KC_P5, KC_P6, KC_PCMM,
KC_APP, KC_INT6, KC_LSFT,KC_LSFT,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_NO, KC_RSFT, KC_LEFT,KC_INT2,KC_RGHT, KC_P1, KC_P2, KC_P3, KC_PENT,
KC_RGUI,KC_LGUI, KC_LCTL, KC_LALT, KC_SPC, KC_LGUI, KC_GRV, KC_DOWN, KC_NO, KC_P0, KC_PDOT,KC_NO
),
/* 101-key keymaps
*/
/* 0: default
* ,---. ,---------------. ,---------------. ,---------------. ,-----------.
* |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
* `---' `---------------' `---------------' `---------------' `-----------'
* ,-----------------------------------------------------------. ,-----------. ,---------------.
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
* |-----------------------------------------------------------| |-----------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
* |-----------------------------------------------------------| `-----------' |-----------| +|
* |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
* |-----------------------------------------------------------| ,---. |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
* |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| |
* `----' `---------------------------------------' `----' `-----------' `---------------'
*/
/*
KEYMAP_101(
KC_ESC, 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_PSCR,KC_SLCK, KC_BRK,
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,KC_MINS, KC_EQL,KC_BSPC, KC_INS,KC_HOME,KC_PGUP, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,KC_LBRC,KC_RBRC,KC_BSLS, KC_DEL, KC_END,KC_PGDN, KC_P7, KC_P8, KC_P9,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6,KC_PPLS,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT,KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3,
KC_LCTL, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT,KC_DOWN,KC_RGHT, KC_P0, KC_PDOT,KC_PENT
),
*/
};

@ -0,0 +1,27 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
UNICODEMAP_ENABLE ?= yes
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PS2_USE_USART ?= yes
API_SYSEX_ENABLE ?= no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../../Makefile
endif

@ -0,0 +1,6 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#endif

@ -0,0 +1,312 @@
/*
Copyright 2016 Priyadi Iman Nurcahyo <priyadi@priyadi.net>
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 "keycode.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "ibm_terminal.h"
#include "action_layer.h"
// Fillers to make layering clearer
#define _______ KC_TRNS
#define XXXXXXX KC_NO
enum layers {
QWE, // qwerty
COL, // colemak
WOR, // workman
DVO, // dvorak
MOU, // mouse keys
EMO, // emoji
SYS, // system
};
enum keycodes {
// default layout switcher
LAY_QWE = SAFE_RANGE,
LAY_COL,
LAY_WOR,
LAY_DVO,
// layer switchers
LYR_SYS,
LYR_EMO,
// os switchers
OS_LIN,
OS_WIN,
OS_MAC,
};
// unicode map
enum unicode_name {
GRIN, // grinning face 😊
TJOY, // tears of joy 😂
SMILE, // grining face with smiling eyes 😁
HEART, // heart ❤
EYERT, // smiling face with heart shaped eyes 😍
CRY, // crying face 😭
SMEYE, // smiling face with smiling eyes 😊
UNAMU, // unamused 😒
KISS, // kiss 😘
HART2, // two hearts 💕
WEARY, // weary 😩
OKHND, // ok hand sign 👌
PENSV, // pensive 😔
SMIRK, // smirk 😏
RECYC, // recycle ♻
WINK, // wink 😉
THMUP, // thumb up 👍
THMDN, // thumb down 👎
PRAY, // pray 🙏
PHEW, // relieved 😌
MUSIC, // musical notes
FLUSH, // flushed 😳
CELEB, // celebration 🙌
CRY2, // crying face 😢
COOL, // smile with sunglasses 😎
NOEVS, // see no evil
NOEVH, // hear no evil
NOEVK, // speak no evil
POO, // pile of poo
EYES, // eyes
VIC, // victory hand
BHART, // broken heart
SLEEP, // sleeping face
SMIL2, // smiling face with open mouth & sweat
HUNRD, // 100
CONFU, // confused
TONGU, // face with tongue & winking eye
DISAP, // disappointed
YUMMY, // face savoring delicious food
CLAP, // hand clapping
FEAR, // face screaming in fear
HORNS, // smiling face with horns
HALO, // smiling face with halo
BYE, // waving hand
SUN, // sun
MOON, // moon
SKULL, // skull
};
const uint32_t PROGMEM unicode_map[] = {
[GRIN] = 0x1F600,
[TJOY] = 0x1F602,
[SMILE] = 0x1F601,
[HEART] = 0x2764,
[EYERT] = 0x1f60d,
[CRY] = 0x1f62d,
[SMEYE] = 0x1F60A,
[UNAMU] = 0x1F612,
[KISS] = 0x1F618,
[HART2] = 0x1F495,
[WEARY] = 0x1F629,
[OKHND] = 0x1F44C,
[PENSV] = 0x1F614,
[SMIRK] = 0x1F60F,
[RECYC] = 0x267B,
[WINK] = 0x1F609,
[THMUP] = 0x1F44D,
[THMDN] = 0x1F44E,
[PRAY] = 0x1F64F,
[PHEW] = 0x1F60C,
[MUSIC] = 0x1F3B6,
[FLUSH] = 0x1F633,
[CELEB] = 0x1F64C,
[CRY2] = 0x1F622,
[COOL] = 0x1F60E,
[NOEVS] = 0x1F648,
[NOEVH] = 0x1F649,
[NOEVK] = 0x1F64A,
[POO] = 0x1F4A9,
[EYES] = 0x1F440,
[VIC] = 0x270C,
[BHART] = 0x1F494,
[SLEEP] = 0x1F634,
[SMIL2] = 0x1F605,
[HUNRD] = 0x1F4AF,
[CONFU] = 0x1F615,
[TONGU] = 0x1F61C,
[DISAP] = 0x1F61E,
[YUMMY] = 0x1F60B,
[CLAP] = 0x1F44F,
[FEAR] = 0x1F631,
[HORNS] = 0x1F608,
[HALO] = 0x1F607,
[BYE] = 0x1F44B,
[SUN] = 0x2600,
[MOON] = 0x1F314,
[SKULL] = 0x1F480,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* qwerty */
[QWE] = KEYMAP(
KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_PSCR, KC_SLCK, KC_PAUS,
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
MO(EMO), MO(SYS), KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, XXXXXXX, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
KC_MNXT, KC_VOLU, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, XXXXXXX, KC_DEL, KC_END, KC_PGDN, KC_P7, KC_P8, KC_P9, KC_PPLS,
KC_MPLY, KC_MUTE, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_ENT, KC_UP, KC_P4, KC_P5, KC_P6, KC_PCMM,
KC_MPRV, KC_VOLD, KC_LSFT, KC_GRV, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, KC_RSFT, KC_LEFT, TG(MOU), KC_RGHT, KC_P1, KC_P2, KC_P3, KC_PENT,
KC_LGUI, KC_APP, KC_LCTL, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_DOWN, XXXXXXX, KC_P0, KC_PDOT, XXXXXXX
),
/* colemak */
[COL] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_LBRC, KC_RBRC, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* workman */
[WOR] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_Q, KC_D, KC_R, KC_W, KC_B, KC_J, KC_F, KC_U, KC_P, KC_SCLN, KC_LBRC, KC_RBRC, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_A, KC_S, KC_H, KC_T, KC_G, KC_Y, KC_N, KC_E, KC_O, KC_I, KC_QUOT, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, KC_Z, KC_X, KC_M, KC_C, KC_V, KC_K, KC_L, KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* dvorak */
[DVO] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LBRC, KC_RBRC, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH, KC_EQL, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* system */
[SYS] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, LAY_QWE, OS_WIN, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, LAY_DVO, _______, _______, _______, _______, LAY_WOR, OS_LIN, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, LAY_COL, _______, _______, _______, OS_MAC, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* mouse keys */
[MOU] = KEYMAP(
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, KC_BTN4, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_U, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, KC_BTN5, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_L, _______, KC_MS_R, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
KC_BTN1, KC_BTN3, KC_BTN2, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_D, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
),
/* emoji */
[EMO] = KEYMAP(
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY), X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV),XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN), X(HEART),X(BYE), X(KISS), X(CELEB),X(COOL), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,X(SLEEP),X(CLAP), X(CRY), X(VIC), X(BHART),X(SUN), X(SMEYE),X(WINK), X(MOON), X(CONFU), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
),
/*
[XXX] = KEYMAP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
*/
};
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) {
/* layout switcher */
case LAY_QWE:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<QWE);
}
return false;
break;
case LAY_COL:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<COL);
}
return false;
break;
case LAY_WOR:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<WOR);
}
return false;
break;
case LAY_DVO:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<DVO);
}
return false;
break;
/* os switcher */
case OS_LIN:
set_unicode_input_mode(UC_LNX);
return false;
break;
case OS_WIN:
set_unicode_input_mode(UC_WINC);
return false;
break;
case OS_MAC:
set_unicode_input_mode(UC_OSX);
return false;
break;
}
return true;
}
void matrix_init_user() {
set_unicode_input_mode(UC_LNX);
}

@ -0,0 +1,33 @@
/*
Copyright 2011 Jun Wako <wakojun@gmail.com>
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 "stdint.h"
#include "ps2.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
uint8_t ps2_led = 0;
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
ps2_led |= (1<<PS2_LED_SCROLL_LOCK);
if (usb_led & (1<<USB_LED_NUM_LOCK))
ps2_led |= (1<<PS2_LED_NUM_LOCK);
if (usb_led & (1<<USB_LED_CAPS_LOCK))
ps2_led |= (1<<PS2_LED_CAPS_LOCK);
ps2_host_set_led(ps2_led);
}

@ -0,0 +1,237 @@
/*
Copyright 2011 Jun Wako <wakojun@gmail.com>
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 <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "util.h"
#include "debug.h"
#include "ps2.h"
#include "matrix.h"
#define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
#define print_matrix_header() print("\nr/c 01234567\n")
#define matrix_bitpop(i) bitpop(matrix[i])
#define ROW_SHIFTER ((uint8_t)1)
static void matrix_make(uint8_t code);
static void matrix_break(uint8_t code);
/*
* Matrix Array usage:
* 'Scan Code Set 3' is assigned into 17x8 cell matrix.
*
* 8bit wide
* +---------+
* 0| |
* :| | 0x00-0x87
* ;| |
* 17| |
* +---------+
*/
static uint8_t matrix[MATRIX_ROWS];
#define ROW(code) (code>>3)
#define COL(code) (code&0x07)
__attribute__ ((weak))
void matrix_init_user(void) {
}
void matrix_init(void)
{
debug_enable = true;
//debug_matrix = true;
//debug_keyboard = true;
//debug_mouse = false;
ps2_host_init();
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
matrix_init_user();
return;
}
uint8_t matrix_scan(void)
{
// scan code reading states
static enum {
RESET,
RESET_RESPONSE,
KBD_ID0,
KBD_ID1,
CONFIG,
READY,
F0,
} state = RESET;
uint8_t code;
if ((code = ps2_host_recv())) {
debug("r"); debug_hex(code); debug(" ");
}
switch (state) {
case RESET:
debug("wFF ");
if (ps2_host_send(0xFF) == 0xFA) {
debug("[ack]\nRESET_RESPONSE: ");
state = RESET_RESPONSE;
}
break;
case RESET_RESPONSE:
if (code == 0xAA) {
debug("[ok]\nKBD_ID: ");
state = KBD_ID0;
} else if (code) {
debug("err\nRESET: ");
state = RESET;
}
break;
// after reset receive keyboad ID(2 bytes)
case KBD_ID0:
if (code) {
state = KBD_ID1;
}
break;
case KBD_ID1:
if (code) {
debug("\nCONFIG: ");
state = CONFIG;
}
break;
case CONFIG:
debug("wF8 ");
if (ps2_host_send(0xF8) == 0xFA) {
debug("[ack]\nREADY\n");
state = READY;
}
break;
case READY:
switch (code) {
case 0x00:
break;
case 0xF0:
state = F0;
debug(" ");
break;
default: // normal key make
if (code < 0x88) {
matrix_make(code);
} else {
debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
}
state = READY;
debug("\n");
}
break;
case F0: // Break code
switch (code) {
case 0x00:
break;
default:
if (code < 0x88) {
matrix_break(code);
} else {
debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
}
state = READY;
debug("\n");
}
break;
}
return 1;
}
inline
uint8_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
inline
static void matrix_make(uint8_t code)
{
if (!matrix_is_on(ROW(code), COL(code))) {
matrix[ROW(code)] |= 1<<COL(code);
}
}
inline
static void matrix_break(uint8_t code)
{
if (matrix_is_on(ROW(code), COL(code))) {
matrix[ROW(code)] &= ~(1<<COL(code));
}
}
bool matrix_is_on(uint8_t row, uint8_t col)
{
return (matrix_get_row(row) & (1<<col));
}
void matrix_print(void)
{
#if (MATRIX_COLS <= 8)
print("r/c 01234567\n");
#elif (MATRIX_COLS <= 16)
print("r/c 0123456789ABCDEF\n");
#elif (MATRIX_COLS <= 32)
print("r/c 0123456789ABCDEF0123456789ABCDEF\n");
#endif
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
#if (MATRIX_COLS <= 8)
xprintf("%02X: %08b%s\n", row, bitrev(matrix_get_row(row)),
#elif (MATRIX_COLS <= 16)
xprintf("%02X: %016b%s\n", row, bitrev16(matrix_get_row(row)),
#elif (MATRIX_COLS <= 32)
xprintf("%02X: %032b%s\n", row, bitrev32(matrix_get_row(row)),
#endif
#ifdef MATRIX_HAS_GHOST
matrix_has_ghost_in_row(row) ? " <ghost" : ""
#else
""
#endif
);
}
}
#ifdef MATRIX_HAS_GHOST
__attribute__ ((weak))
bool matrix_has_ghost_in_row(uint8_t row)
{
matrix_row_t matrix_row = matrix_get_row(row);
// No ghost exists when less than 2 keys are down on the row
if (((matrix_row - 1) & matrix_row) == 0)
return false;
// Ghost occurs when the row shares column line with other row
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
if (i != row && (matrix_get_row(i) & matrix_row))
return true;
}
return false;
}
#endif

@ -0,0 +1,72 @@
# MCU name
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
UNICODEMAP_ENABLE ?= yes
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PS2_USE_USART ?= yes
API_SYSEX_ENABLE ?= n
CUSTOM_MATRIX = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
SRC = matrix.c led.c

@ -1,10 +1,11 @@
#ifndef KEYBOARDS_ERGODOX_CONFIG_H_
#define KEYBOARDS_ERGODOX_CONFIG_H_
#define MOUSEKEY_DELAY 100
#define MOUSEKEY_INTERVAL 20
#define MOUSEKEY_MAX_SPEED 3
#define MOUSEKEY_TIME_TO_MAX 10
#define MOUSEKEY_DELAY 0
#define MOUSEKEY_TIME_TO_MAX 5
#define MOUSEKEY_MAX_SPEED 2
#define MOUSEKEY_WHEEL_DELAY 0
#define TAPPING_TOGGLE 1

@ -2,23 +2,3 @@
#include "debug.h"
#include "action_layer.h"
// swap-hands action needs a matrix to define the swap
const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{0,13}, {1,13}, {2,13}, {3,13}, {4,13}, {5,13}},
{{0,12}, {1,12}, {2,12}, {3,12}, {4,12}, {5,12}},
{{0,11}, {1,11}, {2,11}, {3,11}, {4,11}, {5,11}},
{{0,10}, {1,10}, {2,10}, {3,10}, {4,10}, {5,10}},
{{0,9}, {1,9}, {2,9}, {3,9}, {4,9}, {5,9}},
{{0,8}, {1,8}, {2,8}, {3,8}, {4,8}, {5,8}},
{{0,7}, {1,7}, {2,7}, {3,7}, {4,7}, {5,7}},
/* Right hand, matrix positions */
{{0,6}, {1,6}, {2,6}, {3,6}, {4,6}, {5,6}},
{{0,5}, {1,5}, {2,5}, {3,5}, {4,5}, {5,5}},
{{0,4}, {1,4}, {2,4}, {3,4}, {4,4}, {5,4}},
{{0,3}, {1,3}, {2,3}, {3,3}, {4,3}, {5,3}},
{{0,2}, {1,2}, {2,2}, {3,2}, {4,2}, {5,2}},
{{0,1}, {1,1}, {2,1}, {3,1}, {4,1}, {5,1}},
{{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
};

@ -1,3 +1,8 @@
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
COMMAND_ENABLE = no # Commands for debug and configuration
RGBLIGHT_ENABLE ?= yes
MIDI_ENABLE ?= no
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif
endif

@ -21,6 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../config.h"
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x1307
@ -39,10 +41,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LED_BRIGHTNESS_LO 15
#define LED_BRIGHTNESS_HI 255
/* ws2812 RGB LED */
#define RGB_DI_PIN D7
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 15 // Number of LEDs
#define RGBLIGHT_HUE_STEP 12
#define RGBLIGHT_SAT_STEP 255
#define RGBLIGHT_VAL_STEP 12
#define RGB_MIDI
#define RGBW_BB_TWI
#define RGBW 1
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
#define USB_MAX_POWER_CONSUMPTION 500
/*
* Feature disable options
* These options are also useful to firmware size reduction.

@ -16,10 +16,10 @@ void matrix_init_kb(void) {
// unused pins - C7, D4, D5, D7, E6
// set as input with internal pull-ip enabled
DDRC &= ~(1<<7);
DDRD &= ~(1<<7 | 1<<5 | 1<<4);
DDRD &= ~(1<<5 | 1<<4);
DDRE &= ~(1<<6);
PORTC |= (1<<7);
PORTD |= (1<<7 | 1<<5 | 1<<4);
PORTD |= (1<<5 | 1<<4);
PORTE |= (1<<6);
ergodox_blink_all_leds();
@ -51,6 +51,10 @@ uint8_t init_mcp23018(void) {
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++;
@ -79,7 +83,30 @@ uint8_t init_mcp23018(void) {
out:
i2c_stop();
SREG=sreg_prev;
return mcp23018_status;
}
#ifdef ONEHAND_ENABLE
__attribute__ ((weak))
// swap-hands action needs a matrix to define the swap
const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
/* Left hand, matrix positions */
{{0,13}, {1,13}, {2,13}, {3,13}, {4,13}, {5,13}},
{{0,12}, {1,12}, {2,12}, {3,12}, {4,12}, {5,12}},
{{0,11}, {1,11}, {2,11}, {3,11}, {4,11}, {5,11}},
{{0,10}, {1,10}, {2,10}, {3,10}, {4,10}, {5,10}},
{{0,9}, {1,9}, {2,9}, {3,9}, {4,9}, {5,9}},
{{0,8}, {1,8}, {2,8}, {3,8}, {4,8}, {5,8}},
{{0,7}, {1,7}, {2,7}, {3,7}, {4,7}, {5,7}},
/* Right hand, matrix positions */
{{0,6}, {1,6}, {2,6}, {3,6}, {4,6}, {5,6}},
{{0,5}, {1,5}, {2,5}, {3,5}, {4,5}, {5,5}},
{{0,4}, {1,4}, {2,4}, {3,4}, {4,4}, {5,4}},
{{0,3}, {1,3}, {2,3}, {3,3}, {4,3}, {5,3}},
{{0,2}, {1,2}, {2,2}, {3,2}, {4,2}, {5,2}},
{{0,1}, {1,1}, {2,1}, {3,1}, {4,1}, {5,1}},
{{0,0}, {1,0}, {2,0}, {3,0}, {4,0}, {5,0}},
};
#endif

@ -121,7 +121,7 @@ void matrix_init(void)
matrix_scan_count = 0;
#endif
matrix_init_kb();
matrix_init_quantum();
}

@ -72,6 +72,8 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512
#
SLEEP_LED_ENABLE = no
API_SYSEX_ENABLE ?= no
RGBLIGHT_ENABLE ?= yes
ifndef QUANTUM_DIR
include ../../../Makefile

@ -38,7 +38,6 @@ void init_serial_link_hal(void) {
// Using a higher pre-scalar without flicker is possible but FTM0_MOD will need to be reduced
// Which will reduce the brightness range
#define PRESCALAR_DEFINE 0
#ifdef VISUALIZER_ENABLE
void lcd_backlight_hal_init(void) {
// Setup Backlight
SIM->SCGC6 |= SIM_SCGC6_FTM0;
@ -76,7 +75,6 @@ void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b) {
CHANNEL_GREEN.CnV = g;
CHANNEL_BLUE.CnV = b;
}
#endif
__attribute__ ((weak))
void matrix_init_user(void) {
@ -92,6 +90,10 @@ void matrix_init_kb(void) {
// runs once when the firmware starts up
matrix_init_user();
// The backlight always has to be initialized, otherwise it will stay lit
#ifndef VISUALIZER_ENABLE
lcd_backlight_hal_init();
#endif
}
void matrix_scan_kb(void) {

@ -21,29 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
void led_set(uint8_t usb_led) {
// The LCD backlight functionality conflicts with this simple
// red backlight
#if !defined(LCD_BACKLIGHT_ENABLE) && defined(STATUS_LED_ENABLE)
// PTC1: LCD Backlight Red(0:on/1:off)
GPIOC->PDDR |= (1<<1);
PORTC->PCR[1] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
GPIOC->PCOR |= (1<<1);
} else {
GPIOC->PSOR |= (1<<1);
}
#elif !defined(LCD_BACKLIGHT_ENABLE)
//TODO: Add led emulation if there's no customized visualization
(void)usb_led;
GPIOC->PDDR |= (1<<1);
PORTC->PCR[1] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1);
GPIOC->PSOR |= (1<<1);
GPIOC->PDDR |= (1<<2);
PORTC->PCR[2] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1);
GPIOC->PSOR |= (1<<2);
GPIOC->PDDR |= (1<<3);
PORTC->PCR[3] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1);
GPIOC->PSOR |= (1<<3);
#else
(void)usb_led;
#endif
}

@ -63,6 +63,8 @@ VISUALIZER_ENABLE ?= no #temporarily disabled to make everything compile
LCD_ENABLE ?= yes
LED_ENABLE ?= yes
LCD_BACKLIGHT_ENABLE ?= yes
MIDI_ENABLE = no
RGBLIGHT_ENABLE = no
ifndef QUANTUM_DIR
include ../../../Makefile

@ -1,3 +1,47 @@
<!-- -*- mode: markdown; fill-column: 8192 -*- -->
## v1.10
*2016-12-28*
### Miscellaneous
* `µ` can now be entered with UCIS.
* `™` can now be entered with UCIS.
### Tools
* `tools/hid-commands` can now find Banshee, and prefers it over Kodi.
* `tools/hid-commands` can now find Chrome too, not juts Chromium.
## v1.9
*2016-10-16*
### Overall changes
* `F12` was replaced by an `Fx` key, that activate the **Media** layer as a one-shot layer, and also `Alt` as a one-shot modifier.
### Base layer changes
* The `Media Stop` key is now a tap-dance key, and resets the device for programming on the fourth tap.
### Miscellaneous
* `π` can now be entered with UCIS.
* `🐁` can now be entered with UCIS.
### Tools
* The `tools/layer-notify` tool was removed, it was an example, which I don't use.
#### `tools/hid-commands`
* Now looks at the `DISABLE_APPSEL_START` environment value, and does not display an AppSel notification if it is non-empty.
* Will attempt to re-program the keyboard when receiving a `reflash` command.
* No longer tries to select Emacs 24 on `APPSEL_EMACS`, rather, it goes for any Emacs.
* The `APPSEL_MUSIC` command now includes Kodi in the list too, as the last choice.
## v1.8
*2016-10-03*
@ -13,7 +57,7 @@
### Miscellaneous
* Fixed the [Steno](#steno-layer) toggle key.
* Fixed the **Steno** toggle key.
## v1.7
@ -21,9 +65,9 @@
### Overall changes
* The number row has been completely rearranged on both the [Base](#base-layer) and the [ADORE](#adore-layer) layers.
* The number row has been completely rearranged on both the **Base** and the **ADORE** layers.
* The number/function key behavior was changed: function keys are now on the **Media**.
* The `:`/`;` and `-`/`_` keys were put back to their thumb position on the bottom row, on both the [Base](#base-layer) and [ADORE](#adore-layer) layers.
* The `:`/`;` and `-`/`_` keys were put back to their thumb position on the bottom row, on both the **Base** and **ADORE** layers.
* The bottom large keys on the inner side of each half now function as [tmux](http://tmux.github.io/) keys: the left to send the prefix, the right to send the `display-panes` key. The left also doubles as a GNU screen prefix key, and sends `C-a` when double tapped.
* A number of functions, such as the **AppSel** layer, now require the `hid-commands` tool to be running, with the output of `hid_listen` being piped to it.
@ -59,13 +103,13 @@
### Base layer changes
* The parentheses & bracket keys have been merged: tapping them results in `[` or `{` (if it was shifted), double tapping leads to `(`.
* The `:;` and `-_` keys are now available on the base layer, on their [ADORE](#adore-layer) location, too, just below `[{(`/`]})`.
* The `:;` and `-_` keys are now available on the base layer, on their **ADORE** location, too, just below `[{(`/`]})`.
* The `Apps` key has been replaced by `F12`.
* The `-`/`_` is no longer a tap-dance key.
### ADORE layer changes
* Adjustments were made to the [ADORE](#adore-layer) layer, to separate some inconvenient combinations.
* Adjustments were made to the **ADORE** layer, to separate some inconvenient combinations.
### Miscellaneous changes
@ -84,9 +128,9 @@
* The **1HAND** layer has been removed.
* A `Delete` key is now available on the right thumb cluster.
* The [ADORE](#adore-layer) layer received a major update, see the layout image above.
* It is now possible to enable automatic logging for the [ADORE](#adore-layer) layer, by setting the `ADORE_AUTOLOG` makefile variable to `yes` when compiling the keymap. It is off by default.
* The `~` key and the `Media Next/Prev` key have been swapped on the [base layer](#base-layer).
* The **ADORE** layer received a major update, see the layout image above.
* It is now possible to enable automatic logging for the **ADORE** layer, by setting the `ADORE_AUTOLOG` makefile variable to `yes` when compiling the keymap. It is off by default.
* The `~` key and the `Media Next/Prev` key have been swapped on the **Base** layer.
* On the **ARROW** layer, `Backspace` has been replaced by `Enter`.
* There is some experimental support for entering Unicode symbols.
@ -104,33 +148,33 @@
*2016-07-06*
* Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a [heatmap](#heatmap) out of the logs.
* The arrow and navigation keys were rearranged again, and now require an additional key being held to activate. See the [base layer](#base-layer) for an image that shows where arrows are.
* The **experimental** layer has been redone, and is now called [ADORE](#adore-layer), and as such, can be enabled by `LEAD a` now.
* Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a *heatmap* out of the logs.
* The arrow and navigation keys were rearranged again, and now require an additional key being held to activate. See the **Base** layer for an image that shows where arrows are.
* The **experimental** layer has been redone, and is now called **ADORE**, and as such, can be enabled by `LEAD a` now.
* Switching between Dvorak and ADORE is now persisted into EEPROM, and survives a reboot.
## v1.2
*2016-06-22*
* The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with [certain operating systems](#using-on-windows).
* The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with certain operating systems.
* The `:;` key has changed behaviour: to access the `;` symbol, the key needs to be double-tapped, instead of shifted.
* The `=` and `\` keys were swapped, `=` moved to the home row, on both the [base](#base-layer) and the **experimental** layers.
* The `=` and `\` keys were swapped, `=` moved to the home row, on both the **Base** and the **experimental** layers.
* The arrow and navigation keys were redone, they are now more accessible, but the navigation keys require an extra tap to access.
* The **Emacs** layer is gone, replaced by a simplified **navigation and media** layer.
* `LEAD v` types the firmware version, and the keymap version.
* On the **experimental** layer, the `L` and `Q`, and the `K` and `G` keys were swapped.
* The [Steno](#steno-layer) layer gained a few more `#` and `*` keys, to make it easier on my fingers.
* The **Steno** layer gained a few more `#` and `*` keys, to make it easier on my fingers.
## v1.1
*2016-06-14*
* The keyboard starts in NKRO mode, bootmagic and other things are disabled.
* A [Steno](#steno-layer) layer was added, to be used with Plover.
* A **Steno** layer was added, to be used with Plover.
* An **experimental** layer was added, something halfway between Dvorak and Capewell-Dvorak. A work in progress.
* `LEAD y` types `\o/`.
* Some keys on the [Base](#base-layer) layer have been moved around:
* Some keys on the **Base** layer have been moved around:
- `?` moved to the left pinky, left of `Q`.
- `=` shifted one row down, but `F11` stayed where it was.
- `-` on the left half was replaced by `Tab`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

@ -64,6 +64,9 @@ enum {
A_8,
A_9,
A_0,
// Fx
Fx,
};
/* Fn keys */
@ -86,14 +89,13 @@ enum {
CT_RBP,
CT_TMUX,
CT_TPS,
CT_SR,
};
/* States & timers */
uint16_t gui_timer = 0;
uint16_t kf_timers[12];
#if KEYLOGGER_ENABLE
# ifdef AUTOLOG_ENABLE
bool log_enable = true;
@ -103,6 +105,7 @@ bool log_enable = false;
#endif
bool time_travel = false;
bool skip_leds = false;
static uint8_t is_adore = 0;
@ -113,13 +116,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Base Layer
*
* ,-----------------------------------------------------. ,-----------------------------------------------------.
* | Next/Prev | 9 | 7 @ | 5 * | 3 ^ | 1 $ | F11 | | F12 | 0 % | 2 ! | 4 # | 6 & | 8 | Plover |
* | Next/Prev | 9 | 7 @ | 5 * | 3 ^ | 1 $ | F11 | | Fx | 0 % | 2 ! | 4 # | 6 & | 8 | Plover |
* |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
* | ~ | ' | , | . | P | Y | ( | | ) | F | G | C | R | L | \ |
* |-----------+------+------+------+------+------| [ | | ] |------+------+------+------+------+-----------|
* | Tab/ARROW | A | O | E | U | I |------| |------| D | H | T | N | S | = / Arrow |
* |-----------+------+------+------+------+------| tmux | | tmux |------+------+------+------+------+-----------|
* | Play/Pause| / | Q | J | K | X | | | Pane | B | M | W | V | Z | Stop |
* | Play/Pause| / | Q | J | K | X | | | Pane | B | M | W | V | Z | Stop/Reset|
* `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
* | | | | | : | | - | | | | |
* `-----------------------------------' `-----------------------------------'
@ -144,10 +147,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_BSPC,F(F_SFT),KC_ESC
// right hand
,KC_F12 ,M(A_0) ,M(A_2) ,M(A_4) ,M(A_6) ,M(A_8) ,M(A_PLVR)
,M(Fx) ,M(A_0) ,M(A_2) ,M(A_4) ,M(A_6) ,M(A_8) ,M(A_PLVR)
,TD(CT_RBP),KC_F ,KC_G ,KC_C ,KC_R ,KC_L ,KC_BSLS
,KC_D ,KC_H ,KC_T ,KC_N ,KC_S ,KC_EQL
,TD(CT_TPS),KC_B ,KC_M ,KC_W ,KC_V ,KC_Z ,KC_MSTP
,TD(CT_TPS),KC_B ,KC_M ,KC_W ,KC_V ,KC_Z ,TD(CT_SR)
,KC_MINS ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,OSL(NMDIA),KC_DEL
@ -158,7 +161,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 1: Adore layer
*
* ,-----------------------------------------------------. ,-----------------------------------------------------.
* | Play/Pause| 9 | 7 @ | 5 * | 3 ^ | 1 $ | F11 | | F12 | 0 % | 2 ! | 4 # | 6 & | 8 | Plover |
* | Play/Pause| 9 | 7 @ | 5 * | 3 ^ | 1 $ | F11 | | Fx | 0 % | 2 ! | 4 # | 6 & | 8 | Plover |
* |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
* | \ | X | W | C | H | F | ( | | ) | M | G | L | P | / | `~ |
* |-----------+------+------+------+------+------| [ | | ] |------+------+------+------+------+-----------|
@ -189,7 +192,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_BSPC,F(F_SFT),KC_ESC
// right hand
,KC_F12 ,M(A_0) ,M(A_2) ,M(A_4) ,M(A_6) ,M(A_8) ,M(A_PLVR)
,M(Fx) ,M(A_0) ,M(A_2) ,M(A_4) ,M(A_6) ,M(A_8) ,M(A_PLVR)
,TD(CT_RBP),KC_M ,KC_G ,KC_L ,KC_P ,KC_SLSH ,KC_GRV
,KC_D ,KC_R ,KC_T ,KC_N ,KC_S ,KC_EQL
,TD(CT_TPS),KC_B ,KC_K ,KC_V ,KC_Y ,KC_J ,KC_NO
@ -342,7 +345,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 5: Navigation & Media layer
*
* ,-----------------------------------------------------. ,-----------------------------------------------------.
* | | F9 | F7 | F5 | F3 | F1 | | |ScrLCK| F10 | F2 | F4 | F6 | F8 | |
* | | F9 | F7 | F5 | F3 | F1 |ScrLCK| | | F10 | F2 | F4 | F6 | F8 | |
* |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
* | | | | | | | | | | | | | | | |
* |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------|
@ -362,7 +365,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[NMDIA] = KEYMAP(
// left hand
KC_NO ,KC_F9 ,KC_F7 ,KC_F5 ,KC_F3 ,KC_F1 ,KC_NO
KC_NO ,KC_F9 ,KC_F7 ,KC_F5 ,KC_F3 ,KC_F1 ,LGUI(KC_L)
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
@ -372,7 +375,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_NO ,KC_NO ,KC_TRNS
// right hand
,LGUI(KC_L),KC_F10 ,KC_F2 ,KC_F4 ,KC_F6 ,KC_F8 ,KC_NO
,KC_TRNS ,KC_F10 ,KC_F2 ,KC_F4 ,KC_F6 ,KC_F8 ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
@ -611,6 +614,17 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
toggle_steno(record->event.pressed);
break;
/* Fx */
case Fx:
if (record->event.pressed) {
set_oneshot_mods (MOD_LALT);
layer_on (NMDIA);
set_oneshot_layer (NMDIA, ONESHOT_START);
} else {
clear_oneshot_layer_state (ONESHOT_PRESSED);
}
break;
/* GUI & AppSel */
case A_GUI:
if (record->event.pressed) {
@ -770,7 +784,7 @@ static void ang_tap_dance_tmux_pane_select (qk_tap_dance_state_t *state, void *u
if (state->count >= 2) {
kc = KC_Z;
}
register_code(KC_LALT);
register_code(KC_SPC);
unregister_code(KC_SPC);
@ -780,6 +794,56 @@ static void ang_tap_dance_tmux_pane_select (qk_tap_dance_state_t *state, void *u
unregister_code(kc);
}
static void
_td_sr_each (qk_tap_dance_state_t *state, void *user_data) {
skip_leds = true;
switch (state->count) {
case 1:
ergodox_right_led_3_on ();
break;
case 2:
ergodox_right_led_2_on ();
break;
case 3:
ergodox_right_led_1_on ();
break;
case 4:
ergodox_right_led_3_off ();
wait_ms (50);
ergodox_right_led_2_off ();
wait_ms (50);
ergodox_right_led_1_off ();
break;
}
}
static void
_td_sr_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code (KC_MSTP);
}
if (state->count >= 4) {
uprintf("CMD:reflash\n");
wait_ms (1000);
reset_keyboard ();
reset_tap_dance (state);
}
}
static void
_td_sr_reset (qk_tap_dance_state_t *state, void *user_data) {
ergodox_right_led_1_off ();
wait_ms (50);
ergodox_right_led_2_off ();
wait_ms (50);
ergodox_right_led_3_off ();
if (state->count == 1) {
unregister_code (KC_MSTP);
}
}
qk_tap_dance_action_t tap_dance_actions[] = {
[CT_CLN] = ACTION_TAP_DANCE_DOUBLE (KC_COLN, KC_SCLN)
,[CT_TA] = {
@ -790,77 +854,75 @@ qk_tap_dance_action_t tap_dance_actions[] = {
,[CT_RBP] = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, KC_RPRN)
,[CT_TMUX]= ACTION_TAP_DANCE_FN (ang_tap_dance_tmux_finished)
,[CT_TPS] = ACTION_TAP_DANCE_FN (ang_tap_dance_tmux_pane_select)
,[CT_SR] = ACTION_TAP_DANCE_FN_ADVANCED (_td_sr_each, _td_sr_finished, _td_sr_reset)
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
static uint32_t prev_layer_state;
uint8_t layer = biton32(layer_state);
bool is_arrow = false;
static char *layer_lookup[] = {"Dvorak", "ADORE", "Arrows", "AppSel", "Hungarian", "Nav/Media", "Plover"};
if (layer_state != prev_layer_state) {
prev_layer_state = layer_state;
if (layer_lookup[layer])
uprintf("LAYER: %s\n", layer_lookup[layer]);
}
if (gui_timer && timer_elapsed (gui_timer) > TAPPING_TERM)
unregister_code (KC_LGUI);
if (layer == HUN) {
ergodox_right_led_2_on();
ergodox_right_led_3_on();
} else if (layer == NMDIA) {
ergodox_right_led_1_on();
ergodox_right_led_2_on();
} else if (layer == PLVR) {
ergodox_right_led_1_on ();
ergodox_right_led_2_on ();
ergodox_right_led_3_on ();
} else if (layer == ADORE) {
ergodox_right_led_1_on ();
ergodox_right_led_2_on ();
ergodox_right_led_3_on ();
ergodox_right_led_2_set (LED_BRIGHTNESS_HI);
if (!skip_leds) {
if (layer == HUN) {
ergodox_right_led_2_on();
ergodox_right_led_3_on();
} else if (layer == NMDIA) {
ergodox_right_led_1_on();
ergodox_right_led_2_on();
} else if (layer == PLVR) {
ergodox_right_led_1_on ();
ergodox_right_led_2_on ();
ergodox_right_led_3_on ();
} else if (layer == ADORE) {
ergodox_right_led_1_on ();
ergodox_right_led_2_on ();
ergodox_right_led_3_on ();
ergodox_right_led_2_set (LED_BRIGHTNESS_HI);
}
}
if (layer_state & (1UL << ARRW)) {
ergodox_right_led_1_on ();
ergodox_right_led_3_on ();
if (!skip_leds) {
ergodox_right_led_1_on ();
ergodox_right_led_3_on ();
}
is_arrow = true;
}
if (keyboard_report->mods & MOD_BIT(KC_LSFT) ||
((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_1_set (LED_BRIGHTNESS_HI);
ergodox_right_led_1_on ();
} else {
ergodox_right_led_1_set (LED_BRIGHTNESS_LO);
if (layer != NMDIA && layer != PLVR && layer != ADORE && !is_arrow)
ergodox_right_led_1_off ();
}
if (!skip_leds) {
if (keyboard_report->mods & MOD_BIT(KC_LSFT) ||
((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_1_set (LED_BRIGHTNESS_HI);
ergodox_right_led_1_on ();
} else {
ergodox_right_led_1_set (LED_BRIGHTNESS_LO);
if (layer != NMDIA && layer != PLVR && layer != ADORE && !is_arrow)
ergodox_right_led_1_off ();
}
if (keyboard_report->mods & MOD_BIT(KC_LALT) ||
((get_oneshot_mods() & MOD_BIT(KC_LALT)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_2_set (LED_BRIGHTNESS_HI);
ergodox_right_led_2_on ();
} else {
ergodox_right_led_2_set (LED_BRIGHTNESS_LO);
if (layer != HUN && layer != NMDIA && layer != PLVR && layer != ADORE)
ergodox_right_led_2_off ();
}
if (keyboard_report->mods & MOD_BIT(KC_LALT) ||
((get_oneshot_mods() & MOD_BIT(KC_LALT)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_2_set (LED_BRIGHTNESS_HI);
ergodox_right_led_2_on ();
} else {
ergodox_right_led_2_set (LED_BRIGHTNESS_LO);
if (layer != HUN && layer != NMDIA && layer != PLVR && layer != ADORE)
ergodox_right_led_2_off ();
}
if (keyboard_report->mods & MOD_BIT(KC_LCTRL) ||
((get_oneshot_mods() & MOD_BIT(KC_LCTRL)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_3_set (LED_BRIGHTNESS_HI);
ergodox_right_led_3_on ();
} else {
ergodox_right_led_3_set (LED_BRIGHTNESS_LO);
if (layer != HUN && layer != PLVR && layer != ADORE && !is_arrow)
ergodox_right_led_3_off ();
if (keyboard_report->mods & MOD_BIT(KC_LCTRL) ||
((get_oneshot_mods() & MOD_BIT(KC_LCTRL)) && !has_oneshot_mods_timed_out())) {
ergodox_right_led_3_set (LED_BRIGHTNESS_HI);
ergodox_right_led_3_on ();
} else {
ergodox_right_led_3_set (LED_BRIGHTNESS_LO);
if (layer != HUN && layer != PLVR && layer != ADORE && !is_arrow)
ergodox_right_led_3_off ();
}
}
LEADER_DICTIONARY() {
@ -974,7 +1036,11 @@ const qk_ucis_symbol_t ucis_symbol_table[] = UCIS_TABLE
UCIS_SYM("snowman", 0x2603),
UCIS_SYM("coffee", 0x2615),
UCIS_SYM("heart", 0x2764),
UCIS_SYM("bolt", 0x26a1)
UCIS_SYM("bolt", 0x26a1),
UCIS_SYM("pi", 0x03c0),
UCIS_SYM("mouse", 0x1f401),
UCIS_SYM("micro", 0x00b5),
UCIS_SYM("tm", 0x2122)
);
bool process_record_user (uint16_t keycode, keyrecord_t *record) {

@ -43,6 +43,7 @@ At its core, this is a Dvorak layout, with some minor changes. The more interest
* The `GUI` key is special, because when I double-tap it, it sends `GUI + w`, which pops up an application selector. It also switches to a one-shot layer, where the number row on the left half turns into app selector macros, for the most common things I usually want to switch to. Otherwise it behaves as on a normal layout.
* The `ESC` key also doubles as a one-shot cancel key: if tapped while any of the one-shot modifiers are in-flight (as in, single-tapped, and not expired yet), it cancels all one-shot modifiers. It also cancels the **Hun** layer, if active. Otherwise it sends the usual keycode.
* The **Media** and **Hun** layer keys are one-shot, the **STENO** key is a toggle.
* The **Fx** key is one-shot, and activates the **Media** layer, along with a one-shot `Alt`.
* When holding the `Tab`/**Arrow** key, the arrow layer activates while the key is held. Tapping the key produces the normal, `Tab` key. Double-tapping it toggles the **Arrow** layer on until a third tap.
* Tapping the `:` key once yields `:`, tapping it twice yields `;`.
* Tapping the `[{(`/`)}]` keys once yields `[` (or `{` when shifted), tapping them twice yields `(`.
@ -93,12 +94,7 @@ Unless noted otherwise, the layers use a dim light for the LEDs, while modifiers
Once in the Unicode Symbol Input mode, one is able to type in symbol names, press `Enter` or `Space`, and get the Unicode symbol itself back. When in the mode, a capital `U` is printed first. Once the sequence is finished, all of it is erased by sending enough `Backspace` taps, and the firmware starts the OS-specific unicode input sequence. Then, it looks up the symbol name, and enters the associated code. If it is not found, it will just replay the pressed keycodes.
The currently supported symbols are:
- `snowman`: ☃
- `kiss`: 😙
- `rofl`: 🤣
- `poop`: 💩
For the list of supported symbols, please see the source.
This is an experimental feature, and may or may not work reliably.

@ -65,7 +65,7 @@
"x": 4.5,
"f": 3
},
"F12",
"Fx",
{
"a": 4,
"f": 3,

@ -65,7 +65,7 @@
"x": 4.5,
"f": 3
},
"F12",
"Fx",
{
"a": 4,
"f": 3,

@ -16,7 +16,8 @@ _cmd_appsel () {
}
cmd_appsel_music () {
wmctrl -x -a rhythmbox || wmctrl -x -a spotify || true
wmctrl -x -a rhythmbox || wmctrl -x -a spotify || \
wmctrl -x -a banshee || wmctrl -x -a kodi || true
xdotool key Escape
}
@ -25,7 +26,7 @@ cmd_appsel_slack () {
}
cmd_appsel_emacs () {
_cmd_appsel emacs24
_cmd_appsel emacs
}
cmd_appsel_term () {
@ -33,10 +34,14 @@ cmd_appsel_term () {
}
cmd_appsel_chrome () {
_cmd_appsel chromium
_cmd_appsel chrom
}
cmd_appsel_start () {
if [ ! -z "${DISABLE_APPSEL_START}" ]; then
return
fi
APPSEL_START=$(date +%s)
if [ $APPSEL_START -lt $(expr $LAST_APPSEL_START + 10) ]; then
return
@ -46,6 +51,10 @@ cmd_appsel_start () {
-i /usr/share/icons/Adwaita/24x24/devices/video-display.png
}
cmd_reflash () {
teensy_loader_cli -v -w ~/src/ext/qmk_firmware/algernon.hex --mcu atmega32u4 || true
}
cmd_help () {
cat <<EOF
Use the source, Luke!
@ -69,5 +78,3 @@ while read l; do
cmd_${cmd}
fi
done

@ -1,12 +0,0 @@
#!/bin/sh
HL="${HID_LISTEN:-$HOME/src/ext/hid_listen/hid_listen}"
sudo "${HL}" | grep --line-buffered LAYER: | \
(while read line; do
case $line in
LAYER:*)
layer="$(echo $(echo $line | cut -d: -f2-))"
notify-send -i mark-location-symbolic "Switched to layer: $layer"
;;
esac
done)

@ -0,0 +1,17 @@
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 = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ # nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,12 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#define FORCE_NKRO
#define PREVENT_STUCK_MODIFIERS
#undef TAPPING_TERM
#undef IGNORE_MOD_TAP_INTERRUPT
#endif

@ -0,0 +1,107 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define ETC 2 // etc
enum macro_id {
TEENSY,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[BASE] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TAB, KC_Q, KC_W, KC_D, KC_F, KC_K, KC_PGUP,
CTL_T(KC_ESC), LT(ETC,KC_A), KC_S, KC_E, KC_T, KC_G,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_PGDN,
KC_GRV, KC_DEL, KC_DEL, KC_LALT, GUI_T(KC_TAB),
KC_NO, KC_NO,
KC_NO,
LT(SYMB,KC_BSPC), CTL_T(KC_ESC), KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_VOLU, KC_J, KC_U, KC_R, KC_L, KC_SCLN, KC_BSLS,
KC_Y, KC_N, KC_I, KC_O, KC_H, KC_QUOT,
KC_VOLD, KC_P, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
GUI_T(KC_TAB), KC_LEFT, KC_DOWN, KC_UP, LCAG_T(KC_RGHT),
KC_NO, KC_NO,
KC_NO,
KC_NO, SFT_T(KC_ENT), LT(SYMB,KC_SPC)
),
[SYMB] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_TRNS,
KC_TRNS, KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_BSLS,
KC_TRNS, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_ASTR, KC_TRNS,
KC_TILD, KC_AMPR, KC_AMPR, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_EQL, KC_7, KC_8, KC_9, KC_PLUS, KC_NO,
KC_MINS, KC_4, KC_5, KC_6, KC_QUOT, KC_NO,
KC_TRNS, KC_UNDS, KC_1, KC_2, KC_3, KC_DQUO, KC_TRNS,
KC_0, KC_NO, KC_DOT, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
[ETC] = KEYMAP(
RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_PGUP, KC_TRNS,
KC_TRNS, LT(ETC,KC_A), KC_NO, KC_NO, KC_NO, KC_PGDN,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_DEL, KC_TRNS,
KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_VOLU, KC_F7, KC_F8, KC_F9, KC_HOME, KC_NO,
KC_VOLD, KC_F4, KC_F5, KC_F6, KC_END, KC_NO,
KC_TRNS, KC_MUTE, KC_F1, KC_F2, KC_F3, KC_INS, KC_TRNS,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch(id) {
case TEENSY:
break;
}
return MACRO_NONE;
};
void matrix_init_user(void) {
};
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
break;
}
};

@ -0,0 +1,9 @@
# Having a file like this allows you to override Makefile definitions
# for your own particular keymap
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
COMMAND_ENABLE = no # Commands for debug and configuration
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

@ -1,21 +1,23 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "keymap_bepo.h"
#include "keymap_french.h"
#define BASE 0 // default layer
#define QWER 1 // qwerty compat layer
#define SQWER 2 // shifted qwerty compat layer
#define AQWER 3 // alted qwerty compat layer
#define FNAV 4 // function / navigation keys
#define NUM 5 // numeric keypad keys
#define MSE 6 // mouse keys
// keymaps
#define BEPO 0 // default layer, for bepo compatible systems
#define QW_B 1 // bepo to qwerty base compat layer, for qwerty systems
#define QW_A 2 // bepo with altgr key to qwerty compat layer
#define QW_S 3 // bepo with shift key to qwerty compat layer
#define AZ_B 4 // bepo to azerty base compat layer, for azerty systems
#define AZ_A 5 // bepo with altgr key to azerty compat layer
#define AZ_S 6 // bepo with shift key to azerty compat layer
#define FNAV 7 // function / navigation / mouse layer
#define NUMK 8 // numeric keypad layer
#define KP_00 0
#define CA_Fx 1
// macros
#define KP_00 0 // keypad "double 0"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Base layer
/* Keymap 0: default layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = |
@ -26,22 +28,22 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | E_CIRC |A_GRAV| Y | X | . | K | | | | ' | Q | G | H | F | C_CEDIL|
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* |QWERTY| |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause|
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | L_Num| | CA_Fx| | |
* | | |L_NumK| |L_NumK| | |
* | Space|LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[BASE] = KEYMAP(
[BEPO] = KEYMAP(
// Left hand
BP_DOLLAR, BP_DQOT, BP_LGIL, BP_RGIL, BP_LPRN, BP_RPRN, KC_DEL,
BP_PERCENT, BP_B, BP_E_ACUTE, BP_P, BP_O, BP_E_GRAVE, KC_BSPC,
BP_W, BP_A, BP_U, BP_I, BP_E, BP_COMMA,
BP_ECRC, BP_A_GRAVE, BP_Y, BP_X, BP_DOT, BP_K, KC_TAB,
TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT,
KC_ESC, MO(MSE),
MO(NUM),
KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT,
DF(BEPO), DF(QW_B),
MO(NUMK),
KC_SPC, KC_LSHIFT, MO(FNAV),
// Right hand
KC_SLCK, BP_AT, BP_PLUS, BP_MINUS, BP_SLASH, BP_ASTR, BP_EQUAL,
@ -49,10 +51,10 @@ TG(QWER), KC_NO, KC_LGUI, KC_LCTL, KC_LALT,
BP_C, BP_T, BP_S, BP_R, BP_N, BP_M,
KC_NUMLOCK, BP_APOS, BP_Q, BP_G, BP_H, BP_F, BP_CCED,
BP_ALGR, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_NO, KC_INS,
M(CA_Fx),
DF(AZ_B), DF(BEPO),
MO(NUMK),
MO(FNAV), KC_RSHIFT, KC_ENTER),
/* Keymap 1: QWERTY system compatibility layer
/* Keymap 1: bepo to qwerty base compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = |
@ -63,33 +65,70 @@ MO(FNAV), KC_RSHIFT, KC_ENTER),
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | e | a | y | x | . | k | | | | ' | q | g | h | f | c |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause|
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | L_Num| | | | |
* | | |L_NumK| |L_NumK| | |
* | Space|LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[QWER] = KEYMAP(
[QW_B] = KEYMAP(
// Left hand
KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LPRN, KC_RPRN, KC_DEL,
KC_PERCENT, KC_B, KC_E, KC_P, KC_O, KC_E, KC_BSPC,
KC_W, KC_A, KC_U, KC_I, KC_E, KC_COMMA,
KC_E, KC_A, KC_Y, KC_X, KC_DOT, KC_K, KC_TAB,
KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT,
KC_ESC, MO(MSE),
MO(NUM),
KC_SPC, MO(SQWER), MO(FNAV),
KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_SPC, MO(QW_S), KC_TRNS,
// Right hand
KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL,
KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z,
KC_C, KC_T, KC_S, KC_R, KC_N, KC_M,
KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C,
MO(AQWER), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_NO, KC_INS,
MO(QW_A), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, MO(QW_S), KC_ENTER),
/* Keymap 2: bepo with altgr key to qwerty compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | % | | | e | & | o | e |Backsp| |CapsLo| ^ | v | d | l | j | z |
* |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------|
* | w | a | u | i | | , |------| |------| c | t | s | r | n | m |
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | |L_NumK| |L_NumK| | |
* | _ |LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[QW_A] = KEYMAP(
// Left hand
KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LBRC, KC_RBRC, KC_DEL,
KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC,
KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA,
KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB,
KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_UNDS, MO(QW_S), KC_TRNS,
// Right hand
KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL,
KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z,
KC_C, KC_T, KC_S, KC_R, KC_N, KC_M,
KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C,
KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_TRNS, KC_TRNS,
KC_TRNS,
MO(FNAV), MO(SQWER), KC_ENTER),
/* Keymap 2: QWERTY shifted system compatibility layer
KC_TRNS, MO(QW_S), KC_ENTER),
/* Keymap 3: bepo with shift key to qwerty compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | # | 1 | 2 | 3 | 4 | 5 |Delete| |ScroLo| 6 | 7 | 8 | 9 | 0 | = |
@ -100,20 +139,20 @@ MO(FNAV), MO(SQWER), KC_ENTER),
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | E | A | Y | X | : | K | | | | ? | Q | G | H | F | C |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause|
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | L_Num| | | | |
* | | |L_NumK| |L_NumK| | |
* | Space|LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[SQWER] = KEYMAP(
[QW_S] = KEYMAP(
// Left hand
KC_HASH, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS,
KC_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS,
S(KC_W), S(KC_A), S(KC_U), S(KC_I), S(KC_E), KC_SCOLON,
S(KC_E), S(KC_A), S(KC_Y), S(KC_X), KC_COLON, S(KC_K), S(KC_TAB),
KC_TRNS, KC_TRNS, S(KC_LGUI), S(KC_LCTL), S(KC_LALT),
S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT),
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
@ -126,51 +165,125 @@ KC_TRNS, KC_TRNS, S(KC_LGUI), S(KC_LCTL), S(KC_LALT),
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
/* Keymap 3: QWERTY alted system compatibility layer
/* Keymap 4: bepo to azerty base compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | $ | " | < | > | ( | ) |Delete| |ScroLo| @ | + | - | / | * | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | % | b |e_acut| p | o |e_grav|Backsp| |CapsLo| ^ | v | d | l | j | z |
* |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------|
* | w | a | u | i | e | , |------| |------| c | t | s | r | n | m |
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | e |a_grav| y | x | . | k | | | | ' | q | g | h | f | c_cedil|
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | |L_NumK| |L_NumK| | |
* | Space|LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[AZ_B] = KEYMAP(
// Left hand
FR_DLR, FR_QUOT, FR_LESS, FR_GRTR, FR_LPRN, FR_RPRN, KC_DEL,
FR_PERC, KC_B, FR_EACU, KC_P, KC_O, FR_EGRV, KC_BSPC,
FR_W, FR_A, KC_U, KC_I, KC_E, FR_COMM,
KC_E, FR_AGRV, KC_Y, KC_X, FR_DOT, KC_K, KC_TAB,
KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_SPC, MO(AZ_S), KC_TRNS,
// Right hand
KC_SLCK, FR_AT, FR_PLUS, FR_MINS, FR_SLSH, FR_ASTR, FR_EQL,
KC_CAPSLOCK, KC_LBRC, KC_V, KC_D, KC_L, KC_J, FR_Z,
KC_C, KC_T, KC_S, KC_R, KC_N, FR_M,
KC_NUMLOCK, FR_APOS, FR_Q, KC_G, KC_H, KC_F, FR_CCED,
MO(AZ_A), KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, MO(AZ_S), KC_ENTER),
/* Keymap 5: bepo with altgr key to azerty compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | $ | " | < | > | [ | ] |Delete| |ScroLo| @ | + | - | / | * | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | % | | | e | & | o | e |Backsp| |CapsLo| ^ | v | d | l | j | z |
* |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------|
* | w | a | u | i | | , |------| |------| c | t | s | r | n | m |
* | w | a |u_grav| trem | | , |------| |------| c | t | s | r | n | m |
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | e | \ | { | } | . | ~ | | | | ' | q | g | h | f | c |
* | / | \ | { | } | . | ~ | | | | ' | q | g | h | f | c |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* | BEPO | |LSuper| LCtrl| LAlt| |Escape| L_Mse| | |Insert| | AltGr| RCtrl|RSuper|PrntSc| Pause|
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | L_Num| | | | |
* | | |L_NumK| |L_NumK| | |
* | _ |LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[AQWER] = KEYMAP(
[AZ_A] = KEYMAP(
// Left hand
KC_DOLLAR, S(KC_QUOT), S(KC_COMM), S(KC_DOT), KC_LBRC, KC_RBRC, KC_DEL,
KC_PERCENT, KC_PIPE, KC_E, KC_AMPR, KC_O, KC_E, KC_BSPC,
KC_W, KC_A, KC_U, KC_I, RALT(KC_5), KC_COMMA,
KC_E, KC_BSLASH, KC_LCBR, KC_RCBR, KC_DOT, KC_TILDE, KC_TAB,
KC_TRNS, KC_NO, KC_LGUI, KC_LCTL, KC_LALT,
KC_ESC, MO(MSE),
MO(NUM),
KC_UNDS, MO(SQWER), MO(FNAV),
FR_DLR, FR_QUOT, FR_LESS, FR_GRTR, FR_LBRC, FR_RBRC, KC_DEL,
FR_PERC, FR_PIPE, FR_EACU, FR_AMP, KC_O, FR_EGRV, KC_BSPC,
FR_W, FR_A, FR_UGRV, S(KC_LBRC), FR_EURO, FR_COMM,
FR_SLSH, FR_BSLS, FR_LCBR, FR_RCBR, FR_DOT, FR_TILD, KC_TAB,
KC_ESC, KC_INS, KC_LGUI, KC_LCTL, KC_LALT,
KC_TRNS, KC_TRNS,
KC_TRNS,
FR_UNDS, MO(AZ_S), KC_TRNS,
// Right hand
KC_SLCK, KC_AT, KC_PLUS, KC_MINUS, KC_SLASH, KC_ASTR, KC_EQUAL,
KC_CAPSLOCK, KC_CIRC, KC_V, KC_D, KC_L, KC_J, KC_Z,
KC_C, KC_T, KC_S, KC_R, KC_N, KC_M,
KC_NUMLOCK, KC_QUOT, KC_Q, KC_G, KC_H, KC_F, KC_C,
KC_SLCK, FR_AT, FR_PLUS, FR_MINS, FR_SLSH, FR_ASTR, FR_EQL,
KC_CAPSLOCK, KC_LBRC, KC_V, KC_D, KC_L, KC_J, FR_Z,
KC_C, KC_T, KC_S, KC_R, KC_N, FR_M,
KC_NUMLOCK, FR_APOS, FR_Q, KC_G, KC_H, KC_F, FR_CCED,
KC_TRNS, KC_RCTL, KC_RGUI, KC_PSCREEN, KC_PAUSE,
KC_NO, KC_INS,
KC_TRNS, KC_TRNS,
KC_TRNS,
MO(FNAV), MO(SQWER), KC_ENTER),
/* Keymap 4: function / navigation layer
KC_TRNS, MO(AZ_S), KC_ENTER),
/* Keymap 6: bepo with shift key to azerty compat layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | # | 1 | 2 | 3 | 4 | 5 |Delete| |ScroLo| 6 | 7 | 8 | 9 | 0 | ° |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | ` | B | E | P | O | E |Backsp| |CapsLo| ! | V | D | L | J | Z |
* |--------+------+------+------+------+------| ace | | |------+------+------+------+------+--------|
* | W | A | U | I | E | ; |------| |------| C | T | S | R | N | M |
* |--------+------+------+------+------+------| Tab | | NumLo|------+------+------+------+------+--------|
* | E | A | Y | X | : | K | | | | ? | Q | G | H | F | C |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* |Escape|Insert|LSuper| LCtrl| LAlt| | BEPO |QWERTY| |AZERTY| BEPO | | AltGr| RCtrl|RSuper|PrntSc| Pause|
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | |L_NumK| |L_NumK| | |
* | Space|LShift|------| |------|RShift|Enter |
* | | |L_FNav| |L_FNav| | |
* `--------------------' `--------------------'
*/
[AZ_S] = KEYMAP(
// Left hand
FR_HASH, FR_1, FR_2, FR_3, FR_4, FR_5, KC_TRNS,
FR_GRV, S(KC_B), S(KC_E), S(KC_P), S(KC_O), S(KC_E), KC_TRNS,
S(FR_W), S(FR_A), S(KC_U), S(KC_I), S(KC_E), FR_SCLN,
S(KC_E), S(FR_A), S(KC_Y), S(KC_X), FR_COLN, S(KC_K), S(KC_TAB),
S(KC_ESC), S(KC_INS), S(KC_LGUI), S(KC_LCTL), S(KC_LALT),
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// Right hand
KC_TRNS, FR_6, FR_7, FR_8, FR_9, FR_0, FR_OVRR,
KC_TRNS, FR_EXLM, S(KC_V), S(KC_D), S(KC_L), S(KC_J), S(FR_Z),
S(KC_C), S(KC_T), S(KC_S), S(KC_R), S(KC_N), S(FR_M),
KC_TRNS, FR_QUES, S(FR_Q), S(KC_G), S(KC_H), S(KC_F), S(KC_C),
S(KC_RALT), S(KC_RCTL), S(KC_RGUI), KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS),
/* Keymap 7: function / navigation / mouse layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 |VolMut| | | F6 | F7 | F8 | F9 | F10 | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | |VolDwn| | | PgUp | Home | Up | End | F11 | |
* | | Next |LClick| Up |RClick| WhUp |VolDwn| | | PgUp | Home | Up | End | F11 | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| PgDn | Left | Down | Right| F12 | |
* | | Prev | Left | Down | Right|WhDown|------| |------| PgDn | Left | Down | Right| F12 | |
* |--------+------+------+------+------+------| VolUp| | |------+------+------+------+------+--------|
* | | Undo | Cut | Copy | Paste| | | | | | | | | | |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
@ -184,12 +297,12 @@ MO(FNAV), MO(SQWER), KC_ENTER),
[FNAV] = KEYMAP(
// Left hand
KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_MUTE,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLU,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_MS_BTN5, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, KC_VOLU,
KC_NO, KC_MS_BTN4, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN,
KC_NO, KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, KC_NO, KC_VOLD,
KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,
KC_NO, KC_NO,
KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_NO, KC_TRNS, KC_TRNS,
// Right hand
KC_NO, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_NO,
@ -197,91 +310,52 @@ KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,
KC_PGDOWN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_F12, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_NO),
/* Keymap 5: numeric layer, sends keypad codes
/* Keymap 8: numeric keypad layer, sends keypad codes
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | + | - | / | * | |
* | | | | | | | | | | | NumLo| / | * | - | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | | 7 | 8 | 9 | | |
* | | | | | | | | | | | 7 | 8 | 9 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | 4 | 5 | 6 | | |
* | | | | | | |------| |------| | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | 1 | 2 | 3 | | |
* | | | | | | | | | | | 1 | 2 | 3 | Enter| |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* | | | | | | | | | | | | | 0 | 00 | . | | |
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | | | | | |
* | | |------| |------| | Enter|
* | | | | | | | |
* `--------------------' `--------------------'
*/
[NUM] = KEYMAP(
// Left hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,
KC_NO, KC_NO,
KC_TRNS,
KC_NO, KC_TRNS, KC_NO,
// Right hand
KC_NO, KC_NO, KC_KP_PLUS, KC_KP_MINUS, KC_KP_SLASH, KC_KP_ASTERISK, KC_NO,
KC_NO, KC_NO, KC_KP_7, KC_KP_8, KC_KP_9, KC_NO, KC_NO,
KC_NO, KC_KP_4, KC_KP_5, KC_KP_6, KC_NO, KC_NO,
KC_NO, KC_NO, KC_KP_1, KC_KP_2, KC_KP_3, KC_NO, KC_NO,
KC_KP_0, M(KP_00), KC_KP_COMMA, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_TRNS, KC_KP_ENTER),
/* Keymap 6: mouse layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | |LClick| Up |RClick| WhUp | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | Left | Down | Right|WhDown| |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------,-------------. ,-------------`-------------+------+------+------+------+--------'
* | | | | | | | | | | | | | | | | | |
* | | | | | | | | | | | | | 0 | 00 | . | Enter| |
* `----------------------------------' ,------|------|------| |------+------+------. `----------------------------------'
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
[MSE] = KEYMAP(
[NUMK] = KEYMAP(
// Left hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,
KC_NO, KC_TRNS,
KC_NO,
KC_NO, KC_TRNS, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_NO, KC_TRNS, KC_TRNS,
// Right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_MS_WH_UP, KC_NO,
KC_NO, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_WH_DOWN, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_TRNS, KC_NO)
};
const uint16_t PROGMEM fn_actions[] = {
KC_NO, KC_NO, KC_NUMLOCK, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_NO,
KC_NO, KC_NO, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_PLUS, KC_NO,
KC_NO, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_NO,
KC_NO, KC_NO, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_ENTER, KC_NO,
KC_KP_0, M(KP_00), KC_KP_COMMA, KC_KP_ENTER, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_NO)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
// keypad "double 0"
case KP_00:
if (record->event.pressed) {
return MACRO( T(KP_0), D(KP_0), END );
@ -289,23 +363,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO( U(KP_0), END );
}
break;
case CA_Fx:
if (record->event.pressed) {
layer_on(FNAV);
return MACRO( D(LALT), D(LCTL), END );
} else {
layer_off(FNAV);
return MACRO( U(LCTL), U(LALT), END );
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
};

@ -23,12 +23,12 @@ La touche "Tab" est placée comme sur la TypeMatrix 2020.
Meilleure symétrie et accessibilité que la TypeMatrix 2030 : les touches "W" et "%" ont dû être déplacées du côté gauche en raison du nombre de touches de l'ErgoDox, mais l'auriculaire droit ne gère maintenant que deux colonnes de touches au lieu de trois. La touche "Ê" redevient accessible sur la même rangée que les autres lettres, comme sur un clavier classique en disposition bépo. Les lettres, chiffres et symboles sont tous regroupés sur 4 lignes et 6 colonnes pour chaque main, et la première rangée de lettres à la main gauche conserve une identité visuelle "BÉPO".
Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à F10 sont placées de façon logique par rapport aux chiffres 1 à 0. Cette même touche permet l'accès aux touches directionnelles sans déplacer la main droite. Les touches "Home" et "End" sont placées de la même façon que sur une TypeMatrix 2030 par rapport aux touches directionnelles. Les touches "Page Up" et "Page Down" sont également accessibles facilement sans déplacer la main droite. Les fonctions "VolUp" et "VolDown" sont placées comme sur la TypeMatrix 2030, avec la fonction "Mute" juste au dessus. Les fonctions "Undo", "Cut", "Copy" et "Paste" sont placées côte à côte comme elles le seraient sur un clavier QWERTY en combinaison avec la touche "Ctrl" (à l'emplacement des lettres "Z", "X", "C" et "V"). Par rapport au layout "SpaceFN", l'utilisation d'une touche de fonction dédiée au pouce permet de ne pas ajouter de latence, et la touche espace reste compatible avec les jeux (action au moment de l'appui et possibilité d'appui long).
Touche de fonction permettant de saisir les touches F1 à F12, les touches F1 à F10 sont placées de façon logique par rapport aux chiffres 1 à 0. Cette même touche permet l'accès aux touches directionnelles sans déplacer la main droite et d'effectuer des actions souris avec uniquement la main gauche. Les touches "Home" et "End" sont placées de la même façon que sur une TypeMatrix 2030 par rapport aux touches directionnelles. Les touches "Page Up" et "Page Down" sont également accessibles facilement sans déplacer la main droite. Les fonctions "VolUp" et "VolDown" sont placées comme sur la TypeMatrix 2030, avec la fonction "Mute" juste au dessus. Les fonctions "Undo", "Cut", "Copy" et "Paste" sont placées côte à côte comme elles le seraient sur un clavier QWERTY en combinaison avec la touche "Ctrl" (à l'emplacement des lettres "Z", "X", "C" et "V"). Par rapport au layout "SpaceFN", l'utilisation d'une touche de fonction dédiée au pouce permet de ne pas ajouter de latence, et la touche espace reste compatible avec les jeux (action au moment de l'appui et possibilité d'appui long).
Touche de fonction permettant l'accès au pavé numérique comme sur la TypeMatrix 2030, mais sans avoir à déplacer la main droite : avec les doigts sur la rangée de repos, possibilité de saisir les chiffres "4", "5" et "6" comme sur un pavé numérique classique. Le double "0" de la TypeMatrix a été conservé, et gagne une possibilité de répétition en simples "0".
L'appui sur une touche permet de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle.
Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier QWERTY. Cette compatibilité n'est pas parfaite (pas encore de gestion des accents mais ça devrait être faisable avec une disposition en qwerty international, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle et pour des accès BIOS ou console en QWERTY.
TODO : couche de compatibilité pour utiliser la disposition BÉPO sur un système configuré pour un clavier AZERTY.
Touche permettant de basculer en mode BEPO sur un système configuré pour un clavier AZERTY. Cette compatibilité n'est pas parfaite (pas de gestion des caractères non présents sur le clavier AZERTY, et les combinaisons de touches ne sont pas toutes supportées puisque le clavier traduit déjà certaines touches en combinaisons) mais reste pratique pour une saisie de texte occasionnelle et pour faire du bureau à distance vers un système Windows sans BEPO.
> Olivier Smedts <olivier@gid0.org>

@ -0,0 +1,6 @@
SUBPROJECT_DEFAULT = ez
TAP_DANCE_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,216 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
//Tap Dance Declarations
enum {
TD_U_LBRC = 0,
TD_I_RBRC,
};
//Tap Dance Definitions
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_U_LBRC] = ACTION_TAP_DANCE_DOUBLE(KC_U, KC_LBRC),
[TD_I_RBRC] = ACTION_TAP_DANCE_DOUBLE(KC_I, KC_RBRC)
};
//Macro Declarations
static uint16_t sunds_timer;
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | _ | x | x | _ | Esc | Hypr | Home | | End | Hypr | [ | ] | `~ | `~ | Bks |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* |Ctrl/Tab| Q | W | E | R | T | Up | | PgUp | Y | U | I | O | P | Ctrl |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | Cmd/"' | A | S | D | F | G |------| |------| H | J | K | L | ;: |Cmd/Entr|
* |--------+------+------+------+------+------| Down | | PgDn |------+------+------+------+------+--------|
* | Shft | Z | X | C | V | B | | | | N | M | ,< | .> | /? | Shft |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | Alt | x | x | x | Left | |Right | Bks | x | x | Alt |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* |Teensy| VolUp| | Play | Del |
* ,------|------|------| |------+--------+------.
* | | | VolDn| | Next | | |
* |Sp/~L1| L2 |------| |------| L2 |'"/~L1|
* | | | Mute | | Prev | | |
* `--------------------' `----------------------'
*/
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_UNDS, KC_1, KC_1, KC_UNDS, KC_ESC, ALL_T(KC_NO), KC_HOME,
CTL_T(KC_TAB), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_UP,
M(1), KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_DOWN,
KC_LALT, KC_1, KC_1, KC_1, KC_LEFT,
RESET, KC_VOLU,
KC_VOLD,
LT(SYMB, KC_SPC), TG(MDIA), KC_MUTE,
// right hand
KC_END, ALL_T(KC_NO), KC_LBRC, KC_RBRC, KC_GRV, KC_GRV, KC_BSPC,
KC_PGUP, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LCTRL,
KC_H, KC_J, KC_K, KC_L, KC_SCOLON, GUI_T(KC_ENT),
KC_PGDN, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
KC_RGHT, KC_BSPC, KC_1, KC_1, KC_RALT,
KC_MPLY, KC_DEL,
KC_MNXT,
KC_MPRV, TG(MDIA), LT(SYMB, KC_QUOT)
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | ^ | [ | ( | { | | | | = | 7 | 8 | 9 | 0 | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | & | $ | ] | ) | } |------| |------| + | 4 | 5 | 6 | * | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | \ | @ | # | % | | | | | | - | 1 | 2 | 3 | / | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | 0 | 0 | . | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_EXLM, KC_CIRC, KC_LBRC, KC_LPRN, KC_LCBR, KC_TRNS,
KC_TRNS, KC_AMPR, KC_DLR, KC_RBRC, KC_RPRN, KC_RCBR,
KC_TRNS, KC_BSLS, KC_AT, KC_HASH, KC_PERC, KC_PIPE, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
KC_TRNS, KC_EQL, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
KC_PLUS, KC_4, KC_5, KC_6, KC_ASTR, KC_TRNS,
KC_TRNS, KC_MINS, KC_1, KC_2, KC_3, KC_TRNS, KC_TRNS,
KC_0, KC_0, KC_DOT, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* |Version | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | | WhDn | WhUp | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | R-Ck | L-Ck | |------| |------| MsLt | MsDn | MsUp | MsRt | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | | |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
M(0), 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_BTN2, KC_BTN1, 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,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_WH_U, KC_WH_D, KC_TRNS, KC_TRNS, KC_TRNS,
KC_MS_LEFT, KC_MS_DOWN, KC_MS_UP, KC_MS_RIGHT, 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_WBAK
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
case 1:
if (record->event.pressed) {
sunds_timer = timer_read();
register_code (KC_LGUI);
} else {
if (timer_elapsed (sunds_timer) < TAPPING_TERM) {
unregister_code (KC_LGUI);
register_code (KC_LSFT);
register_code (KC_QUOT);
unregister_code (KC_QUOT);
unregister_code (KC_LSFT);
register_code (KC_LGUI);
}
unregister_code (KC_LGUI);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_3_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
if (keyboard_report->mods & MOD_BIT(KC_LSFT)) {
ergodox_right_led_1_on ();
}
};

@ -0,0 +1,273 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
#define NAVG 3 // navigation
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
EPRM,
VRSN,
RGB_SLD
};
// TODO: Get rid of of keys I don't want. Make others that I do. Set up lots of makros (Using hyper (and meh)) keys (where to put them?)
// TODO: Need to change hotkeys for lastpass, and potentially make my own keys for them on one of my layers
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | Esc/L3 | 1 | 2 | 3 | 4 | 5 | 6 | | 6 | 7 | 8 | 9 | 0 | - | =/L3 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab/L1 | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \/L1 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | LCtrl | A | S | D | F | G |------| |------| H | J | K | L |; / L2| ctrl/'|
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
* | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |Grv/L1| '" |AltShf| Lalt | Ralt | | Lalt | Ralt | [ | ] | ~/L1 |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | App | Home | | PgUp | Ins |
* ,------|------|------| |------+--------+------.
* | | | End | | PgDn | | |
* | Space| TAB |------| |------| BSPC |Enter |
* | | | [ | | ] | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
LT(NAVG,KC_ESC), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
LT(SYMB,KC_TAB), KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_RALT,KC_LALT,
ALT_T(KC_APP), KC_HOME,
KC_END,
KC_SPC,KC_TAB,KC_LBRC,
// right hand
KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, LT(NAVG,KC_EQL),
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, LT(SYMB, KC_BSLS),
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),CTL_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_LALT, KC_RALT,KC_LBRC,KC_RBRC, LT(SYMB,KC_TILD),
KC_PGUP, KC_INS,
KC_PGDN,
KC_RBRC,KC_BSPC, KC_ENT
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| DEL | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_TRNS,
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_DEL, KC_TRNS
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | | |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
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_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK
),
/* Keymap 3: Navigation TODO: Printscreen, pg up down, home, end, others? Insert for example
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | VER | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | up | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | left | down | right| |------| |------| | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// NAVIGATION
[NAVG] = KEYMAP(
KC_TRNS, VRSN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, 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,
// right hand
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_MPRV, 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
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
case 1:
if (record->event.pressed) { // For resetting EEPROM
eeconfig_init();
}
break;
}
return MACRO_NONE;
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case EPRM:
if (record->event.pressed) {
eeconfig_init();
}
return false;
break;
case VRSN:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
return false;
break;
case RGB_SLD:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_mode(1);
#endif
}
return false;
break;
}
return true;
}
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
break;
case 4:
ergodox_right_led_1_on(); // TODO: Make a fourth layer
ergodox_right_led_3_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,10 @@
# ErgoDox EZ 1337 configuration
Custom layout based on the default layout. Intended for interational users of us intl-altgr layout. Note that
some common keys might be missing, as this layout is intented to be used on *nix systems by users familiar
with their system. The layout is geared towards avoiding using the rat (mouse for those of you who are
unfamiliar with tiling window managers) as much as possibly.
# Changelog
- 02.01.2017 Added delete key on second layer

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

@ -7,7 +7,12 @@
#define SYMB 1 // symbols
#define MDIA 2 // media keys
#define EPRM M(1) // Macro 1: Reset EEPROM
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
EPRM,
VRSN,
RGB_SLD
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
@ -44,56 +49,56 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_HOME,
KC_SPC,KC_BSPC,KC_END,
// right hand
KC_RGHT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1,
KC_RGHT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1,
KC_LALT, CTL_T(KC_ESC),
KC_PGUP,
KC_PGDN,KC_TAB, KC_ENT
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | EPRM | | | | | | | . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,---------------------------------------------------. ,--------------------------------------------------.
* |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |---------+------+------+------+------+------+------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
* |---------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |---------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `---------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | EPRM | | | | | | | . | 0 | = | |
* `-----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* |Animat| | |Toggle|Solid |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* |Bright|Bright| | | |Hue- |Hue+ |
* |ness- |ness+ |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
M(0), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
VRSN, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
EPRM,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
RGB_MOD,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
RGB_VAD,RGB_VAI,KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
KC_TRNS, KC_TRNS,
RGB_TOG, RGB_SLD,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
KC_TRNS, RGB_HUD, RGB_HUI
),
/* Keymap 2: Media and mouse keys
*
@ -160,6 +165,33 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
return MACRO_NONE;
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case EPRM:
if (record->event.pressed) {
eeconfig_init();
}
return false;
break;
case VRSN:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
return false;
break;
case RGB_SLD:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_mode(1);
#endif
}
return false;
break;
}
return true;
}
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {

@ -2,6 +2,9 @@
## Changelog
* Dec 2016:
* Added LED keys
* Refreshed layout graphic, comes from http://configure.ergodox-ez.com now.
* Sep 22, 2016:
* Created a new key in layer 1 (bottom-corner key) that resets the EEPROM.
* Feb 2, 2016 (V1.1):
@ -9,4 +12,4 @@
This is what we ship with out of the factory. :) The image says it all:
![Default](default_highres.png)
![Default](default_firmware_v1.2-2.png)

@ -0,0 +1,165 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
/******************************************************************************************
* DVORAK LAYOUT (see http://djelibeibi.unex.es/dvorak/)
* Layer 1: auxiliary keys
* Layer 2: full qwerty layout
*****************************************************************************************/
// LAYERS
#define BASE 0 // dvorak layout (default)
#define AUX 1 // auxiliary keys
// MACROS
/* #define OBRACE 0 // key { or shift */
/* #define CBRACE 1 // key } or shift */
/* #define OBRACK 2 // key [ or left alt */
/* #define CBRACK 3 // key ] or left alt */
/* #define CAPS 4 // caps lock */
// LEDS
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
// TIMERS
#define KEY_TAP_FAST 85
#define KEY_TAP_SLOW 95
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Base layer
* Keys with double values (like Esc/Ctrl) correspond to the 'tapped' key and the 'held' key, respectively
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | 1 | 2 | 3 | 4 | 5 | Esc | | Esc | 6 | 7 | 8 | 9 | 0 | = / + |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | ~ |" / ' |, / < |. / > | P | Y | [ | | ] | F | G | C | H | L | / / ? |
* |--------+------+------+------+------+------| { | | } |------+------+------+------+------+--------|
* | Tab | A | O | E |U/LSft| I/L1 |------| |------| D/L1|R/RSft| T | N | S | - / _ |
* |--------+------+------+------+------+------| LGUI | | LGUI |------+------+------+------+------+--------|
* | {/LSft |; / : | Q | J | K | X | | | | B | M | W | V | Z | }/RSft |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | ~L1 | | ~L1 | | | \ / || |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | HOME | END | | LEFT | RIGHT|
* ,------|------|------| |------+--------+------.
* | BSPC | DEL | PGUP | | UP | SPACE |RETURN|
* | / | / |------| |------| / | / |
* | LCTL | LALT |PGDWN | | DOWN | LALT | LCTL |
* `--------------------' `----------------------'
*
*/
[BASE] = KEYMAP(
// left hand
KC_NO, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
KC_TILD, KC_QUOTE, KC_COMM,KC_DOT, KC_P, KC_Y, KC_LBRACKET,
KC_TAB, KC_A, KC_O, KC_E, SFT_T(KC_U), LT(AUX, KC_I),
SFT_T(KC_LBRC), KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_LGUI,
KC_NO, KC_NO, KC_NO, KC_NO, MO(AUX),
KC_HOME, KC_END,
KC_PGUP,
CTL_T(KC_BSPC), ALT_T(KC_DEL), KC_PGDN,
// right hand
KC_ESC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL,
KC_RBRACKET, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLASH,
LT(AUX, KC_D), SFT_T(KC_H), KC_T, KC_N, KC_S, KC_MINUS,
KC_LGUI, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_T(KC_RBRC),
MO(AUX), KC_NO, KC_NO, KC_BSLASH, KC_NO,
KC_LEFT, KC_RIGHT,
KC_UP,
KC_DOWN, ALT_T(KC_ENT), CTL_T(KC_SPC)
),
/* Keymap 1: Aux layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | VolUp | | | | | | SLEEP | PWR | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | VolDn | F1 | F2 | F3 | F4 | | | | | | 7 | 8 | 9 | * | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | F5 | F6 | F7 | F8 | TRANS|------| |------|TRANS | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | |PSCR |------+------+------+------+------+--------|
* | TRANS | F9 | F10 | F11 | F12 | | | | | | 1 | 2 | 3 | / | TRANS |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |CTRL-S|CTRL-Z|CTRL-X|CTRL-C| TRANS| | TRANS| . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | TRANS| TRANS| | TRANS| TRANS|
* ,------|------|------| |------+------+------.
* | | | TRANS| | TRANS| | |
* |TRANS |TRANS |------| |------| TRANS| TRANS|
* | | | TRANS| | TRANS| | |
* `--------------------' `--------------------'
*/
[AUX] = KEYMAP(
// left hand
KC_VOLU, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_SLEP,
KC_VOLD, KC_F1, KC_F2, KC_F3, KC_F4, KC_NO, KC_NO,
KC_NO , KC_F5, KC_F6, KC_F7, KC_F8, KC_TRNS,
KC_TRNS, KC_F9, KC_F10, KC_F11, KC_F12, KC_NO, KC_NO,
LCTL(KC_S), LCTL(KC_Z), LCTL(KC_X), LCTL(KC_C), KC_TRNS,
KC_TRNS , KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_PWR, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_7, KC_8, KC_9, KC_PAST, KC_NO,
KC_TRNS, KC_4, KC_5, KC_6, KC_PPLS, KC_NO,
KC_PSCR, KC_NO, KC_1, KC_2, KC_3, KC_PSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, KC_PEQL, KC_NO,
KC_TRNS , KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(AUX) // FN1 - Momentary Layer 1 (Aux)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
}

@ -0,0 +1,70 @@
# Ergodox Dvorak Layout with emacs binding in mind
* Control & Alt key on the thumbs (activated if pressed with another key).
* In the same way, "U" and "R" are the shift modifier if pressed with another key.
* "I" and "D" set the layer 1 for the auxiliary keys if pressed with another key.
* Software layout set to english.
## Keymap Layers
- L0: dvorak with some customizations (see layout below)
- L1: auxiliary keys (includes function keys, numpad...)
### Keymap 0: Base layer
Keys with double values (like U/LSft) correspond to the 'tapped' key and the 'held' key, respectively
<pre><code>
,--------------------------------------------------. ,--------------------------------------------------.
| | 1 | 2 | 3 | 4 | 5 | Esc | | Esc | 6 | 7 | 8 | 9 | 0 | = |
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
| ~ | ' | , | . | P | Y | [ | | ] | F | G | C | H | L | / |
|--------+------+------+------+------+------| { | | } |------+------+------+------+------+--------|
| Tab | A | O | E |U/LSft| I/L1 |------| |------| D/L1|R/RSft| T | N | S | - |
|--------+------+------+------+------+------| LGUI | | LGUI |------+------+------+------+------+--------|
| {/LSft | ; | Q | J | K | X | | | | B | M | W | V | Z | }/RSft |
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
| | | | | ~L1 | | ~L1 | | | \ | |
`----------------------------------' `----------------------------------'
,-------------. ,-------------.
| HOME | END | | LEFT | RIGHT|
,------|------|------| |------+--------+------.
| BSPC | DEL | PGUP | | UP | SPACE |RETURN|
| / | / |------| |------| / | / |
| LCTL | LALT |PGDWN | | DOWN | LALT | LCTL |
`--------------------' `----------------------'
</pre></code>
### Keymap 1: Aux layer
<pre><code>
,--------------------------------------------------. ,--------------------------------------------------.
| VolUp | | | | | | SLEEP | PWR | | | | | | |
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
| VolDn | F1 | F2 | F3 | F4 | | | | | | 7 | 8 | 9 | * | |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| | F5 | F6 | F7 | F8 | TRANS|------| |------|TRANS | 4 | 5 | 6 | + | |
|--------+------+------+------+------+------| | |PSCR |------+------+------+------+------+--------|
| TRANS | F9 | F10 | F11 | F12 | | | | | | 1 | 2 | 3 | / | TRANS |
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|CTRL-S|CTRL-Z|CTRL-X|CTRL-C| TRANS| | TRANS| . | 0 | = | |
`----------------------------------' `----------------------------------'
,-------------. ,-------------.
| TRANS| TRANS| | TRANS| TRANS|
,------|------|------| |------+------+------.
| | | TRANS| | TRANS| | |
|TRANS |TRANS |------| |------| TRANS| TRANS|
| | | TRANS| | TRANS| | |
`--------------------' `--------------------'
</pre></code>
## Generation of .hex file
> In the "qmk_firmware/keyboards/ergodox" directory.
> Execute "make dvorak_emacs". Then the hex file "ergodox_ez_dvorak_emacs.hex" is in the root directory : "qmk_firmware".
> Flash with `teensy_loader` binary

@ -0,0 +1,14 @@
Dvorak support, plover support, gaming support
I'm used to the Kinesis, so originally I was just going to patch up
the thumb keys to be more familiar. But the ergodox is really well
suited to NKRO support in Plover, so I added a layer for that, and
then I remembered that dvorak can be really annoying for video
games (try to reach WASD), so I added a layer for that.
The result is probably a bit idiosyncratic, but it works for me.
(I also don't have any press/hold distinction keys, because that
confuses my fuzzy little brain.)
Contributed by seebs (seebs@seebs.net)

@ -0,0 +1,230 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define PLVR 2 // media keys
#define QWRT 3 // qwerty layer for gaming
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | = | 1 | 2 | 3 | 4 | 5 | Esc | | Esc | 6 | 7 | 8 | 9 | 0 | \ |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | ' | , | . | P | Y | L1 | | L2 | F | G | C | R | L | / |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | LGui | A | O | E | U | I |------| |------| D | H | T | N | S | - |
* |--------+------+------+------+------+------| Esc | | L3 |------+------+------+------+------+--------|
* | LShift | ; | Q | J | K | X | | | | B | M | W | V | Z | RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |Lalt | Grv | | Left | Right| | Up | Down | [ | ] | RAlt |
* `----------------------------------' `----------------------------------'
* ,-------------. ,---------------.
* | LCtrl| Alt | | LGui | RCtrl |
* ,------|------|------| |------+--------+------.
* | | | Home | | PgUp | | |
* |Backsp|Delete|------| |------| Enter |Space |
* | ace| | End | | PgDn | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, MO(SYMB),
KC_LGUI, KC_A, KC_O, KC_E, KC_U, KC_I,
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_ESC,
KC_LALT, KC_GRV, KC_ESC, KC_LEFT,KC_RGHT,
KC_LCTL, KC_LALT,
KC_HOME,
KC_BSPC,KC_DEL,KC_END,
// right hand
KC_ESC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS,
TG(PLVR), KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH,
KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS,
TG(QWRT),KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_RALT,
KC_LGUI, KC_RCTL,
KC_PGUP,
KC_PGDN,KC_ENT, KC_SPC
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | KP7 | KP8 | KP9 | KP* | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | KP4 | KP5 | KP6 | KP+ | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | KP1 | KP2 | KP3 | KP/ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | KP. | KP0 | KP= | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_UP, KC_P7, KC_P8, KC_P9, KC_PAST, KC_F12,
KC_DOWN, KC_P4, KC_P5, KC_P6, KC_PPLS, KC_TRNS,
KC_TRNS, KC_AMPR, KC_P1, KC_P2, KC_P3, KC_PSLS, KC_TRNS,
KC_TRNS,KC_PDOT, KC_P0, KC_PEQL, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Steno for Plover from https://github.com/shayneholmes/tmk_keyboard/commit/11290f8489013018f778627db725160c745e75bd
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | 1 | 2 | 3 | 4 | 5 | | | L2 | 6 | 7 | 8 | 9 | 0 | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | q | w | e | r | t |------| |------| y | u | i | o | p | [ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | a | s | d | f | g | | | | h | j | k | l | ; | ' |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | c | v |------| |------| n | m |
* | | | | | | | |
* `--------------------' `--------------------'
*/
[PLVR] = KEYMAP( // layout: layer 2: Steno for Plover
// left hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_1, KC_2, KC_3, KC_4, KC_5, KC_TRNS,
KC_NO, KC_Q, KC_W, KC_E, KC_R, KC_T,
KC_NO, KC_A, KC_S, KC_D, KC_F, KC_G, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_FN4, KC_NO,
KC_NO,
KC_C, KC_V, KC_NO,
// right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS,
TG(2), KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
KC_NO, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_NO, KC_N, KC_M
),
/* Keymap 3: qwerty-ish
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | = | 1 | 2 | 3 | 4 | 5 | Esc | | Esc | 6 | 7 | 8 | 9 | 0 | - |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | W | E | R | T | | | | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | LGui | A | S | D | F | G |------| |------| H | J | K | L | ; | LGui |
* |--------+------+------+------+------+------| Spc | | L3 |------+------+------+------+------+--------|
* | LShift | Z | X | C | V | B | | | | N | M | , | . | / | RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | Lalt | Grv | '" | Left | Right| | Up | Down | [ | ] | RAlt |
* `----------------------------------' `----------------------------------'
* ,-------------. ,---------------.
* | LCtrl| LAlt | | LGui | RCtrl |
* ,------|------|------| |------+--------+------.
* | | | Home | | PgUp | | |
* |Backsp|Delete|------| |------| Enter |Space |
* | ace| | End | | PgDn | | |
* `--------------------' `----------------------'
*/
[QWRT] = KEYMAP( // layer 3: qwerty for gaming
// left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_LGUI, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_SPACE,
KC_LALT, KC_GRV, KC_QUOT, KC_LEFT,KC_RGHT,
KC_LCTL, KC_LALT,
KC_HOME,
KC_BSPC,KC_DEL,KC_END,
// right hand
KC_ESC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_NO, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
TG(QWRT), KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_RALT,
KC_LGUI, KC_RCTL,
KC_PGUP,
KC_PGDN,KC_ENT, KC_SPC
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,8 @@
BOOTMAGIC_ENABLE=no
COMMAND_ENABLE=no
SLEEP_LED_ENABLE=no
FORCE_NKRO ?= yes
DEBUG_ENABLE = no
CONSOLE_ENABLE = no
TAP_DANCE_ENABLE = yes
MOUSEKEY_ENABLE = yes

@ -0,0 +1,29 @@
Dvorak Programmer Layout
========================
This is a dvorak-only layout. The overall philosophy is that the left hand contains a number of layer-switching shortcuts, and the right hand key codes vary based on the layer selected.
Layers
------
* BASE: this is where you type.
* SHELL_NAV: hold down the Tab key to access shell/terminal navigation shorcuts such as forward/backward word, history, Ctrl+C, screen tab movement.
* KEY_NAV: arrow key movement with backward/forward word support, and copy/paste.
* KEY_SEL: same as above, but every movement shift-selects.
* NUMBER: keypad layer.
* SYMBOL: all the symbols.
* BRACKET: special brackets-only layer for programming
* SHORTCUTS: sends Hyper keys for Autohotkey to interpret. I use this to switch between specific apps.
* MOUSE: use mouse keys
Updates
-------
2016/12/10:
* toggle for brackets layer is now on left thumb cluster.
2016/11/05:
* removed brackets anywhere but in brackets layer
* added mouse layer back in
* put semicolon-newline and end-newline on symbol layer
* replaced all HYPR with MEH, added more shortcut keys

@ -0,0 +1,424 @@
#include "ergodox.h"
#include "led.h"
#include "debug.h"
#include "action_layer.h"
#include "action_code.h"
#define BASE 0 // default layer
#define SHELL_NAV 1
#define KEY_NAV 3 // key navigation layer
#define KEY_SEL 4 // key selection layer
#define NUMBER 5 // number layer
#define SYMBOL 6
#define BRACKETS 7
#define SHORTCUTS 8
#define MOUSE 9
// macros
#define MC_COPY_LINE 0
#define MC_CUT_LINE 1
#define MC_PASTE_LINE 2
#define MC_NEW_SEARCH_TAB 3
#define SCREEN_TAB_LEFT 4
#define SCREEN_TAB_RIGHT 5
#define SCREEN_NEW_TAB 6
#define SWITCH_NDS 7
#define SCREEN_COPY_MODE 8
#define SCREEN_PASTE 9
#define OPEN_CLOSE_PAREN 10
#define OPEN_CLOSE_BRACKET 11
#define OPEN_CLOSE_CURLY 12
#define OPEN_CLOSE_SINGLE_QUOTE 13
#define OPEN_CLOSE_DOUBLE_QUOTE 14
#define SHELL_RECALL_LAST_ARG_REMOVE_FIRST_COMMAND 15
#define SEMICOLON_NEWLINE 16
#define END_NEWLINE 17
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(KEY_NAV), // FN1 - keynav layer
[2] = ACTION_LAYER_TAP_TOGGLE(NUMBER), // FN2 - number layer
[3] = ACTION_MODS_ONESHOT(MOD_LSFT), // FN3 - shift modifier / oneshot
[4] = ACTION_MODS_ONESHOT(MOD_LCTL), // FN4 - ctrl modifier / oneshot
[5] = ACTION_MODS_ONESHOT(MOD_LALT), // FN5 - alt modifier / oneshot
};
//Tap Dance Declarations
enum {
TD_SHIFT_CAPSLOCK = 0,
TD_BRK_LEFT = 1,
TD_BRK_RIGHT = 2
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// base layer
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
LT(MOUSE,KC_TAB), KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, MO(KEY_SEL),
MO(SHELL_NAV), KC_A, KC_O, KC_E, KC_U, KC_I,
KC_FN3, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, MO(KEY_NAV),
OSL(SHORTCUTS),KC_FN4, KC_FN5,OSL(SYMBOL),MO(NUMBER),
// thumb cluster
MO(BRACKETS), RCTL(KC_S),
RCTL(KC_DEL),
KC_BSPC,RCTL(KC_BSPC),KC_DEL,
// right hand
KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_BSLS,
KC_PGUP, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH,
KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS,
KC_PGDN, KC_B, KC_M, KC_W, KC_V, KC_Z, TD(TD_SHIFT_CAPSLOCK),
// lower keys - browser tab control
RSFT(RCTL(KC_TAB)), RCTL(KC_TAB), RCTL(KC_T), LALT(KC_LEFT), RCTL(KC_W),
// thumb cluster
KC_HOME,KC_END,
KC_UP,
KC_DOWN,KC_ENT, KC_SPC
),
// shell navigation layer
[SHELL_NAV] = KEYMAP(
// left hand
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,
// bottom row
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
// thumb cluster
KC_TRNS,KC_TRNS,
LALT(KC_D),
KC_TRNS,RCTL(KC_W),KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
RCTL(KC_L), RCTL(KC_W), KC_HOME, KC_UP, KC_END, LALT(KC_D), RCTL(KC_R),
LALT(KC_B), KC_LEFT, KC_DOWN, KC_RIGHT, LALT(KC_F), LALT(KC_DOT),
RCTL(KC_C), RCTL(KC_U), M(SCREEN_COPY_MODE), M(SCREEN_PASTE), MEH(KC_V), RCTL(KC_K), M(SHELL_RECALL_LAST_ARG_REMOVE_FIRST_COMMAND),
// bottom row
M(SCREEN_TAB_LEFT), M(SCREEN_TAB_RIGHT), M(SCREEN_NEW_TAB), KC_TRNS, KC_TRNS,
// thumb cluster
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
// key navigation layer
[KEY_NAV] = KEYMAP(
// left hand
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,
// bottom row
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
// thumb cluster
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_PGDN, KC_HOME, KC_UP, KC_END, KC_PGUP, M(MC_COPY_LINE),
RCTL(KC_LEFT), KC_LEFT, KC_DOWN, KC_RIGHT, RCTL(KC_RIGHT), M(MC_CUT_LINE),
KC_TRNS, KC_TRNS, RCTL(KC_C), RCTL(KC_X), RCTL(KC_V), KC_TRNS, M(MC_PASTE_LINE),
// bottom row
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
// thumb cluster
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
// key selection layer
[KEY_SEL] = KEYMAP(
// left hand
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,
// bottom row
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
// thumb cluster
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
RSFT(KC_PGUP), RSFT(KC_PGDN), RSFT(KC_HOME), RSFT(KC_UP), RSFT(KC_END), RSFT(KC_PGUP), M(MC_COPY_LINE),
RSFT(RCTL(KC_LEFT)), RSFT(KC_LEFT), RSFT(KC_DOWN), RSFT(KC_RIGHT), RSFT(RCTL(KC_RIGHT)), M(MC_CUT_LINE),
RSFT(KC_PGDN), KC_TRNS, RCTL(KC_C), RCTL(KC_X), RCTL(KC_V), KC_TRNS, M(MC_PASTE_LINE),
// bottom row
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
// thumb cluster
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
// number layer
[NUMBER] = KEYMAP(
// left hand
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,
// bottom row
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
// thumb cluster
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_PLUS, KC_7, KC_8, KC_9, KC_ASTR, KC_TRNS,
KC_MINS, KC_4, KC_5, KC_6, KC_SLSH, KC_TRNS,
KC_TRNS, KC_EQUAL, KC_1, KC_2, KC_3, KC_COLN, KC_TRNS,
// bottom row
KC_0, KC_DOT, KC_COMMA, KC_TRNS, KC_TRNS,
// thumb cluster
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
[SYMBOL] = KEYMAP(
// left hand
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,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_PLUS, KC_AMPR, KC_ASTR, KC_GRAVE,KC_TILD, KC_TRNS,
KC_MINS, KC_DLR, KC_PERC, KC_CIRC, KC_PIPE, KC_TRNS,
KC_TRNS, KC_EQUAL,KC_EXLM, KC_AT, KC_HASH, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
M(SEMICOLON_NEWLINE), M(END_NEWLINE),
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
[BRACKETS] = KEYMAP(
// left hand
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,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS, KC_TRNS, M(OPEN_CLOSE_BRACKET),M(OPEN_CLOSE_PAREN),M(OPEN_CLOSE_CURLY),KC_TRNS,KC_TRNS,
KC_TRNS, KC_LBRC, KC_RBRC, KC_LPRN, KC_RPRN, KC_TRNS,
KC_TRNS, KC_TRNS, KC_LCBR, KC_RCBR, 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
),
[SHORTCUTS] = KEYMAP(
// left hand
KC_NO, MEH(KC_F1), MEH(KC_F2), MEH(KC_F3), MEH(KC_F4), MEH(KC_F5), MEH(KC_F6),
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,
MEH(KC_0),MEH(KC_1),
MEH(KC_2),
MEH(KC_3),MEH(KC_4),MEH(KC_5),
// right hand
MEH(KC_F7), MEH(KC_F8), MEH(KC_F9), MEH(KC_F10), MEH(KC_F11), MEH(KC_F12), M(SWITCH_NDS),
KC_TRNS, MEH(KC_A), MEH(KC_B), MEH(KC_C), MEH(KC_D), MEH(KC_E), MEH(KC_F),
MEH(KC_G), MEH(KC_H), MEH(KC_I), MEH(KC_J), MEH(KC_K), MEH(KC_L),
KC_TRNS, MEH(KC_M), MEH(KC_N), MEH(KC_O), MEH(KC_P), MEH(KC_Q), MEH(KC_R),
MEH(KC_S), MEH(KC_T), MEH(KC_U), MEH(KC_V), MEH(KC_X),
MEH(KC_6), MEH(KC_7),
MEH(KC_8),
MEH(KC_9), MEH(KC_Y), MEH(KC_Z)
),
[MOUSE] = KEYMAP(
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, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, 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_BTN1, KC_BTN2
),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case MC_COPY_LINE:
if (record->event.pressed) {
return MACRO( T(HOME), D(LSFT), T(END), U(LSFT), D(LCTL), T(C), U(LCTL), END);
}
break;
case MC_CUT_LINE:
if (record->event.pressed) {
return MACRO( T(HOME), D(LSFT), T(END), U(LSFT), D(LCTL), T(X), U(LCTL), END);
}
break;
case MC_PASTE_LINE:
if (record->event.pressed) {
return MACRO( T(END), T(ENTER), D(LCTL), T(V), U(LCTL), END);
}
break;
case MC_NEW_SEARCH_TAB:
if (record->event.pressed) {
return MACRO( D(LCTL), T(T), T(K), U(LCTL), END);
}
break;
case SCREEN_TAB_LEFT:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(P), END);
}
break;
case SCREEN_TAB_RIGHT:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(N), END);
}
break;
case SCREEN_NEW_TAB:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(C), END);
}
break;
case SCREEN_COPY_MODE:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(ESC), END);
}
break;
case SCREEN_PASTE:
if (record->event.pressed) {
return MACRO( D(LCTL), T(A), U(LCTL), T(RBRC), END);
}
break;
case SWITCH_NDS:
if (record->event.pressed) {
return MACRO( D(LSFT), T(F11), U(LSFT), W(500), D(LALT), T(TAB), U(LALT), END);
}
break;
case OPEN_CLOSE_PAREN:
if (record->event.pressed) {
return MACRO( D(LSFT), T(LPRN), T(RPRN), U(LSFT), T(LEFT), END);
}
break;
case OPEN_CLOSE_BRACKET:
if (record->event.pressed) {
return MACRO( T(LBRC), T(RBRC), T(LEFT), END);
}
break;
case OPEN_CLOSE_CURLY:
if (record->event.pressed) {
return MACRO( D(LSFT), T(LCBR), T(RCBR), U(LSFT), T(LEFT), END);
}
break;
case OPEN_CLOSE_SINGLE_QUOTE:
if (record->event.pressed) {
return MACRO( T(QUOT), T(QUOT), T(LEFT), END);
}
break;
case OPEN_CLOSE_DOUBLE_QUOTE:
if (record->event.pressed) {
return MACRO( D(LSFT), T(QUOT), T(QUOT), U(LSFT), T(LEFT), END);
}
break;
case SHELL_RECALL_LAST_ARG_REMOVE_FIRST_COMMAND:
if (record->event.pressed) {
return MACRO( T(UP), T(HOME), D(LALT), T(D), U(LALT), END);
}
break;
case SEMICOLON_NEWLINE:
if (record->event.pressed) {
return MACRO( T(END), T(SCLN), T(ENTER), END);
}
break;
case END_NEWLINE:
if (record->event.pressed) {
return MACRO( T(END), T(ENTER), END);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
return;
};
void led_set_user(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
ergodox_right_led_1_on();
} else {
ergodox_right_led_1_off();
}
}
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_SHIFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPSLOCK),
[TD_BRK_LEFT] = ACTION_TAP_DANCE_DOUBLE (KC_LPRN, KC_LCBR),
[TD_BRK_RIGHT] = ACTION_TAP_DANCE_DOUBLE (KC_RPRN, KC_RCBR)
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case NUMBER:
case SYMBOL:
ergodox_right_led_2_on();
break;
case KEY_NAV:
case KEY_SEL:
ergodox_right_led_3_on();
break;
case SHORTCUTS:
ergodox_right_led_2_on();
ergodox_right_led_3_on();
break;
default:
// none
break;
}
return;
};

@ -3,6 +3,8 @@
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
COMMAND_ENABLE = no # Commands for debug and configuration
RGBLIGHT_ENABLE ?= yes
MIDI_ENABLE ?= yes
ifndef QUANTUM_DIR
include ../../../../Makefile

@ -8,5 +8,6 @@
#undef LEADER_TIMEOUT
#define LEADER_TIMEOUT 300
#endif

@ -7,11 +7,17 @@
#define SYMB 1 // symbols
#define MDIA 2 // media keys
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
RGB_FF00BB // always start with RGB_
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | = | 1 | 2 | 3 | 4 | 5 | LEFT | | RIGHT| 6 | 7 | 8 | 9 | 0 | - |
* | = | 1 | 2 | 3 | 4 | 5 |Ctrl- | | Ctrl+| 6 | 7 | 8 | 9 | 0 | - |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Del | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
@ -33,7 +39,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, LCTL(KC_MINS),
KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSPO, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_LBRC),
@ -42,7 +48,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_HOME,
KC_SPC,KC_LEAD,KC_END,
// right hand
KC_RGHT, KC_6,KC_7, KC_8, KC_9, KC_0, KC_MINS,
LCTL(KC_EQL), KC_6,KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(SYMB), KC_Y,KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H,ALT_T(KC_J),KC_K, KC_L, LT(MDIA,KC_SCLN),GUI_T(KC_QUOT),
MEH_T(KC_RBRC),KC_N,KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSPC,
@ -65,33 +71,33 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | |NxtTab|PrvTab| | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* | | | |TOG |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* |VAI |VAD |HUI | |SAI | |MOD |
* | | |------| |------| | |
* | | | | | | | |
* | | |HUD | |SAD | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
RGB_FF00BB, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5,
KC_TRNS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
KC_TRNS, KC_TRNS,KC_TRNS,LCTL(KC_PGUP), LCTL(KC_PGDN),
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
RGB_HUI,
RGB_VAI,RGB_VAD,RGB_HUD,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_F12,
KC_AMPR, KC_UNDS, KC_MINS, CM_SCLN, KC_PLUS, KC_TRNS,
KC_TRNS, KC_PIPE, KC_AT, KC_EQL, KC_PERC, 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
RGB_TOG, KC_TRNS,
RGB_SAI,
RGB_SAD, KC_TRNS, RGB_MOD
),
/* Keymap 2: Media and mouse keys
*
@ -152,6 +158,24 @@ void matrix_init_user(void) {
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case RGB_FF00BB:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_enable();
rgblight_mode(1);
rgblight_setrgb(0xff,0x00,0xbb);
#endif
}
return false;
break;
}
return true;
}
LEADER_EXTERNS();
// Runs constantly in the background, in a loop.

@ -4,6 +4,10 @@ This is my personal layout which I use to test out ideas which may or may not ma
Changelog:
## Nov 1, 2016:
* Adds dedicated text zooming keys in inner corners
## May 24, 2016:
* Implements Leader key example

@ -0,0 +1,2 @@
COMMAND_ENABLE = no # Commands for debug and configuration

@ -0,0 +1,183 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | + | 1 | 2 | 3 | 4 | 5 | rclk | | lclk | 6 | 7 | 8 | 9 | 0 | - |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | = | Q | W | E | R |cmd/T |shift | |shift |cmd/Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| ( | | ) |------+------+------+------+------+--------|
* | " | A | S | D | F | G |------| |------| H | J | K | L |; / L2| ' |
* |--------+------+------+------+------+------| ctrl | | ctrl |------+------+------+------+------+--------|
* | { | Z | X | C | V | B | [ | | ] | N | M | , | . | / | } |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | _ | ` | $ | Left | Right| | Up | Down | : | * | ! |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | < | | | | & | > |
* ,------|------|------| |------+--------+------.
* | | | # | | @ | | |
* | Space|Backsp|------| |------| Tab |Enter |
* | |ace | % | | ESC | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_PLUS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_BTN2,
KC_EQL, KC_Q, KC_W, KC_E, KC_R, GUI_T(KC_T), KC_LSPO,
KC_DQUO, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LCBR, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, CTL_T(KC_LBRC),
KC_UNDS, KC_GRV, KC_DLR, KC_LEFT,KC_RGHT,
KC_LABK, KC_PIPE,
KC_HASH,
KC_SPC, KC_BSPC,KC_PERC,
// right hand
KC_BTN1, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_RSPC, GUI_T(KC_Y), KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN), KC_QUOT,
CTL_T(KC_RBRC), KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RCBR,
KC_UP, KC_DOWN,KC_COLN,KC_ASTR, KC_EXLM,
KC_AMPR, KC_RABK,
KC_AT,
KC_ESC, KC_TAB, KC_ENT
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------.
* |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
M(0), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | | |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
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_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,11 @@
# Galson keymap
Sep 26, 2016.
This is an ergonomic layout for programming for those with typing-related injuries. Key features:
- As many symbol keys as possible are accessible without shifting. These should be accessed by moving the entire hand and pressing with a strong finger.
- Arrow keys and left and right mouse clicks for mouse-free navigation when combined with head mouse or eyetracker.
- Modifier keys are dual role and relocated to positions convenient for the index finger.
- Positions are more convenient when the keyboard is vertically mounted (as it should be!)

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

@ -0,0 +1,962 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "keymap_jp.h"
static uint16_t start;
#define BASE 0 // EN layer
#define JP 1 // Japanese
#define JPXON 2 // JP + Fn
#define JPKAZARI 3 // JP + KAZARI
#define JPTOPROW 4 // JP + TOPROW
#define JPTRKZ 5 // JP + TOPROW + KAZARI
#define NUM 6 // Numbers
#define CTLSHFT 1
#define CUTCOPY 2
//kana macro definitions start here
#define JPVU 4
#define JPNU 6
#define JPKO 7
#define JPSA 8
#define JPKE 9
#define JPHE 10
#define JPSHI 11
#define JPKA 12
#define JPKI 13
#define JPSU 14
#define JPSO 15
#define JPHI 16
#define JPCHI 17
#define JPFU 18
#define JPSE 19
#define JPTSU 20
#define JPKU 21
#define JPTE 22
#define JPTA 23
#define JPTO 24
#define JPHA 25
#define JPHO 26
#define JPXKE 27
#define JPXU 28
#define JPXKA 29
#define JPXA 30
#define JPXO 31
#define JPGO 32
#define JPZA 33
#define JPGE 34
#define JPBE 35
#define JPYU 36
#define JPJI 37
#define JPGA 38
#define JPGI 39
#define JPZU 40
#define JPZO 41
#define JPBI 42
#define JPDI 43
#define JPZE 44
#define JPDU 45
#define JPGU 46
#define JPYA 47
#define JPYO 48
#define JPDE 49
#define JPDA 50
#define JPDO 51
#define JPBA 52
#define JPBO 53
#define JPRI 54
#define JPRE 55
#define JPRA 56
#define JPNA 57
#define JPNO 58
#define JPMI 59
#define JPMU 60
#define JPME 61
#define JPNE 62
#define JPMA 63
#define JPXTU 64
#define JPWA 65
#define JPRU 66
#define JPWO 67
#define JPNI 68
#define JPNN 69
#define JPMO 70
#define JPRO 71
#define JPXE 72
#define JPXI 73
#define JPXYU 74
#define JPXYA 75
#define JPXYO 76
#define JPPE 77
#define JPPU 78
#define JPPI 79
#define JPPA 80
#define JPPO 81
#define JPBU 82
// kana macro definitions end here
#define SHIFT 86
#define KAZARI 87
#define JPFN 88 //shifts to JPXON layer
#define TOJPLOUT 89
#define TOENL 90
#define TOJPL 91
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
*
* ,----------------------------------------------------. ,--------------------------------------------------.
* | En / | | ^ | % | | |Selall| | Undo | | $ | @ | LT | UP | RT |
* |----------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | D | R | W | B | Cut | | PgUP | J | F | U | P | DN | \ |
* |----------+------+------+------+------+------| Copy | | |------+------+------+------+------+--------|
* | / | A | S | H | T | G |------| |------| Y | N | E | O | I | , |
* |----------+------+------+------+------+------|Paste | | PgDN |------+------+------+------+------+--------|
* | Ctl+Shft | Z | X | M | C | V | | | | . | L | K | ' | ? | tmux |
* `----------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | LCtrl | LGui | Alt| _ | Esc | |MouseL|MouseR| - | ~ | Ctrl |
* `------------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* |MidMs | Del | | VolUp| Mute |
* ,------|------|------| |------+--------+------.
* | | | | | VolDn| | |
* | Space| Shift|------| |------| Backsp |Enter |
* | | | Num | | Esc | | |
* `--------------------' `----------------------'
*
*
* tmux prefix set to C-b
*
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
M(TOJPLOUT), KC_NO, KC_EQL, LSFT(KC_5), KC_NO, KC_NO, LCTL(KC_A),
KC_TAB, KC_Q, KC_D, KC_R, KC_W, KC_B, M(CUTCOPY),
KC_SLSH, KC_A, KC_S, KC_H, KC_T, KC_G,
M(CTLSHFT), KC_Z, KC_X, KC_M, KC_C, KC_V, LCTL(KC_V),
KC_RCTL, KC_LGUI, KC_LALT,JP_UNDS,KC_LCTL,
KC_BTN3, KC_DEL,
KC_NO,
KC_SPC,KC_LSFT,F(1),
// right hand
LCTL(KC_Z), KC_NO, LSFT(KC_4), JP_AT, KC_LEFT, KC_UP, KC_RIGHT,
KC_PGUP, KC_J, KC_F, KC_U, KC_P, KC_DOWN, LSFT(KC_3),
KC_Y, KC_N, KC_E, KC_O, KC_I, KC_COMMA,
KC_PGDN, KC_DOT, KC_L, KC_K, LSFT(KC_7), KC_QUES, LCTL(KC_B),
KC_BTN1, KC_BTN2,KC_MINS,JP_TILD, KC_RCTL,
KC_VOLU, KC_MUTE,
KC_VOLD,
KC_SPC,KC_BSLS, KC_ENT
),
/* Keymap 1: Japanese
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | En / | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |   nu | ko | sa | he | ke | | | | fu | se | tsu | ku | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | to | shi | ka | ki | su |------| |------| a | ha | te | ta | u | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | mu | so | hi | chi | me | | | | | ma | ho | i | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | shift| fn |------| |------| |kazari|
* | | | Num | | | | |
* `--------------------' `--------------------'
*
*
*
*/
[JP] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, M(JPNU), M(JPKO), M(JPSA), M(JPHE), M(JPKE), KC_TRNS,
KC_TRNS, M(JPTO), M(JPSHI), M(JPKA), M(JPKI), M(JPSU),
KC_TRNS, M(JPMU), M(JPSO), M(JPHI), M(JPCHI), M(JPME), KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_NO,
M(SHIFT), M(JPFN), F(1),
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, M(JPFU), M(JPSE), M(JPTSU), M(JPKU), KC_TRNS, KC_TRNS,
KC_A, M(JPHA), M(JPTE), M(JPTA), KC_U, KC_TRNS,
KC_TRNS, KC_TRNS, M(JPMA), M(JPHO), KC_I, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,M(KAZARI)
),
/* Keymap 2: Japanese with Fn
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |   | xe | | | xke | | | | xya | | xtsu | xo | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | xka | | |------| |------| xa | xyo | | | xu | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | xi | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*
*
*
*/
[JPXON] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, M(JPXE), KC_NO, M(JPXKE), KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, M(JPXKA), KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_TRNS, KC_TRNS,
// right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, M(JPXYA), KC_NO, M(JPXTU), M(JPXO), KC_NO, KC_NO,
M(JPXA), M(JPXYO), M(JPXYU), KC_NO, M(JPXU), KC_NO,
KC_NO, KC_NO,KC_NO, KC_NO, M(JPXI), KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_NO, KC_NO
),
/* Keymap 3: Japanese with kazari
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |   | go | za | be | ge | | | | bu | ze | du | gu | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | do | ji | ga | gi | zu |------| |------| | ba | de | da | vu | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | zo | bi | di | | | | | | | bo | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*
*
*
*/
[JPKAZARI] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, M(JPGO), M(JPZA), M(JPBE), M(JPGE), KC_NO,
KC_NO, M(JPDO), M(JPJI), M(JPGA), M(JPGI), M(JPZU),
KC_NO, KC_NO, M(JPZO), M(JPBI), M(JPDI), KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
M(SHIFT), KC_NO, KC_TRNS,
// right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, M(JPBU), M(JPZE), M(JPDU), M(JPGU), KC_NO, KC_NO,
KC_NO, M(JPBA), M(JPDE), M(JPDA), M(JPVU), KC_NO,
KC_NO, KC_NO, KC_NO, M(JPBO), KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_NO, KC_TRNS
),
/* Keymap 4: Japanese with Toprow
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |   | e | - | re | | | | | ya | ne | ru | o | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | ra | ri | na | no | mi |------| |------| wa | yo | yu | ni | nn | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | mo | ro | wo | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*
*
*
*/
[JPTOPROW] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_E, KC_MINS, M(JPRE), KC_NO, KC_NO,
KC_NO, M(JPRA), M(JPRI), M(JPNA), M(JPNO), M(JPMI),
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_TRNS, KC_NO, KC_NO,
// right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, M(JPYA), M(JPNE), M(JPRU), KC_O, KC_NO, KC_NO,
M(JPWA), M(JPYO), M(JPYU), M(JPNI), M(JPNN), KC_NO,
KC_NO, KC_NO, M(JPMO), M(JPRO), M(JPWO), KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_NO, M(KAZARI)
),
/* Keymap 5: Japanese with Toprow and Kazari
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |   | | | pe | | | | | pu | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | pa | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | pi | | | | | | | | po | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*
*
*
*/
[JPTRKZ] = KEYMAP(
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, M(JPPE),KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, M(JPPI), KC_NO, KC_NO, KC_NO,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_TRNS, KC_NO, KC_NO,
// right hand
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, M(JPPU), KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, M(JPPA), KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, M(JPPO), KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_NO, KC_TRNS
),
/* Keymap 6: Number Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | " | [ | ] | | | | | % | 7 | 8 | 9 | | F12 |
* |--------+------+------+------+------+------| ; | | |------+------+------+------+------+--------|
* | | | / | + | { | } |------| |------| ! | 4 | 5 | 6 | 0 | , |
* |--------+------+------+------+------+------| : | | & |------+------+------+------+------+--------|
* | | | * | - | ( | ) | | | | . | 1 | 2 | 3 | ? | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | # | | < | = | > | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| Back | Ent |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// Numbers
[NUM] = KEYMAP(
// left hand
KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_NO,
KC_NO, KC_NO, KC_NO, JP_DQT, KC_RBRACKET, KC_BSPC, KC_SCLN,
KC_NO, KC_NO, KC_SLSH, JP_PLUS, LSFT(KC_RBRACKET), JP_RCBR,
KC_NO, KC_NO, JP_ASTR, KC_MINS, LSFT(KC_8), LSFT(KC_9), JP_COLN,
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_HASH,
KC_NO, KC_NO,
KC_NO,
KC_NO, KC_NO, KC_TRNS,
// right hand
KC_NO, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
LSFT(KC_JYEN), KC_PERC, KC_7, KC_8, KC_9, KC_NO, KC_F12,
KC_EXLM, KC_4, KC_5, KC_6, KC_0, KC_COMM,
LSFT(KC_6), KC_DOT, KC_1, KC_2, KC_3, KC_QUES, KC_NO,
KC_LT,JP_EQL, KC_GT, KC_NO, KC_NO,
KC_NO, KC_NO,
KC_NO,
KC_SPC, KC_BSLS, KC_DOT
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_MOMENTARY(NUM) // FN1 - Momentary Layer 6 (Numbers)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRO only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
case CTLSHFT:
if (record->event.pressed) {
return MACRO( D(LSFT), D(LCTL), END);
} else {
return MACRO( U(LSFT), U(LCTL), END);
}
break;
case CUTCOPY:
if (record->event.pressed) {
start = timer_read();
} else {
if (timer_elapsed(start) > 150) {
return MACRO( D(LCTL), T(X), U(LCTL), END);
} else {
return MACRO( D(LCTL), T(C), U(LCTL), END);
}
}
break;
// kana macros start here
case JPVU:
if (record->event.pressed) {
return MACRO( I(1), T(V), T(U), END);
}
break;
case JPNU:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(U), END);
}
break;
case JPKO:
if (record->event.pressed) {
return MACRO( I(1), T(K), T(O), END);
}
break;
case JPSA:
if (record->event.pressed) {
return MACRO( I(1), T(S), T(A), END);
}
break;
case JPKE:
if (record->event.pressed) {
return MACRO( I(1), T(K), T(E), END);
}
break;
case JPHE:
if (record->event.pressed) {
return MACRO( I(1), T(H), T(E), END);
}
break;
case JPSHI:
if (record->event.pressed) {
return MACRO( I(1), T(S), T(I), END);
}
break;
case JPKA:
if (record->event.pressed) {
return MACRO( I(1), T(K), T(A), END);
}
break;
case JPKI:
if (record->event.pressed) {
return MACRO( I(1), T(K), T(I), END);
}
break;
case JPSU:
if (record->event.pressed) {
return MACRO( I(1), T(S), T(U), END);
}
break;
case JPSO:
if (record->event.pressed) {
return MACRO( I(1), T(S), T(O), END);
}
break;
case JPHI:
if (record->event.pressed) {
return MACRO( I(1), T(H), T(I), END);
}
break;
case JPCHI:
if (record->event.pressed) {
return MACRO( I(1), T(T), T(I), END);
}
break;
case JPFU:
if (record->event.pressed) {
return MACRO( I(1), T(F), T(U), END);
}
break;
case JPSE:
if (record->event.pressed) {
return MACRO( I(1), T(S), T(E), END);
}
break;
case JPTSU:
if (record->event.pressed) {
return MACRO( I(1), T(T), T(U), END);
}
break;
case JPKU:
if (record->event.pressed) {
return MACRO( I(1), T(K), T(U), END);
}
break;
case JPTE:
if (record->event.pressed) {
return MACRO( I(1), T(T), T(E), END);
}
break;
case JPTA:
if (record->event.pressed) {
return MACRO( I(1), T(T), T(A), END);
}
break;
case JPTO:
if (record->event.pressed) {
return MACRO( I(1), T(T), T(O), END);
}
break;
case JPHA:
if (record->event.pressed) {
return MACRO( I(1), T(H), T(A), END);
}
break;
case JPHO:
if (record->event.pressed) {
return MACRO( I(1), T(H), T(O), END);
}
break;
case JPXKE:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(K), T(E), END);
}
break;
case JPXU:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(U), END);
}
break;
case JPXKA:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(K), T(A), END);
}
break;
case JPXA:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(A), END);
}
break;
case JPXO:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(O), END);
}
break;
case JPGO:
if (record->event.pressed) {
return MACRO( I(1), T(G), T(O), END);
}
break;
case JPZA:
if (record->event.pressed) {
return MACRO( I(1), T(Z), T(A), END);
}
break;
case JPGE:
if (record->event.pressed) {
return MACRO( I(1), T(G), T(E), END);
}
break;
case JPBE:
if (record->event.pressed) {
return MACRO( I(1), T(B), T(E), END);
}
break;
case JPYU:
if (record->event.pressed) {
return MACRO( I(1), T(Y), T(U), END);
}
break;
case JPJI:
if (record->event.pressed) {
return MACRO( I(1), T(J), T(I), END);
}
break;
case JPGA:
if (record->event.pressed) {
return MACRO( I(1), T(G), T(A), END);
}
break;
case JPGI:
if (record->event.pressed) {
return MACRO( I(1), T(G), T(I), END);
}
break;
case JPZU:
if (record->event.pressed) {
return MACRO( I(1), T(Z), T(U), END);
}
break;
case JPZO:
if (record->event.pressed) {
return MACRO( I(1), T(Z), T(O), END);
}
break;
case JPBI:
if (record->event.pressed) {
return MACRO( I(1), T(B), T(I), END);
}
break;
case JPDI:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(I), END);
}
break;
case JPZE:
if (record->event.pressed) {
return MACRO( I(1), T(Z), T(E), END);
}
break;
case JPDU:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(U), END);
}
break;
case JPGU:
if (record->event.pressed) {
return MACRO( I(1), T(G), T(U), END);
}
break;
case JPYA:
if (record->event.pressed) {
return MACRO( I(1), T(Y), T(A), END);
}
break;
case JPYO:
if (record->event.pressed) {
return MACRO( I(1), T(Y), T(O), END);
}
break;
case JPDE:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(E), END);
}
break;
case JPDA:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(A), END);
}
break;
case JPDO:
if (record->event.pressed) {
return MACRO( I(1), T(D), T(O), END);
}
break;
case JPBA:
if (record->event.pressed) {
return MACRO( I(1), T(B), T(A), END);
}
break;
case JPBO:
if (record->event.pressed) {
return MACRO( I(1), T(B), T(O), END);
}
break;
case JPRI:
if (record->event.pressed) {
return MACRO( I(1), T(R), T(I), END);
}
break;
case JPRE:
if (record->event.pressed) {
return MACRO( I(1), T(R), T(E), END);
}
break;
case JPRA:
if (record->event.pressed) {
return MACRO( I(1), T(R), T(A), END);
}
break;
case JPNA:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(A), END);
}
break;
case JPNO:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(O), END);
}
break;
case JPMI:
if (record->event.pressed) {
return MACRO( I(1), T(M), T(I), END);
}
break;
case JPMU:
if (record->event.pressed) {
return MACRO( I(1), T(M), T(U), END);
}
break;
case JPME:
if (record->event.pressed) {
return MACRO( I(1), T(M), T(E), END);
}
break;
case JPNE:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(E), END);
}
break;
case JPMA:
if (record->event.pressed) {
return MACRO( I(1), T(M), T(A), END);
}
break;
case JPXTU:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(T), T(U), END);
}
break;
case JPWA:
if (record->event.pressed) {
return MACRO( I(1), T(W), T(A), END);
}
break;
case JPRU:
if (record->event.pressed) {
return MACRO( I(1), T(R), T(U), END);
}
break;
case JPWO:
if (record->event.pressed) {
return MACRO( I(1), T(W), T(O), END);
}
break;
case JPNI:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(I), END);
}
break;
case JPNN:
if (record->event.pressed) {
return MACRO( I(1), T(N), T(N), END);
}
break;
case JPMO:
if (record->event.pressed) {
return MACRO( I(1), T(M), T(O), END);
}
break;
case JPRO:
if (record->event.pressed) {
return MACRO( I(1), T(R), T(O), END);
}
break;
case JPXE:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(E), END);
}
break;
case JPXI:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(I), END);
}
break;
case JPXYU:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(Y), T(U), END);
}
break;
case JPXYA:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(Y), T(A), END);
}
break;
case JPXYO:
if (record->event.pressed) {
return MACRO( I(1), T(X), T(Y), T(O), END);
}
break;
case JPPE:
if (record->event.pressed) {
return MACRO( I(1), T(P), T(E), END);
}
break;
case JPPU:
if (record->event.pressed) {
return MACRO( I(1), T(P), T(U), END);
}
break;
case JPPI:
if (record->event.pressed) {
return MACRO( I(1), T(P), T(I), END);
}
break;
case JPPA:
if (record->event.pressed) {
return MACRO( I(1), T(P), T(A), END);
}
break;
case JPPO:
if (record->event.pressed) {
return MACRO( I(1), T(P), T(O), END);
}
break;
case JPBU:
if (record->event.pressed) {
return MACRO( I(1), T(B), T(U), END);
}
break;
// kana macros end here
break;
case SHIFT:
if (record->event.pressed) {
start = timer_read();
if (layer_state == (1<<JPKAZARI)) {
layer_state = (1<<JPTOPROW)| (1<<JPTRKZ);
} else {
layer_state = (1<<JPTOPROW);
}
} else {
layer_state = (0<<JPTOPROW);
clear_keyboard_but_mods();
if (timer_elapsed(start) < 100) {
return MACRO( I(1), T(SPC), END);
}
}
break;
case KAZARI:
if (record->event.pressed) {
start = timer_read();
if (layer_state == (1<<JPTOPROW)) {
layer_state = (1<<JPKAZARI)| (1<<JPTRKZ);
} else {
layer_state = (1<<JPKAZARI);
}
break;
} else {
layer_state = (0<<JPKAZARI);
layer_state = (0<<JPTRKZ);
if (timer_elapsed(start) < 100) {
return MACRO( T(ENTER), END);
}
}
break;
case JPFN:
if (record->event.pressed) {
start = timer_read();
layer_state = (1<<JPXON);
} else {
layer_state = (0<<JPXON);
if (timer_elapsed(start) < 100) {
return MACRO( T(F7), END);
}
}
break;
case TOJPLOUT:
if (record->event.pressed) {
if (default_layer_state == (1<<JP)) {
default_layer_state = (0<<JP);
} else {
default_layer_state = (1<<JP);
}
return MACRO( T(ZKHK), END);
}
break;
/*
// TOJPL and TOENL switch keyboard language.
// The Ctrl+[] commands here load the appropriate ibus-anthy input engine via a WM shortcut
// The first key pressed in the new engine is missed, thus the space key
// TOJPLOUT works in the same way but is used for switching engines on external systems.
case TOJPL:
if (record->event.pressed) {
default_layer_state = (1<<JP);
return MACRO( D(LCTL), T(END), U(LCTL), END);
//return MACRO( D(LCTL), T(END), U(LCTL), W(250), W(250), W(250), T(SPACE), END);
}
break;
case TOENL:
if (record->event.pressed) {
default_layer_state = (1<<BASE);
return MACRO( D(LCTL), T(HOME), U(LCTL), END);
//return MACRO( D(LCTL), T(HOME), U(LCTL), W(250), W(250), W(250), T(SPACE), END);
}
break;
*/
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
uint8_t deflayer = biton32(default_layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 0:
//none
break;
// case 1:
// ergodox_right_led_2_on();
// break;
case 6:
ergodox_right_led_3_on();
break;
}
switch (deflayer) {
case 0:
ergodox_right_led_1_off();
break;
case 1:
ergodox_right_led_1_on();
break;
}
};

@ -0,0 +1,54 @@
This is a dual English-Japanese keymap that utilises a thumb-shift system for Japanese input. You can read more about this layout on my blog [here](https://ishigoya.com).
### Some Editing Necessary
The system I created this on is a Chromebook, and uses a Japanese keymap, so some of the key mappings may not be the same as those on your system. In particular, the Escape key on layer 0 is mapped to KC_LCTL.
### Layouts
------
#### English layer - layer 0
The English layout is a modified Workman layout, and is pictured below:
![English layout](img/keyboard-layout-enL.png)
Some of the punctuation keys have been moved to a separate number/symbol layer.
#### Number / Symbol layer - layer 6
The Number / Symbol layer is reachable through a ACTION_LAYER_MOMENTARY function. The blue LED is illuminated when this layer is active. It is accessible from the English or Japanese layers.
![Number layout](img/keyboard-layout-numL.png)
#### Japanese layers - layers 1-5
There are 5 layers involved in Japanese input. The TOJPLOUT macro is mapped to the En / 和 button, and switches default layer between layer 0 (English) and 1 (main Japanese layer). When layer 1 is the default layer, the red LED is on. It also outputs the ZKHK button to change the input method language.
On keypress, strings of romaji characters are output by the keyboard using macros, and these simulate the input of individual keys on a latin keyboard.
![Japanese layout](img/keyboard-layout-jpL.png)
Layer 1 is the JP layer. Keys on this layer correspond to singleton keys, or keys on the bottom row where a key is shared. For example, pressing the "ふ や" key outputs `ふ` (or "fu").
Layer 2 is the JPXON layer, and is active while holding the Fn key. This prints keys that are prefaced by "x" when writing in romaji. For example, pressing the "ふ や" key while holding the Fn key outputs `ゃ` (or "xya").
Layer 3 is the JPKAZARI layer, and is active while holding the 飾り key. This provides letters with dakuten. For example, pressing the "ふ や" key while holding the 飾り key outputs `ぶ` (or "bu").
Layer 4 is the JPTOPROW layer, and is active while holding the シフト key. Keys on this line correspond to top row keys on shared keys in the image. For example, pressing the "ふ や" key while holding the シフト key outputs `や` (or "ya").
Layer 5 is the JPTRKZ layer, and is active while holding both the シフト key and the 飾り key. This layer contains handakuten keys. For example, pressing the "ふ や" while holding both the シフト key and the 飾り key outputs `ぷ` (or "pu").
I've also separated out the #define sections and the macros required for kana for easy copying, in case anyone else should wish to make a kana-based layout.
When tapped, the シフト key acts as a space key, and the 飾り key acts as a return key. This allows them to function as 変換 and 無変換, respectively, in many IMEs.
Furthermore the Fn key, when tapped, acts as an F7 key, providing easy switching to katakana in many IMEs.
### Other features
The cut/copy button gives copy functionality on a short press, and cut functionality on a long press.
The tmux prefix button outputs Control-B.
The Control & Shift key acts as holding the control and shift keys at the same time.
SelAll outputs Control-A.
Undo outputs Control-Z.

@ -16,7 +16,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* |Ctrl/Esc| A | S | D | F | G |------| |------| H | J | K | L | ; | ' |
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
* | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
* | LShift | Z | X | C | V | B | | | | N | M | , | . | / | RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | ~L1 | Alt |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
* `----------------------------------' `----------------------------------'
@ -35,22 +35,22 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LBRC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_MINS,
CTL_T(KC_ESC), KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
KC_FN1, KC_LALT, LALT(KC_LSFT), KC_LEFT,KC_RGHT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
MO(SYMB), KC_LALT, LALT(KC_LSFT), KC_LEFT,KC_RGHT,
ALT_T(KC_APP), KC_HOME,
KC_END,
KC_SPC, KC_LGUI, KC_FN2,
KC_SPC,KC_LGUI,MO(MDIA),
// right hand
KC_RBRC, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
KC_EQL, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1,
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT,
KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, MO(SYMB),
KC_PGUP, CTL_T(KC_ESC),
KC_PGUP, CTL_T(KC_ESC),
KC_PGDN,
KC_FN1, KC_TAB, KC_ENT
MO(SYMB),KC_TAB, KC_ENT
),
/* Keymap 1: Symbol Layer
*

@ -0,0 +1,6 @@
RGBLIGHT_ENABLE ?= yes
MIDI_ENABLE ?= yes
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,17 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/* ws2812 RGB LED */
#define RGB_DI_PIN D7
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 15 // Number of LEDs
#define RGBLIGHT_HUE_STEP 12
#define RGBLIGHT_SAT_STEP 255
#define RGBLIGHT_VAL_STEP 12
#define RGB_MIDI
#define RGBW_BB_TWI
#endif

@ -19,14 +19,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_HOME,
KC_SPC,KC_SPC,KC_END,
// right hand
KC_NO, KC_6, KC_7, KC_8, KC_9, KC_0, KC_NO,
KC_NO, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_NO, M(1), KC_7, KC_8, KC_9, KC_0, KC_NO,
KC_NO, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, KC_P, KC_BSPC,
RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_SCLN, KC_QUOT,
KC_NO, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_ENT,
MO(1), KC_LEFT,KC_DOWN,KC_UP, KC_RGHT,
KC_NO, KC_NO,
KC_PGUP,
KC_PGDN, KC_SPC,KC_SPC
RGB_TOG, RGB_HUI,
RGB_MOD,
M(2), KC_SPC,KC_SPC
),
[SYMB] = KEYMAP(
// left hand
@ -84,6 +84,16 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
unregister_code(KC_RSFT);
}
break;
case 1:
if (record->event.pressed) { // For resetting EEPROM
eeconfig_init();
}
break;
case 2:
if (record->event.pressed) { // For resetting EEPROM
api_send_unicode(0x0CA0);
}
break;
}
return MACRO_NONE;
};

@ -0,0 +1,79 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#include "keymap_fr_ch.h"
#include "keymap_french.h"
#include "keymap_german.h"
#include "keymap_german_ch.h"
#include "keymap_nordic.h"
#include "keymap_norwegian.h"
#include "keymap_spanish.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP(NO_LESS,KC_1,KC_2,KC_3,KC_4,KC_5,KC_BSPACE,KC_TAB,KC_Q,KC_W,KC_E,KC_R,KC_T,TG(1),KC_BSPACE,KC_A,KC_S,KC_D,KC_F,KC_G,SFT_T(NO_APOS),CTL_T(KC_Z),KC_X,KC_C,KC_V,KC_B,SFT_T(KC_EQUAL),MO(1),CTL_T(KC_GRAVE),KC_LGUI,KC_LEFT,KC_RIGHT,KC_ESCAPE,KC_CAPSLOCK,KC_HOME,KC_SPACE,KC_LGUI,KC_LALT,KC_DELETE,KC_6,KC_7,KC_8,KC_9,KC_0,NO_PLUS,TG(1),KC_Y,KC_U,KC_I,KC_O,KC_P,NO_AM,KC_H,KC_J,KC_K,KC_L,LT(2,NO_OSLH),NO_AE,SFT_T(KC_RBRC),KC_N,KC_M,KC_COMMA,KC_DOT,CTL_T(KC_SLASH),SFT_T(NO_APOS),KC_DOWN,KC_UP,NO_LPRN,NO_RPRN,MO(1),NO_QUOT,CTL_T(KC_ESCAPE),NO_APOS,KC_LALT,KC_LGUI,KC_ENTER),
[1] = KEYMAP(M(0),KC_F1,KC_F2,KC_F3,KC_F4,KC_F5,KC_BSPACE,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_BSPACE,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_LSHIFT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_LCTL,KC_LGUI,KC_LEFT,KC_RIGHT,KC_ESCAPE,KC_TRANSPARENT,KC_HOME,KC_SPACE,KC_LGUI,KC_LALT,KC_DELETE,KC_F6,KC_F7,KC_F8,KC_F9,KC_F10,KC_F11,KC_TRANSPARENT,KC_7,KC_8,KC_9,KC_TRANSPARENT,KC_TRANSPARENT,KC_F12,KC_4,KC_5,KC_6,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_0,KC_1,KC_2,KC_3,NO_LBRC,NO_RBRC,KC_LSHIFT,KC_COMMA,KC_DOT,LSFT(NO_LBRC),LSFT(NO_RBRC),KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_LALT,KC_LGUI,KC_ENTER),
[2] = KEYMAP(KC_ESCAPE,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_MS_UP,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_MS_LEFT,KC_MS_DOWN,KC_MS_RIGHT,KC_TRANSPARENT,KC_LSHIFT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_LCTL,KC_LALT,KC_LGUI,KC_MS_BTN1,KC_MS_BTN2,KC_ESCAPE,KC_TRANSPARENT,KC_TRANSPARENT,KC_SPACE,KC_LGUI,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_MEDIA_PREV_TRACK,KC_MEDIA_PLAY_PAUSE,KC_MEDIA_NEXT_TRACK,KC_TRANSPARENT,KC_TRANSPARENT,KC_AUDIO_VOL_UP,KC_AUDIO_VOL_DOWN,KC_AUDIO_MUTE,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_ESCAPE,KC_MS_WH_UP,KC_MS_WH_DOWN,KC_MS_ACCEL0,KC_MS_ACCEL1),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(1)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
}
return MACRO_NONE;
};
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
break;
case 4:
ergodox_right_led_1_on();
ergodox_right_led_2_on();
break;
case 5:
ergodox_right_led_1_on();
ergodox_right_led_3_on();
break;
case 6:
ergodox_right_led_2_on();
ergodox_right_led_3_on();
break;
case 7:
ergodox_right_led_1_on();
ergodox_right_led_2_on();
ergodox_right_led_3_on();
break;
default:
break;
}
};

@ -0,0 +1,184 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | _ | | Del | 6 | 7 | 8 | 9 | 0 | - |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | = | A | S | D | F | G |------| |------| H | J | K | L |; / L2|' / Cmd |
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
* | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |Grv/L1| '" |AltShf| Left | Right| | Down | UP | [ | ] | ~L1 |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | App | Home | | Alt |Ctrl/Esc|
* ,------|------|------| |------+--------+------.
* | | | End | | PgUp | | |
* | Space|Backsp|------| |------| Enter |Space |
* | |ace | LGui | | PgDn | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, LSFT(KC_MINS),
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_EQL, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_LEFT,KC_RGHT,
ALT_T(KC_APP), KC_HOME,
KC_END,
KC_SPC,KC_BSPC,KC_LGUI,
// right hand
KC_DELT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_DOWN,KC_UP ,KC_LBRC,KC_RBRC, KC_FN1,
KC_LALT, CTL_T(KC_ESC),
KC_PGUP,
KC_PGDN,KC_ENT, KC_SPC
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | F11 | F12 | | | | | | | Up | 7 | 8 | 9 | * | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | 0 | 0 | . | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS,KC_F11, KC_F12, 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,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_TRNS,
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_0, KC_0, KC_DOT, KC_EQL, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | Lclk | Rclk | |VolDn |VolUp | Mute | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | | |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
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_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,10 @@
# ErgoDox EZ Phoenix Configuration
I started working using the default layout. The changes that I made are largely things that I consistely do wrong.
As a programmer I hit tab a lot for autocomplete so that muscle memory is very difficult to re-write. The stragest change might be all the keys that I cleared in the Code layer. This is mainly to facilitate quickly typing uuids, as sometimes it is quite tedious to copy/paste them from one window to the other.
## Changelog
* April 25, 2016 (V1.0):
* Initial submission.

@ -13,20 +13,16 @@ enum {
QWERTY,
CARPALX,
SYSCTL,
MOUSE,
};
// extra keys
enum {
NONE = 0,
// mouse
MS_UL, // up left
MS_UR, // up right
MS_DL, // down left
MS_DR, // down right
// tap dance
TD_FLSH, // flash keyboard
TD_LAYR, // SYSCTL and MOUSE layer switch
};
// application selection
@ -49,10 +45,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* | | | | | | |SYSCTL| | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* |BEGIN |QWERTY| |SYSCTL| |
* |BEGIN |QWERTY| | | |
* ,------|------|------| |------+--------+------.
* | | |CARPAL| |Slack | | |
* |Backsp|LShift|------| |------| Enter |Space |
@ -66,15 +62,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,TG(BEGIN) ,TG(QWERTY)
,TG(CARPALX)
,KC_BSPC ,KC_LSFT ,TG(SYSCTL)
,TG(BEGIN) ,TD(TD_LAYR)
,TG(MOUSE)
,KC_BSPC ,KC_LSFT ,TD(TD_LAYR)
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,MO(SYSCTL) ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,TG(SYSCTL) ,KC_NO
,AP_SLCK
@ -85,7 +81,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* a beginner's keymap i currently use.
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | 1 | 2 | 3 | 4 | 5 | 6 | | 6 | 7 | 8 | 9 | 0 | - | = |
* | | 1 | 2 | 3 | 4 | 5 | opt | | 6 | 7 | 8 | 9 | 0 | - | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | W | E | R | T | [ | | ] | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
@ -104,7 +100,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `--------------------' `----------------------'
*/
[BEGIN] = KEYMAP(
KC_TRNS ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 ,KC_6
KC_TRNS ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 ,KC_LALT
,KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_LBRC
,CTL_T(KC_ESC) ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G
,KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B ,KC_LPRN
@ -114,11 +110,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_TRNS
,KC_TRNS ,KC_TRNS ,KC_TRNS
,KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINS ,KC_EQL
,KC_RBRC ,KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_BSLS
,KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_ENT
,KC_RPRN ,KC_N ,KC_M ,KC_COMM ,KC_DOT ,KC_SLSH ,KC_RSFT
,KC_UP ,KC_DOWN ,KC_TRNS ,KC_QUOT ,KC_TRNS
,KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINS ,KC_EQL
,KC_RBRC ,KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_BSLS
,KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_ENT
,KC_RPRN ,KC_N ,KC_M ,KC_COMM ,KC_DOT ,KC_SLSH ,KC_RSFT
,KC_TRNS ,KC_DOWN ,KC_TRNS ,KC_QUOT ,KC_TRNS
,KC_TRNS ,KC_TRNS
,KC_TRNS
@ -213,30 +209,73 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_TRNS ,KC_TRNS ,KC_TRNS
),
/* SYSCTL
* a keymap to control my system.
*
* ,--------------------------------------------------. ,------------------------------------------------------.
* | ^ | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+----------+------+------+--------|
* | | | | | | | | | | Mute | Home | Up | End | | |
* |--------+------+------+------+------+------| | | |------+------+----------+------+------+--------|
* | | | | | | |------| |------|VolUp | Left | Down |Right | | Lock |
* |--------+------+------+------+------+------| | | |------+------+----------+------+------+--------|
* | | | | | | | | | |VolDn | Prev |Play/Pause| Next | | Sleep |
* `--------+------+------+------+------+-------------' `-------------+------+----------+------+------+--------'
* | | | | | | | | | | | Power|
* `----------------------------------' `--------------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | ^ | | | | |
* `--------------------' `--------------------'
*/
[SYSCTL] = KEYMAP(
KC_TRNS ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO
,KC_NO
,KC_NO ,KC_NO ,KC_TRNS
/*,KC_POP /// */,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
/* /// ,KC_PTRN*/,KC_NO ,KC_MUTE ,KC_HOME ,KC_UP ,KC_END ,KC_NO ,KC_NO
,KC_VOLU ,KC_LEFT ,KC_DOWN ,KC_RGHT ,KC_NO ,LCTL(LSFT(KC_PWR))
,KC_NO ,KC_VOLD ,KC_MPRV ,KC_MPLY ,KC_MNXT ,KC_NO ,KC_SLEP
,KC_TRNS ,KC_NO ,KC_NO ,KC_NO ,KC_PWR
,KC_NO ,KC_NO
,KC_NO
,KC_NO ,KC_NO ,KC_NO
),
/* MOUSE
* a keymap to control my system.
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | Mute |VolDn |VolUp | |
* | ^ | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | |MsUpL | MsUp |MsUpR | | |
* | | | | | | | | | | | | MsUp | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| |MsLeft| MsDn |MsRght| | Lock |
* | | | | | | |------| |------| |MsLeft| MsDn |MsRght| | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | |MsDnL | MsDn | | | Sleep |
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | Power|
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | |MidClk|
* ,------|------|------| |------+------+------.
* | | | | | |Left |Right |
* | | |------| |------| Click| Click|
* | | | | | | | |
* | | | ^ | | | | |
* `--------------------' `--------------------'
*/
[SYSCTL] = KEYMAP(
[MOUSE] = KEYMAP(
KC_TRNS ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
@ -245,13 +284,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_NO ,KC_NO
,KC_NO
,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_TRNS
/*,KC_POP*/,KC_NO ,KC_NO ,KC_NO ,KC_MUTE ,KC_VOLD ,KC_VOLU ,KC_NO
/*,KC_PTRN*/,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,LCTL(LSFT(KC_PWR))
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_SLEP
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_PWR
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_MS_U ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_MS_L ,KC_MS_D ,KC_MS_R ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO
,KC_NO ,KC_NO
,KC_NO
@ -341,48 +380,29 @@ void matrix_init_user() {
ergodox_led_all_off();
}
// extra keys
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch (id) {
// light up leds based on the layer
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
// mouse
case MS_UL:
if (record->event.pressed) {
mousekey_on(KC_MS_UP);
mousekey_on(KC_MS_LEFT);
} else {
mousekey_off(KC_MS_UP);
mousekey_off(KC_MS_LEFT);
}
break;
case MS_UR:
if (record->event.pressed) {
mousekey_on(KC_MS_UP);
mousekey_on(KC_MS_RIGHT);
} else {
mousekey_off(KC_MS_UP);
mousekey_off(KC_MS_RIGHT);
}
switch(layer) {
case SYSCTL:
ergodox_right_led_3_on();
break;
case MS_DL:
if (record->event.pressed) {
mousekey_on(KC_MS_DOWN);
mousekey_on(KC_MS_LEFT);
} else {
mousekey_off(KC_MS_DOWN);
mousekey_off(KC_MS_LEFT);
}
case MOUSE:
ergodox_right_led_2_on();
break;
case MS_DR:
if (record->event.pressed) {
mousekey_on(KC_MS_DOWN);
mousekey_on(KC_MS_RIGHT);
} else {
mousekey_off(KC_MS_DOWN);
mousekey_off(KC_MS_RIGHT);
}
default:
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
break;
}
}
// extra keys
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch (id) {
}
return MACRO_NONE;
}
@ -425,6 +445,31 @@ void flash_dance_reset(qk_tap_dance_state_t *state, void *user_data) {
ergodox_right_led_3_off();
}
// SYSCTL on first tap, MOUSE ON second tap
void layers_dance_finished(qk_tap_dance_state_t *state, void *user_data) {
uint8_t layer = biton32(layer_state);
switch(state->count) {
case 1:
switch(layer) {
case SYSCTL:
layer_off(SYSCTL);
break;
case MOUSE:
layer_off(MOUSE);
break;
default:
layer_on(SYSCTL);
break;
}
break;
case 2:
layer_on(MOUSE);
break;
}
}
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED( flash_each_tap, flash_dance_finished, flash_dance_reset ),
[TD_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED( NULL, layers_dance_finished, NULL ),
};

@ -0,0 +1,140 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
EPRM,
VRSN,
RGB_SLD
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | = | 1 | 2 | 3 | 4 | 5 | LEFT | | RIGHT| 6 | 7 | 8 | 9 | 0 | - |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Del | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | BkSp | A | S | D | F | G |------| |------| H | J | K | L |; / L2|' / Cmd |
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
* | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |Grv/L1| '" |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | App | LGui | | Alt |Ctrl/Esc|
* ,------|------|------| |------+--------+------.
* | | | Home | | PgUp | | |
* | Space|Backsp|------| |------| Tab |Enter |
* | |ace | End | | PgDn | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM,EPRM,
EPRM, EPRM,
EPRM,
EPRM,EPRM,EPRM,
// right hand
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM, EPRM, EPRM, EPRM,
EPRM, EPRM, EPRM, EPRM, EPRM,EPRM,
EPRM,EPRM, EPRM, EPRM,EPRM, EPRM, EPRM,
EPRM, EPRM,EPRM,EPRM, EPRM,
EPRM, EPRM,
EPRM,
EPRM,EPRM, EPRM
)
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
case 1:
if (record->event.pressed) { // For resetting EEPROM
eeconfig_init();
}
break;
}
return MACRO_NONE;
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case EPRM:
if (record->event.pressed) {
eeconfig_init();
}
return false;
break;
case VRSN:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
return false;
break;
case RGB_SLD:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_mode(1);
#endif
}
return false;
break;
}
return true;
}
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,151 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
RGB_FF0000,
RGB_00FF00,
RGB_0000FF,
RGB_FFFFFF,
RGB_TOGGLE,
LED1,
LED2,
LED3
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP(
RGB_TOGGLE, RGB_FF0000, RGB_00FF00, RGB_0000FF, RGB_FFFFFF, KC_5, KC_LPRN,
KC_GRAVE, KC_A, KC_B, KC_C, KC_D, KC_E, KC_EXLM,
KC_HASH, KC_J, KC_K, KC_L, KC_M, KC_N,
KC_AMPR, KC_T, KC_U, KC_V, KC_W, KC_X, KC_DLR,
KC_PIPE, KC_R, KC_PLUS, KC_LCBR, KC_RCBR,
KC_F, KC_G,
KC_H,
KC_P, KC_O, KC_I,
// RIGHT HAND
KC_RPRN, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_AT, KC_F, KC_G, KC_H, KC_I, KC_COLN, KC_BSLS,
KC_O, KC_P, KC_Q, KC_R, KC_S, KC_QUOT,
LSFT(KC_COMM), KC_Y, KC_Z, KC_COMM, KC_DOT, KC_SLSH, KC_ASTR,
KC_A, KC_B, KC_C, KC_D, KC_PIPE,
LED1, KC_E,
LED2,
LED3, KC_J, KC_K
)
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(1)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
}
return MACRO_NONE;
};
bool status_led1_on = false, status_led2_on = false, status_led3_on = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case RGB_FF0000:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
EZ_RGB(0xff0000);
register_code(KC_1); unregister_code(KC_1);
#endif
}
return false;
break;
case RGB_00FF00:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
EZ_RGB(0x00ff00);
register_code(KC_2); unregister_code(KC_2);
#endif
}
return false;
break;
case RGB_0000FF:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
EZ_RGB(0x0000ff);
register_code(KC_3); unregister_code(KC_3);
#endif
}
return false;
break;
case RGB_FFFFFF:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
EZ_RGB(0xffffff);
register_code(KC_4); unregister_code(KC_4);
#endif
}
return false;
break;
case RGB_TOGGLE:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_toggle();
register_code(KC_EQL); unregister_code(KC_EQL);
#endif
}
return false;
break;
case LED1:
if (record->event.pressed) {
if(status_led1_on) {
ergodox_right_led_1_off();
status_led1_on = false;
} else {
ergodox_right_led_1_on();
status_led1_on = true;
}
}
return false;
break;
case LED2:
if (record->event.pressed) {
if(status_led2_on) {
ergodox_right_led_2_off();
status_led2_on = false;
} else {
ergodox_right_led_2_on();
status_led2_on = true;
}
}
return false;
break;
case LED3:
if (record->event.pressed) {
if(status_led3_on) {
ergodox_right_led_3_off();
status_led3_on = false;
} else {
ergodox_right_led_3_on();
status_led3_on = true;
}
}
return false;
break;
}
return true;
}

@ -0,0 +1,5 @@
# Robot test layout
Use this layout if you like to pretend you're [Norman](https://www.youtube.com/watch?v=-sbxFBay-tg), the ErgoDox EZ manufacturing robot.
It's really meant just for internal use, but we're posting it on GitHub anyway, because hurray to open source. :)

@ -1,14 +1,3 @@
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
CUSTOM_MATRIX = yes # Custom matrix file for the ErgoDox EZ
SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
MIDI_ENABLE = no # MIDI controls
UNICODE_ENABLE = yes # Unicode
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -15,7 +15,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LGUI, KC_GRV, KC_BSLS, KC_LEFT, KC_RGHT,
KC_LCTL, KC_LALT,
KC_HOME,
KC_SPC, KC_BSPC, KC_END,
KC_BSPC, KC_DEL, KC_END,
// right hand
MO(FN2), KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_LBRC, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_RBRC,

@ -1,3 +1,4 @@
# sethbc's Ergodox EZ keymap
Largely based on the Ergodox Infinity default keymap
Largely based on the Ergodox Infinity default keymap, but layer locking has been
removed in favor of momentary layer activation

@ -0,0 +1,213 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic Dvorak layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | Hebrew | 1 | 2 | 3 | 4 | 5 |ALT+S | |B.tick| 6 | 7 | 8 | 9 | 0 | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | TAB | ' | , | . | P | Y | LCK2 | | | F | G | C | R | L | / |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | ESC | A | O | E | U | I |------| |------| D | H | T | N | S | - |
* |--------+------+------+------+------+------| LCK1 | | |------+------+------+------+------+--------|
* | LShift | ; | Q | J | K | X | | | | B | M | W | V | Z | RSHIFT |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |FN2 | COPY | CUT | PASTE| FN1 | | [ | ] | \ | UNDO | CTRL+A |
* `----------------------------------' `------------------------------------'
* ,-------------. ,-------------.
* | DEL | | | END | HOME |
* ,------|------|------| |------+--------+------.
* | | | SUPER| | PgUp | | |
* | BACK | CTRL |------| |------| Enter |SPACE |
* | SPACE| | ALT | | PgDn | | |
* `--------------------' `----------------------'
*/
[0] = KEYMAP(
TG(1), KC_1, KC_2, KC_3, KC_4, KC_5, LALT(KC_LSHIFT),
KC_TAB, KC_QUOTE, KC_COMMA, KC_DOT, KC_P, KC_Y, TG(3),
KC_ESCAPE, KC_A, KC_O, KC_E, KC_U, KC_I,
KC_LSHIFT, KC_SCOLON, KC_Q, KC_J, KC_K, KC_X, TG(2),
MO(3), LCTL(KC_C), LCTL(KC_X), LCTL(KC_V), MO(2),
KC_DELETE, KC_TRNS,
KC_LGUI,
KC_BSPACE,CTL_T(KC_NO),KC_LALT,
KC_TILD, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQUAL,
KC_TRNS, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLASH,
KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINUS,
KC_TRNS, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_LSHIFT,
KC_LBRACKET, KC_RBRACKET, KC_BSLASH, KC_UNDO, LCTL(KC_A),
KC_END, KC_HOME,
KC_PGUP,
KC_PGDOWN, KC_ENTER, KC_SPACE
),
/* Keymap 1: Hebrew layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
[1] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_W, KC_QUOTE, KC_SLASH, KC_R, KC_T, KC_TRNS,
KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_TRNS, KC_Z, KC_X, KC_C, KC_V, KC_B, 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_Y, KC_U, KC_E, KC_O, KC_P, KC_TRNS,
KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_TRNS,
KC_TRNS, KC_N, KC_M, KC_COMMA, KC_DOT, KC_I, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Arrows ,Mouse Navigation and F Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | F11 | | | UP | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | LEFT | DOWN | RIGHT| | |
* |--------+------+------+------+------+------| | | F12 |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | Lclk | Rclk | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
[2] = KEYMAP(
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_UP, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, 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_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
KC_F11, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_TRNS,
KC_F12, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_MS_BTN1, KC_MS_BTN2, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 3: Numpad Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | NMLK | P/ | P* | P- | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | | 7 | 8 | 9 | P+ | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | 4 | 5 | 6 | P+ | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | 1 | 2 | 3 | ENTER| |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | 0 | 0 | . | ENTER| |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
[3] = KEYMAP(
// Left Hand
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,KC_TRNS,KC_TRNS,
// Right Hand
KC_TRNS, KC_TRNS, KC_LOCKING_NUM, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_PLUS, KC_TRNS,
KC_TRNS, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_KP_1, KC_KP_2, KC_KP_3, KC_ENTER, KC_TRNS,
KC_KP_0, KC_KP_0, KC_KP_DOT, KC_ENTER, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(1)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
}
return MACRO_NONE;
};
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
default:
break;
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

@ -0,0 +1,10 @@
#Dvorak-Hebrew
* This layout solves the problem of Dvorak Keyboard with OS QWERTY, which when you change to hebrew all the letters scrumble, the second layer is the Hebrew (top left button), which you can use on any computer, Plug and play.
* The Hebrew layout itself solve another problem with the different locations of punctuation on Dvorak/Hebrew with few minor changes, it's based on Yuval Rabinovich's layout which you can find here : http://heboard.wordpress.com for regular QWERTY keyboards and for other operation systems.
* these are only good when using a public computer or one you can't change settings on, because you need to change both keyboard layout and os layout each time you change language. A better solution is to use [hebrew-hw-dvorak](https://github.com/20lives/hebrew-hw-dvorak) as os layout.
![layout image](https://github.com/20lives/qmk_firmware/blob/master/keyboards/ergodox/keymaps/twentylives_dvorak_with_hebrew/keymap.png)
![layout image](https://github.com/20lives/qmk_firmware/blob/master/keyboards/ergodox/keymaps/twentylives_dvorak_with_hebrew/keymap2.png)

@ -0,0 +1,19 @@
AUDIO_ENABLE:=no
BACKLIGHT_ENABLE:=no
BLUETOOTH_ENABLE:=no
BOOTMAGIC_ENABLE:=no
COMMAND_ENABLE:=no
CONSOLE_ENABLE:=no
EXTRAKEY_ENABLE:=yes
MIDI_ENABLE:=no
MOUSEKEY_ENABLE:=yes
NKRO_ENABLE:=no
RGBLIGHT_ENABLE:=no
SLEEP_LED_ENABLE:=no
TAP_DANCE_ENABLE:=yes
UNICODEMAP_ENABLE:=no
UNICODE_ENABLE:=no
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,13 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#ifndef NO_DEBUG
#define NO_DEBUG
#endif
#ifndef NO_PRINT
#define NO_PRINT
#endif
#endif

@ -0,0 +1,179 @@
#include <stdbool.h>
#include "ergodox.h"
#include "action_layer.h"
enum {
BASE = 0, // Default layer
ARROWS = 1, // Arrows and Fx keys layer
MOUSE = 2, // Mouse movement and buttons layer
PARENS = 3, // Parenthesis easy access layer
TD_L = 0, // Tap dance index for left shift
TD_R = 1 // Tap dance index for right shift
};
// See the videck.png image for a visualization of the layout.
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[BASE] = KEYMAP(
// left hand
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_HOME,
KC_EQL, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_END,
MO(PARENS), KC_A, KC_S, KC_D, KC_F, KC_G,
TD(TD_L), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_BSPC,
KC_LCTL, KC_LALT, KC_VOLD, KC_VOLU, KC_MUTE,
KC_ESC, KC_LGUI,
TG(MOUSE),
KC_SPC, KC_TAB, TG(ARROWS),
// right hand
KC_PGUP, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
KC_PGDN, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_DELT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, TD(TD_R),
KC_LBRC, KC_RBRC, KC_EQL, KC_RALT, KC_RCTL,
KC_APP, KC_ESC,
KC_INS,
KC_SLCK, KC_ENT, KC_SPC
),
[ARROWS] = KEYMAP(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, 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_NO,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_F12,
KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, 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
),
[MOUSE] = KEYMAP(
// left hand
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_BTN3, KC_TRNS,
KC_TRNS,
KC_BTN1, KC_BTN2, KC_NO,
// right hand
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_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, 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
),
[PARENS] = KEYMAP(
// left hand
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_NO,
KC_TRNS, KC_TRNS, KC_NO,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LCBR, KC_RCBR, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_LPRN, KC_RPRN, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LBRC, KC_RBRC, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
)
};
typedef void (*videck_tap_dance_trigger_t) (const uint16_t kc);
typedef struct
{
uint16_t kc1;
uint16_t kc2;
videck_tap_dance_trigger_t trigger;
} videck_tap_dance_tuple_t;
static void videck_tap_dance_finished (qk_tap_dance_state_t *state, void *user_data) {
videck_tap_dance_tuple_t *const tuple = (videck_tap_dance_tuple_t *)user_data;
if (state->count == 1) {
register_code16 (tuple->kc1);
} else if (state->count == 2) {
register_code16 (tuple->kc2);
}
}
static void videck_tap_dance_reset (qk_tap_dance_state_t *state, void *user_data) {
videck_tap_dance_tuple_t *const tuple = (videck_tap_dance_tuple_t *)user_data;
if (state->count == 1) {
unregister_code16 (tuple->kc1);
} else if (state->count == 2) {
unregister_code16 (tuple->kc2);
tuple->trigger(tuple->kc2);
}
}
static bool caps_lock_is_on;
// Toggles caps lock status.
static void videck_caps_trigger (const uint16_t kc) {
caps_lock_is_on ^= true;
}
#define ACTION_TAP_DANCE_DOUBLE_TRIGGER(kc1, kc2, double_trigger) { \
.fn = { NULL, videck_tap_dance_finished, videck_tap_dance_reset }, \
.user_data = (void *)&((videck_tap_dance_tuple_t) { kc1, kc2, double_trigger }), \
}
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_L] = ACTION_TAP_DANCE_DOUBLE_TRIGGER(KC_LSFT, KC_CAPS, videck_caps_trigger),
[TD_R] = ACTION_TAP_DANCE_DOUBLE_TRIGGER(KC_RSFT, KC_CAPS, videck_caps_trigger)
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
ergodox_led_all_set(LED_BRIGHTNESS_LO);
caps_lock_is_on = false;
};
static void indicate_using_led(const uint8_t led, const bool enabled) {
if (enabled) {
ergodox_right_led_on(led);
} else {
ergodox_right_led_off(led);
}
}
static inline void indicate_caps_lock_state(const bool enabled) {
indicate_using_led(1, enabled);
}
static inline void indicate_arrows_layer_state(const bool enabled) {
indicate_using_led(2, enabled);
}
static inline void indicate_mouse_layer_state(const bool enabled) {
indicate_using_led(3, enabled);
}
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
// Check if we have shift locked.
indicate_caps_lock_state(caps_lock_is_on);
indicate_arrows_layer_state(IS_LAYER_ON(ARROWS));
indicate_mouse_layer_state(IS_LAYER_ON(MOUSE));
};

@ -0,0 +1,24 @@
ViDeck keymap for ErgoDox
=========================
This is a QWERTY layout based on the US layout, where Vi functionality has been
especially considered.
# Features
* Mouse movements using the Vi movement keys.
* Vi movement keys doubling as arrow keys.
* Shift lock using double tap.
* A coder's modifier key for easy input of parenthesis.
* Acess to the escape key using either thumb.
* Reasonably accessible Scroll Lock key (useful if you, like me, want to switch
to a non-US layout once in a while in X).
# Missing keys
* Caps Lock (shift lock is used instead).
* Pause/Break.
* Print Screen.
# LEDs
* Shift lock is indicated using first LED.
* Arrow keys layer is indicated using second LED.
* Mouse keys layer is indicated using third LED.

@ -0,0 +1,443 @@
[
{
"backcolor": "#333333",
"background": {
"name": "PBT Black",
"style": "background-image: url('/bg/plastic/pbt-black.png');"
},
"switchMount": "cherry",
"switchBrand": "gateron",
"switchType": "KS-3-Red"
},
[
{
"x": 3.5,
"c": "#323232",
"t": "#ffffff\n\n\n#ac97d8"
},
"#\n3\n\nF3",
{
"x": 10.5
},
"*\n8\n\nF8"
],
[
{
"y": -0.875,
"x": 2.5
},
"@\n2\n\nF2",
{
"x": 1
},
"$\n4\n\nF4",
{
"x": 8.5
},
"&\n7\n\nF7",
{
"x": 1,
"t": "#ffffff\n\n\n#ac97d8\n\n\n\n#555454"
},
"(\n9\n\nF9"
],
[
{
"y": -0.875,
"x": 5.5,
"t": "#ffffff\n\n\n#ac97d8"
},
"%\n5\n\nF5",
{
"t": "#ffffff"
},
"home",
{
"x": 4.5
},
"pgup",
{
"t": "#ffffff\n\n\n#ac97d8"
},
"^\n6\n\nF6"
],
[
{
"y": -0.875,
"t": "#ffffff",
"w": 1.5
},
"~\n`",
{
"t": "#ffffff\n\n\n#ac97d8"
},
"!\n1\n\nF1",
{
"x": 14.5
},
")\n0\n\nF10",
{
"w": 1.5
},
"_\n-\n\nF11"
],
[
{
"y": -0.375,
"x": 3.5,
"t": "#ffffff"
},
"E",
{
"x": 10.5
},
"I"
],
[
{
"y": -0.875,
"x": 2.5
},
"W",
{
"x": 1
},
"R",
{
"x": 8.5
},
"U",
{
"x": 1,
"t": "#ffffff\n\n\n\n\n\n\n\n\n#f8d615"
},
"O\n\n\n\n\n\n\n\n\n{"
],
[
{
"y": -0.875,
"x": 5.5,
"t": "#ffffff"
},
"T",
{
"h": 1.5
},
"end",
{
"x": 4.5,
"h": 1.5
},
"pgdn",
"Y"
],
[
{
"y": -0.875,
"w": 1.5
},
"+\n=",
"Q",
{
"x": 14.5,
"t": "#ffffff\n\n\n\n\n\n\n\n\n#f8d615"
},
"P\n\n\n\n\n\n\n\n\n}",
{
"t": "#ffffff\n\n\n#ac97d8",
"w": 1.5
},
"|\n\\\n\nF12"
],
[
{
"y": -0.375,
"x": 3.5,
"t": "#ffffff"
},
"D",
{
"x": 10.5,
"t": "#ffffff\n\n#5eb1e7\n#ac97d8"
},
"K\n\n<i class='fa fa-caret-up'></i>\n<i class='kb kb-Arrows-Up'></i>"
],
[
{
"y": -0.875,
"x": 2.5,
"t": "#ffffff"
},
"S",
{
"x": 1,
"n": true
},
"F",
{
"x": 8.5,
"t": "#ffffff\n\n#5eb1e7\n#ac97d8",
"n": true
},
"J\n\n<i class='fa fa-caret-down'></i>\n<i class='kb kb-Arrows-Down'></i>",
{
"x": 1,
"t": "#ffffff\n\n#5eb1e7\n#ac97d8\n\n\n\n\n\n#f8d615"
},
"L\n\n<i class='fa fa-caret-right'></i>\n<i class='kb kb-Arrows-Right'></i>\n\n\n\n\n\n("
],
[
{
"y": -0.875,
"x": 5.5,
"t": "#ffffff"
},
"G",
{
"x": 6.5,
"t": "#ffffff\n\n#5eb1e7\n#ac97d8"
},
"H\n\n<i class='fa fa-caret-left'></i>\n<i class='kb kb-Arrows-Left'></i>"
],
[
{
"y": -0.875,
"t": "#f8d615",
"a": 6,
"w": 1.5
},
"( ) [ ] { }",
{
"t": "#ffffff",
"a": 4
},
"A",
{
"x": 14.5,
"t": "#ffffff\n\n\n\n\n\n\n#60605b\n\n#f8d615"
},
":\n;\n\n\n\n\n\n&Ouml;\n\n)",
{
"t": "#ffffff\n\n\n\n\n\n\n#60605b",
"w": 1.5
},
"\"\n'\n\n\n\n\n\n&Auml;"
],
[
{
"y": -0.625,
"x": 6.5,
"t": "#ffffff",
"h": 1.5
},
"<i class='kb kb-Unicode-BackSpace-DeleteLeft-Big'></i>",
{
"x": 4.5,
"h": 1.5
},
"<i class='kb kb-Unicode-DeleteRight-Big'></i>"
],
[
{
"y": -0.75,
"x": 3.5
},
"C",
{
"x": 10.5
},
"<\n,"
],
[
{
"y": -0.875,
"x": 2.5
},
"X",
{
"x": 1
},
"V",
{
"x": 8.5
},
"M",
{
"x": 1,
"t": "#ffffff\n\n\n\n\n\n\n\n\n#f8d615"
},
">\n.\n\n\n\n\n\n\n\n["
],
[
{
"y": -0.875,
"x": 5.5,
"t": "#ffffff"
},
"B",
{
"x": 6.5
},
"N"
],
[
{
"y": -0.875,
"t": "#ffffff\n\n#f67f00",
"a": 6,
"fa": [
5
],
"w": 1.5
},
"&uArr;\n\n2-tap<br/>locks",
{
"t": "#ffffff",
"a": 4,
"f": 3
},
"Z",
{
"x": 14.5,
"t": "#ffffff\n\n\n\n\n\n\n\n\n#f8d615",
"f": 3
},
"?\n/\n\n\n\n\n\n\n\n]",
{
"t": "#ffffff\n\n#f67f00",
"a": 6,
"f": 3,
"w": 1.5
},
"&uArr;\n\n2-tap<br/>locks"
],
[
{
"y": -0.375,
"x": 3.5,
"t": "#ffffff",
"a": 4
},
"\n<i class='kb kb-Multimedia-Volume-Up-2'></i>",
{
"x": 10.5,
"f": 3
},
"}\n]"
],
[
{
"y": -0.875,
"x": 2.5
},
"\n<i class='kb kb-Multimedia-Volume-Down-1'></i>",
{
"x": 1
},
"\n<i class='kb kb-Multimedia-Mute-1'></i>",
{
"x": 8.5,
"t": "#ffffff\n\n\n\n\n\n\n#60605b",
"f": 3
},
"{\n[\n\n\n\n\n\n&Aring;",
{
"x": 1,
"t": "#ffffff",
"f": 3
},
"+\n="
],
[
{
"y": -0.75,
"x": 0.5,
"f": 3
},
"ctrl",
{
"f": 3
},
"alt",
{
"x": 14.5,
"f": 3
},
"altgr",
{
"f": 3
},
"ctrl"
],
[
{
"r": 30,
"rx": 6.5,
"ry": 4.25,
"y": -1,
"x": 1,
"t": "#ffffff\n\n\n\n\n\n\n\n\n\n#5eb1e7",
"f": 3
},
"esc\n\n\n\n\n\n\n\n\n\n<i class='fa fa-mouse-pointer'></i>M",
{
"t": "#ffffff",
"f": 7
},
"<i class='kb kb-logo-linux-tux'></i>"
],
[
{
"t": "#ffffff\n\n\n\n\n\n\n\n\n\n#5eb1e7",
"f": 3,
"h": 2
},
"space\n\n\n\n\n\n\n\n\n\n<i class='fa fa-mouse-pointer'></i>L",
{
"h": 2
},
"<i class='kb kb-Tab-1'></i>\n\n\n\n\n\n\n\n\n\n<i class='fa fa-mouse-pointer'></i>R",
{
"t": "#5eb1e7"
},
"<i class='fa fa-mouse-pointer'></i>"
],
[
{
"x": 2,
"t": "#ac97d8"
},
"<i class='fa fa-arrows'></i>"
],
[
{
"r": -30,
"rx": 13,
"y": -1,
"x": -3,
"t": "#ffffff"
},
"<i class='kb kb-Hamburger-Menu'></i>",
"esc"
],
[
{
"x": -3
},
"ins",
{
"h": 2
},
"<i class='kb kb-Return-2'></i>",
{
"h": 2
},
"space"
],
[
{
"x": -3
},
"scroll<br/>lock"
]
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

@ -0,0 +1,9 @@
# Having a file like this allows you to override Makefile definitions
# for your own particular keymap
TAP_DANCE_ENABLE=yes
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,36 @@
#ifndef KEYBOARDS_ERGODOX_CONFIG_H_
#define KEYBOARDS_ERGODOX_CONFIG_H_
#define MOUSEKEY_DELAY 100
#define MOUSEKEY_INTERVAL 20
#define MOUSEKEY_MAX_SPEED 3
#define MOUSEKEY_TIME_TO_MAX 10
#define TAPPING_TOGGLE 1
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
#define TAPPING_TERM 300
#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.)
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)) || \
keyboard_report->mods == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) \
)
#ifdef SUBPROJECT_ez
#include "ez/config.h"
#endif
#ifdef SUBPROJECT_infinity
#include "infinity/config.h"
#endif
#endif /* KEYBOARDS_ERGODOX_CONFIG_H_ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

@ -0,0 +1,324 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#include "wait.h"
#define BASE 0 // default layer - helpful for writing in Office-style word processors.
#define SYMB 1 // symbol layer - NumPad, etc. - same as Ergodox EZ default but no EEPROM or Version key
#define RIMW 2 // rimworld layer - made for the game RimWorld, by Tynan Sylvester | feel free to remap for your favorite game!
#define MDIA 3 // media layer - mouse and music - close to Ergodox EZ default media layer
#define CO_PA M(0) // hold copy, tap paste
#define W_CUT LCTL(KC_X) // C-x Cut
#define W_COPY LCTL(KC_C) // C-c Copy
#define W_PASTE LCTL(KC_V) // C-v Paste
#define W_UNDO LCTL(KC_Z) // C-z Undo
#define W_FIND LCTL(KC_F) // C-v Find
#define W_CAD LCTL(LALT(KC_DEL)) // one-tap ctrl-alt-del
//Tap Dance Declarations
enum {
CAKEWARP,
CTRLALTMDIA,
};
void cake_count (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 2) {
layer_on (SYMB); //define double tap here
layer_off (MDIA);
}
else {
layer_off (SYMB); //define single tap or hold here
layer_off (MDIA);
}
if (state->count == 3) {
layer_on (RIMW); //define triple tap here
layer_off (MDIA);
}
else {
layer_off (RIMW); //define single tap or hold here
layer_off (MDIA);
reset_tap_dance (state);
}
}
void dance_cad_mdia_fin (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code (KC_LCTL);
register_code (KC_LALT);
register_code (KC_DEL);
} else {
layer_on (MDIA);
}
}
void dance_cad_mdia_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code (KC_DEL);
unregister_code (KC_LALT);
unregister_code (KC_LCTL);
} else {
;
}
}
//Tap Dance Definitions
qk_tap_dance_action_t tap_dance_actions[] = {
// tap for Layer 0, tap twice to switch to symbol layer, and tap three times to switch to rimworld layer.
[CAKEWARP] = ACTION_TAP_DANCE_FN(cake_count)
// tap for ctrl-alt-del, tap twice for media layer
,[CTRLALTMDIA] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cad_mdia_fin, dance_cad_mdia_reset)
// Other declarations would go here, separated by commas, if you have them
};
//In Layer declaration, add tap dance item in place of a key code
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer - TD(one_tap, two_taps, three_taps...)
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 7 | 8 | 9 | 0 | - | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | F12/L1 | Q | W | E | R | T | {/[ | |TD(L0 | Y | U | I | O | P | \ |
* |--------+------+------+------+------+------| | |L1 L2)|------+------+------+------+------+--------|
* |Caps/Win| A | S | D | F | G |------| |------| H | J | K | L | ; | ' |
* |--------+------+------+------+------+------| }/] | TD(ctrl|------+------+------+------+------+--------|
* |LShift/(|Z/Ctrl| X | C | V | B | | |altdel| N | M | , | . | / |RShift/)|
* `--------+------+------+------+------+-------------' |L3) |------+------+------+------+------+--------'
* | Undo | Cut |CopyPa| Meh | LGui | '------| | Enter| Left | Up | Down | Right |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | Esc | VolUp| | F4 | Mute |
* ,------|------|------| |------+--------+------.
* | | | VolDn| | F5 | | |
* |Backsp|Delete|------| |------| Tab / |Space |
* |ace | | Find | | Alt | CTRL | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
LT(SYMB, KC_F12), KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LBRC,
GUI_T(KC_CAPS), KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSPO, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_RBRC,
W_UNDO, W_CUT, CO_PA, MEH_T(KC_NO), KC_LGUI,
KC_ESC, KC_VOLU,
KC_VOLD,
KC_BSPC, KC_DELETE, W_FIND,
// right hand
KC_7, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL,
TD(CAKEWARP), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
TD(CTRLALTMDIA), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSPC,
KC_ENT, KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT,
KC_F4, KC_MUTE,
KC_F5,
KC_RALT, CTL_T(KC_TAB), KC_SPC
),
/* Keymap 1: Symbol Layer | No EEPROM Or Version keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | xx | | xx | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | |TD(L0 | Up | 7 | 8 | 9 | * | F12 |
* |--------+------+------+------+------+------| | |L1 L2)|------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | - |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_NO,
KC_TRNS,KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
KC_TRNS,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_NO, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_MINS,
KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_NO,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: RimWorld Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | ESC | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 7 | 8 | 9 | 0 | - | = |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | TAB | C | ,< | W | >. | R | | |TD(L0 | U | B | N | J | M | PGUP |
* |--------+------+------+------+------+------| F10 | |L1 L2)|------+------+------+------+------+--------|
* | I | F | A | S | D | 8 |------| |------| X | L | P | Y | H | ENTER |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | K | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | PGDN |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | F | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* |SPACE | C |------| |------| E |SPACE |
* | | | Q | | | | |
* `--------------------' `--------------------'
*/
// RIMWORLD
[RIMW] = KEYMAP(
// left hand
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
KC_TAB, KC_C, KC_COMM, KC_W, KC_DOT, KC_R, KC_F10,
KC_I, KC_F, KC_A, KC_S, KC_D, KC_8,
KC_K, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_C,KC_Q,KC_TRNS,
// right hand
KC_7, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL,
KC_TRNS, KC_U, KC_B, KC_N, KC_J, KC_M, KC_PGUP,
KC_X, KC_L, SFT_T(KC_P), KC_Y, KC_H, KC_ENT,
KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PGDN,
KC_F, KC_LEFT, KC_UP, KC_DOWN,KC_RIGHT,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_E, KC_TRNS
),
/* Keymap 3: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | Lclk | Rclk |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_BTN1, KC_BTN2, KC_TRNS,
// right hand
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_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK
),
};
static uint16_t key_timer;
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0: {
if (record->event.pressed) {
key_timer = timer_read(); // if the key is being pressed, we start the timer.
}
else { // this means the key was just released, so we can figure out how long it was pressed for (tap or "held down").
if (timer_elapsed(key_timer) > 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap.
return MACRO( D(LCTL), T(C), U(LCTL), END );
}
else {
return MACRO( D(LCTL), T(V), U(LCTL), END );
}
}
break;
}
}
return MACRO_NONE;
};
// Anything you want to do once when the keyboard initializes.
// Tests LED function when the keyboard initializes.
void matrix_init_user(void) {
wait_ms(500);
ergodox_board_led_on();
wait_ms(200);
ergodox_right_led_1_on();
wait_ms(200);
ergodox_right_led_2_on();
wait_ms(200);
ergodox_right_led_3_on();
wait_ms(200);
ergodox_board_led_off();
wait_ms(200);
ergodox_right_led_1_off();
wait_ms(200);
ergodox_right_led_2_off();
wait_ms(200);
ergodox_right_led_3_off();
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,113 @@
<!-- -*- mode: markdown; fill-column: 8192 -*- -->
Win10 Writer's Block ErgoDox - v1.0
=======================
This is a QWERTY layout for QMK. It's designed to work well in MS Office-like environments. It's tested on Windows 7 and 10.
Professional writers may find this layout useful -- copywriters, technical writers, novelists, etc.
I use my ErgoDox with this keymap as a daily driver at my office.
A gaming layer is unobtrusively built into this layout. I use that layer to play RimWorld.
Feel free to modify the gaming layer to your personal taste.
## Table of Contents
* [Layouts](#layouts)
- [Base layer](#base-layer)
- [Symbol layer](#symbol-layer)
- [Gaming layer](#rimworld-layer)
- [Media layer](#media-layer)
* [Tools](#tools)
- [Layer notification](#layer-notification)
* [Building](#building)
- [Using on Windows](#using-on-windows)
* [License](#license)
* [Special Thanks](#special-thanks)
# Layouts
* TapDance will teleport you to the layer you want:
* One Tap for the Base layer
* Two Taps for the Symbol layer
* Three Taps for the Rimworld/Gaming layer
* Where the "Meh" key is located on the Ergodox EZ default layout, I've changed it to another tap dance key:
* One Tap for CTRL-ALT-DEL
* Two Taps for the Media/Mouse layer
## Base layer
[![Base layer](images/base-layer.png)](http://www.keyboard-layout-editor.com/#/gists/8fd9bbdd3a23bbb5a8779de3624a3be1)
This is a QWERTY layout with some quirks.
* Enter is located on a key that won't cause as much thumb fatigue.
* Copy and Paste work from the same key. Just hold the key to copy and tap the key to paste!
* Undo, Find and Cut are also one-touch keys.
* F12 is where you would normally find TAB on standard layouts. Quickly save in Word, safely.
* You'll find bracket keys below the "6" key.
* The Meh Key is a single-button CTRL+ALT+SHIFT modifier.
* Space Cadet Shift: Tap L Shift for "(" and R Shift for ")" -- holding either shift works like a normal shift.
* Tap "Z" or Tab to use either normally. Hold them for CTRL.
* Tap Caps Lock to use it normally. Hold it for Win key combinations (Win+D to minimize all programs, etc).
## Symbol layer
[![Symbol layer](images/symbol-layer.png)](http://www.keyboard-layout-editor.com/#/gists/04eb6458b8b17882e472f64d482f12b4)
Your standard Ergodox EZ symbol + numpad layout, minus the Version and EEPROM keys.
* From the base layer, hold the F12 Key to temporarily access this layer (use for quick access to numpad)
* Release F12 to return to the base layer.
## Rimworld layer
[![Rimworld / Gaming Layer](images/rimworld-layer.png)](http://www.keyboard-layout-editor.com/#/gists/d53af8391e6e443ed0a98ccfbdb4eace)
This layer was made to play RimWorld, a Sci-Fi Colony Survival Game by Tynan Sylvester and Ludeon Studios, available on Steam.
* Have fun!
## Media layer
[![Media layer](images/media-layer.png)](http://www.keyboard-layout-editor.com/#/gists/3209d09ed4bd997e4f49f28c6ada2ab3)
This is the standard Ergodox EZ media layout with more options for mouseclick buttons.
* In this layer, your "space" key changes into a back button for your browser.
## LED states
Your LEDs will change to indicate your layer. You'll know you are in the base layer if all LEDs are off.
# Building
To build, you will need the [QMK][qmk] firmware checked out. from there, dive into `keyboards/ergodox/keymaps/win10_writers-block/`
[qmk]: https://github.com/jackhumbert/qmk_firmware
```
$ make keyboard=ergodox keymap=win10_writers-block
```
## Using on Windows
This layout is tested in Windows 7 Pro and Windows 10 Home environments.
# License
GPL 3+
# Special Thanks
* To algernon for his coding help. I'm a novice but I still made this work (and figured out tap dance) with his help.
* To /r/MechanicalKeyboards for being an all-around great community.
* To /u/profet23 for his amazing custom Ergodox boards.

@ -1,5 +1,7 @@
# The Easy Way
If you have an ErgoDox EZ, the absolute easiest way for you to customize your firmware is using the [graphical configurator](http://configure.ergodox-ez.com), which uses QMK under the hood.
If you can find firmware someone else has made that does what you want, that
is the easiest way to customize your ErgoDox. It requires no programming
experience or the setup of a build environment.
@ -63,7 +65,7 @@ files. Check them out with:
# Flashing Firmware
## ErgoDox Ez
## ErgoDox EZ
The Ez uses the [Teensy Loader](https://www.pjrc.com/teensy/loader.html).
@ -153,13 +155,10 @@ If you want to send a plain vanilla key, you can look up its code under `doc/key
There are external tools for customizing the layout, but those do not use
the featurs of this qmk firmware. These sites include:
- [Massdrop configurator](https://keyboard-configurator.massdrop.com/ext/ergodox) for Ez
- The official [ErgoDox EZ configurator](http://configure.ergodox-ez.com)
- [Massdrop configurator](https://keyboard-configurator.massdrop.com/ext/ergodox) for EZ, works but not officially supported
- [Input Club configurator](https://input.club/configurator-ergodox) for Infinity, provides left and right files
You can also find an existing firmware that you like, for example from:
- [Dozens of community-contributed keymaps](http://qmk.fm/keyboards/ergodox/)
This qmk firmware also provides the ability to customize keymaps, but requires
a toolchain to build the firmware. See below for instructions on building
firmware and customizing keymaps.

@ -24,6 +24,5 @@ COMMAND_ENABLE ?= yes # Commands for debug and configuration
CUSTOM_MATRIX ?= yes # Custom matrix file for the ErgoDox EZ
SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= yes # Unicode
ONEHAND_ENABLE ?= yes # Allow swapping hands of keyboard

@ -4,7 +4,7 @@
#include "quantum.h"
#include "led.h"
/* GH60 LEDs
/* GH60 LEDs
* GPIO pads
* 0 F7 WASD LEDs
* 1 F6 ESC LED
@ -35,40 +35,41 @@ inline void gh60_wasd_leds_off(void) { DDRF &= ~(1<<7); PORTF &= ~(1<<7); }
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D }, \
{ KC_##K40, KC_##K41, KC_##K42, KC_NO, KC_NO, KC_##K45, KC_NO, KC_NO, KC_NO, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D } \
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
{ K40, K41, K42, KC_NO, KC_NO, K45, KC_NO, KC_NO, KC_NO, K49, K4A, K4B, K4C, K4D } \
}
/* ANSI valiant. No extra keys for ISO */
/* ANSI variant. No extra keys for ISO */
#define KEYMAP_ANSI( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, \
K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, \
K40, K41, K42, K45, K4A, K4B, K4C, K4D \
) KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO, K2D, \
K30, NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, NO, K3D, \
K40, K41, K42, K45, NO, K4A, K4B, K4C, K4D \
)
) { \
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D }, \
{ K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, KC_NO, K3D }, \
{ K40, K41, K42, KC_NO, KC_NO, K45, KC_NO, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D } \
}
/* HHKB Variant */
#define KEYMAP_HHKB( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K49,\
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, \
K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, K3C, \
K40, K41, K42, K45, K4A, K4B, K4C, K4D \
) KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, NO, K2D, \
K30, NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D \
)
) { \
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D }, \
{ K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
{ K40, K41, K42, KC_NO, KC_NO, K45, KC_NO, KC_NO, KC_NO, K49, K4A, K4B, K4C, K4D } \
}
#endif
#endif

@ -0,0 +1,112 @@
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device.
# Please customize your programmer settings(PROGRAM_CMD)
#
# make teensy = Download the hex file to the device, using teensy_loader_cli.
# (must have teensy_loader_cli installed).
#
# make dfu = Download the hex file to the device, using dfu-programmer (must
# have dfu-programmer installed).
#
# make flip = Download the hex file to the device, using Atmel FLIP (must
# have Atmel FLIP installed).
#
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
# (must have dfu-programmer installed).
#
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
# (must have Atmel FLIP installed).
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
# CONSOLE_ENABLE ?= yes # Console for debug(+400)
# COMMAND_ENABLE ?= yes # Commands for debug and configuration
KEYBOARD_LOCK_ENABLE ?= yes # Allow locking of keyboard via magic key
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
# BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
# MIDI_ENABLE ?= YES # MIDI controls
# UNICODE_ENABLE ?= YES # Unicode
# BLUETOOTH_ENABLE ?= yes # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= yes # Enable RGB Underglow
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,187 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER geekhack
#define PRODUCT GH60
#define DESCRIPTION t.m.k. keyboard firmware for GH60
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 14
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }
#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
#define BACKLIGHT_LEVELS 3
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
/*
* RGB Underglow
* These settings are for the F4 by default:
*
*
* #define ws2812_PORTREG PORTF
* #define ws2812_DDRREG DDRF
* #define ws2812_pin PF4
* #define RGBLED_NUM 14 // Number of LEDs
* #define RGBLIGHT_HUE_STEP 10
* #define RGBLIGHT_SAT_STEP 17
* #define RGBLIGHT_VAL_STEP 17
*
* The firmware supports 5 different light effects, and the color (hue, saturation, brightness) can be customized in most effects.
* To control the underglow, you need to modify your keymap file to assign those functions to some keys/key combinations.
* For details, please check this keymap. keyboard/planck/keymaps/yang/keymap.c
*/
/* Deprecated code below
#define ws2812_PORTREG PORTF
#define ws2812_DDRREG DDRF
#define ws2812_pin PF4
*/
#define RGB_DI_PIN F4
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 11 // Number of LEDs
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
#endif

@ -0,0 +1,198 @@
#include "gh60.h"
#include "action_layer.h"
#include "rgblight.h"
#define _DEFAULT 0
#define _FN 1
#define _WASD 2
#define _SFX 3
//bool esc_led_on;
enum planck_keycodes {
DEFAULT = SAFE_RANGE
};
// Fillers to make layering more clear
#define ______ KC_TRNS
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty gui/alt/space/alt/gui
* ,-----------------------------------------------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | \ | ` |
* |-----------------------------------------------------------------------------------------+
* | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | Bksp |
* |-----------------------------------------------------------------------------------------+
* | Ctrl | A | S | D | F | G | H | J | K | L | ; | ' | Enter |
* |-----------------------------------------------------------------------------------------+
* | Shift | Z | X | C | V | B | N | M | , | . | / | RShift | FN |
* |-----------------------------------------------------------------------------------------+
* |LGUI | LAlt | Space | RAlt |RGUI |
* `-----------------------------------------------------------------'
*/
[_DEFAULT] = KEYMAP_HHKB( /* Basic QWERTY */
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN), \
______, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, ______, ______ \
),
/* FN Layer
* ,-----------------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | Ins | Del |
* |-----------------------------------------------------------------------------------------+
* | CAPS | | | | | | | | Psc | Slck| Paus| Up | | |
* |-----------------------------------------------------------------------------------------+
* | | Vol-| Vol+| Mute| | | * | / | Home| PgUp| Left|Right| |
* |-----------------------------------------------------------------------------------------+
* | | Prev| Play| Next| | | + | - | End |PgDn| Down| | |
* |-----------------------------------------------------------------------------------------+
* | | | | Stop | |
* `-----------------------------------------------------------------'
*/
[_FN] = KEYMAP_HHKB( /* Layer 1 */
TG(_SFX),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_INS, KC_DEL, \
KC_CAPS, ______, ______, ______, ______, ______, ______, ______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, ______, ______, \
______, KC_VOLD, KC_VOLU, KC_MUTE, ______, ______, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT,______, \
______, KC_MPRV, KC_MPLY, KC_MNXT, ______, ______, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, ______, ______, \
______, ______, ______, TG(_WASD), KC_MSTP, ______, ______, ______ \
),
/* WASD Layer
* ,-----------------------------------------------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | Up | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | Left| Down|Right| | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | | | |
* `-----------------------------------------------------------------'
*/
[_WASD] = KEYMAP_HHKB( /* Layer 2 */
______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, ______, KC_UP, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, KC_LEFT, KC_DOWN,KC_RGHT,______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,______, \
______, ______, ______, ______, ______, ______, ______, ______ \
),
/* SFX Layer
* ,-----------------------------------------------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | BL- | BL+ | BL | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | RGBT| RGBM| | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | Hue+| Hue-| Sat+| Sat-| Val+| Val-| | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | | | |
* `-----------------------------------------------------------------'
*/
[_SFX] = KEYMAP_HHKB(
______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, F(0), F(1), ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, F(2), F(3), F(4), F(5), F(6), F(7), ______, ______, ______, ______, ______, ______, \
______, ______, ______, ______, ______, ______, ______, ______ \
)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
return MACRO_NONE;
};
enum function_id {
RGBLED_TOGGLE,
RGBLED_STEP_MODE,
RGBLED_INCREASE_HUE,
RGBLED_DECREASE_HUE,
RGBLED_INCREASE_SAT,
RGBLED_DECREASE_SAT,
RGBLED_INCREASE_VAL,
RGBLED_DECREASE_VAL
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(RGBLED_TOGGLE),
[1] = ACTION_FUNCTION(RGBLED_STEP_MODE),
[2] = ACTION_FUNCTION(RGBLED_INCREASE_HUE),
[3] = ACTION_FUNCTION(RGBLED_DECREASE_HUE),
[4] = ACTION_FUNCTION(RGBLED_INCREASE_SAT),
[5] = ACTION_FUNCTION(RGBLED_DECREASE_SAT),
[6] = ACTION_FUNCTION(RGBLED_INCREASE_VAL),
[7] = ACTION_FUNCTION(RGBLED_DECREASE_VAL)
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch (id) {
case RGBLED_TOGGLE:
if (record->event.pressed) {
rgblight_toggle();
}
break;
case RGBLED_INCREASE_HUE:
if (record->event.pressed) {
rgblight_increase_hue();
}
break;
case RGBLED_DECREASE_HUE:
if (record->event.pressed) {
rgblight_decrease_hue();
}
break;
case RGBLED_INCREASE_SAT:
if (record->event.pressed) {
rgblight_increase_sat();
}
break;
case RGBLED_DECREASE_SAT:
if (record->event.pressed) {
rgblight_decrease_sat();
}
break;
case RGBLED_INCREASE_VAL:
if (record->event.pressed) {
rgblight_increase_val();
}
break;
case RGBLED_DECREASE_VAL:
if (record->event.pressed) {
rgblight_decrease_val();
}
break;
case RGBLED_STEP_MODE:
if (record->event.pressed) {
rgblight_step();
}
break;
}
}
void matrix_scan_user(void) {
uint32_t layer = layer_state;
if (layer & (1<<1)) {
gh60_fn_led_on();
} else {
gh60_fn_led_off();
}
if (layer & (1<<2)) {
gh60_wasd_leds_on();
} else {
gh60_wasd_leds_off();
}
if (layer & (1<<3)) {
gh60_esc_led_on();
} else {
gh60_esc_led_off();
}
};

@ -4,25 +4,25 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: qwerty */
KEYMAP(
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, \
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT,NO, ENT, \
LSFT,FN1, Z, X, C, V, B, N, M, COMM,DOT, SLSH,FN0, RSFT, \
LCTL,LGUI,LALT, SPC, BSLS,RALT,RGUI,APP, RCTL),
KC_ESC,KC_1,KC_2,KC_3,KC_4,KC_5,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINS,KC_EQL,KC_GRV,\
KC_TAB,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_LBRC,KC_RBRC,KC_BSPC,\
KC_CAPS,KC_A,KC_S,KC_D,KC_F,KC_G,KC_H,KC_J,KC_K,KC_L,KC_SCLN,KC_QUOT,KC_NO,KC_ENT,\
KC_LSFT,F(1),KC_Z,KC_X,KC_C,KC_V,KC_B,KC_N,KC_M,KC_COMM,KC_DOT,KC_SLSH,F(0),KC_RSFT,\
KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_BSLS,KC_RALT,KC_RGUI,KC_APP,KC_RCTL),
/* 1: fn */
KEYMAP(
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS, \
TRNS,TRNS,UP, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,LEFT,DOWN,RGHT,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS),
KC_ESC,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_TRNS,\
KC_TRNS,KC_TRNS,KC_UP,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_LEFT,KC_DOWN,KC_RGHT,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),
/* 2: arrows */
KEYMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,UP, \
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,LEFT,DOWN,RGHT),
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,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_UP,\
KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_LEFT,KC_DOWN,KC_RGHT),
};
const uint16_t PROGMEM fn_actions[] = {
@ -49,7 +49,7 @@ void matrix_scan_user(void) {
//Layer LED indicators
uint32_t layer = layer_state;
if (layer & (1<<1)) {
gh60_wasd_leds_on();
gh60_fn_led_on();
@ -57,7 +57,7 @@ void matrix_scan_user(void) {
gh60_wasd_leds_off();
gh60_fn_led_off();
}
if (layer & (1<<2)) {
gh60_poker_leds_on();
gh60_esc_led_on();
@ -65,5 +65,5 @@ void matrix_scan_user(void) {
gh60_poker_leds_off();
gh60_esc_led_off();
}
};

@ -182,7 +182,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ws2812_pin PF4
*/
#define RGB_DI_PIN F4
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8

@ -8,9 +8,9 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* Base layer, pretty standard ANSI layout.
* Base layer, pretty standard ANSI layout.
* ,-----------------------------------------------------------.
* |FN12| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |F(12)| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
* |-----------------------------------------------------------|
@ -22,13 +22,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------'
*/
[_BL] = KEYMAP(
FN12,1,2,3,4,5,6,7,8,9,0,MINS,EQL,BSPC, \
TAB,Q,W,E,R,T,Y,U,I,O,P,LBRC,RBRC,BSLS, \
FN2,A,S,D,F,G,H,J,K,L,SCLN,QUOT,NO,ENT, \
LSFT,NO,Z,X,C,V,B,N,M,COMM,DOT,SLSH,NO,RSFT, \
LCTL,LGUI,LALT, SPC, NO,RALT,FN0,APP, RCTL),
/*
F(12),KC_1,KC_2,KC_3,KC_4,KC_5,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINS,KC_EQL,KC_BSPC, \
KC_TAB,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_LBRC,KC_RBRC,KC_BSLS, \
F(2),KC_A,KC_S,KC_D,KC_F,KC_G,KC_H,KC_J,KC_K,KC_L,KC_SCLN,KC_QUOT,KC_NO,KC_ENT, \
KC_LSFT,KC_NO,KC_Z,KC_X,KC_C,KC_V,KC_B,KC_N,KC_M,KC_COMM,KC_DOT,KC_SLSH,KC_NO,KC_RSFT, \
KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_NO,KC_RALT,F(0),KC_APP,KC_RCTL),
/*
* Locking arrow keys to WASD for when you need dedicated arrow keys
* ,-----------------------------------------------------------.
* | | | | | | | | | | | | | | |
@ -43,14 +43,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------'
*/
[_AL] = KEYMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,UP,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,LEFT,DOWN,RGHT,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,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_UP,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_LEFT,KC_DOWN,KC_RGHT,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),
/*
/*
* Primary function layer, mostly the same as the traditional Pok3r layout.
* ,-------------------------------------------------------------.
* |`~ | F1| F2| F3| F4| F5| F6| F7| F8| F9| F10| F11| F12|DEL |
@ -65,15 +65,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-------------------------------------------------------------'
*/
[_FL] = KEYMAP(
GRAVE,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12, DELETE, \
TRNS,FN1,TRNS,TRNS,TRNS,TRNS,CALC,PGUP,UP,PGDN,PSCR,SLCK,PAUS,TRNS, \
TRNS,MUTE,_VOLDOWN,_VOLUP,TRNS,TRNS,HOME,LEFT,DOWN,RGHT,INS,TRNS,TRNS,TRNS, \
TRNS,TRNS,FN3,TRNS,TRNS,TRNS,TRNS,END,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS),
/*
KC_GRAVE,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_DELETE, \
KC_TRNS,F(1),KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_CALC,KC_PGUP,KC_UP,KC_PGDN,KC_PSCR,KC_SLCK,KC_PAUS,KC_TRNS, \
KC_TRNS,KC_MUTE,KC__VOLDOWN,KC__VOLUP,KC_TRNS,KC_TRNS,KC_HOME,KC_LEFT,KC_DOWN,KC_RGHT,KC_INS,KC_TRNS,KC_TRNS,KC_TRNS, \
KC_TRNS,KC_TRNS,F(3),KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_END,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),
/*
* Locking layer for controlling the underglow.
*
*
* ,-----------------------------------------------------------.
* | | | | | | | | | | | | | | |
* |-----------------------------------------------------------|
@ -87,11 +87,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------'
*/
[_UL] = KEYMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,FN4,FN5,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS,FN6,FN7,FN8,FN9,FN10,FN11,TRNS,TRNS,TRNS,TRNS,TRNS, \
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,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,F(4),F(5),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,F(6),F(7),F(8),F(9),F(10),F(11),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),
};
enum function_id {
@ -124,7 +124,7 @@ const uint16_t PROGMEM fn_actions[] = {
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {

@ -0,0 +1,3 @@
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,76 @@
#include "gh60.h"
#include "action_layer.h"
#define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: qwerty */
KEYMAP_HHKB(
F(0),KC_1,KC_2,KC_3,KC_4,KC_5,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINS,KC_EQL,KC_BSLS,KC_GRV,\
KC_TAB,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_LBRC,KC_RBRC,KC_BSPC,\
KC_LCTL,KC_A,KC_S,KC_D,KC_F,KC_G,KC_H,KC_J,KC_K,KC_L,KC_SCLN,KC_QUOT,KC_ENT,\
KC_LSFT,KC_Z,KC_X,KC_C,KC_V,KC_B,KC_N,KC_M,KC_COMM,KC_DOT,KC_SLSH,KC_RSFT,F(1),\
KC_LCTL,KC_LALT,KC_LGUI, KC_SPC, KC_RGUI,KC_RALT,KC_APP,KC_RCTL),
/* 1: fn */
KEYMAP_HHKB(
KC_GRV,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_TRNS,KC_TRNS,\
KC_CAPS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_UP,KC_TRNS,KC_TRNS,\
KC_TRNS,KC_VOLD,KC_VOLU,KC_MUTE,KC_TRNS,KC_TRNS,KC_PAST,KC_PSLS,KC_HOME,KC_PGUP,KC_LEFT,KC_RIGHT,KC_PENT,\
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_PPLS,KC_PMNS,KC_END,KC_PGDN,KC_DOWN,KC_TRNS,KC_TRNS,\
KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS),
};
enum function_id {
SHIFT_ESC,
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(SHIFT_ESC),
[1] = ACTION_LAYER_MOMENTARY(1), // to Fn overlay
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
void matrix_scan_user(void) {
}
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t shift_esc_shift_mask;
switch (id) {
case SHIFT_ESC:
shift_esc_shift_mask = get_mods()&MODS_CTRL_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_GRV);
send_keyboard_report();
} else {
add_key(KC_ESC);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_GRV);
send_keyboard_report();
} else {
del_key(KC_ESC);
send_keyboard_report();
}
}
break;
}
}

@ -11,7 +11,7 @@
/* ws2812 RGB LED */
#define RGB_DI_PIN D5
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 13 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,162 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER You
#define PRODUCT pilcrow
#define DESCRIPTION A custom keyboard
/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 10
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { B4, F7, B1, B3 }
#define MATRIX_COL_PINS { D4, C6, D7, E6, F5, F6, B6, B2, F4, B5}
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,8 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here
#endif

@ -0,0 +1,88 @@
#include "pilcrow.h"
#define _______ KC_TRNS
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( \
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_LCTL, KC_LALT, KC_LGUI, MO(1), KC_SPC, MT(MOD_LSFT, KC_SPC), MO(2), MO(3), KC_DEL, KC_ESC \
),
/* 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 |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[1] = KEYMAP( \
KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, \
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, \
KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_PIPE, S(KC_QUOT), \
_______, _______, _______, _______, KC_BSPC, KC_BSPC, _______, KC_MNXT, KC_VOLD, KC_GRV \
),
[2] = KEYMAP( \
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, \
KC_TAB, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT,KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, \
OSM(MOD_LSFT), KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_BSLS, KC_QUOT, \
_______, _______, _______, _______, KC_ENT, KC_ENT, _______, KC_MNXT, KC_VOLD, KC_VOLU \
),
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[3] = KEYMAP( \
RESET, KC_UP, _______, _______, _______, _______, _______, KC_MS_WH_DOWN, KC_MS_U, KC_MS_WH_UP, \
KC_LEFT, KC_DOWN, KC_RIGHT, AU_ON, AU_OFF, AG_NORM, AG_SWAP, KC_MS_L,KC_MS_D, KC_MS_R, \
RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, \
_______, _______, _______, _______, KC_MS_BTN1, KC_MS_BTN2, _______, _______, _______, _______ \
)
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
void matrix_init_user(void) {
}
void matrix_scan_user(void) {
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
void led_set_user(uint8_t usb_led) {
}

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

@ -0,0 +1,28 @@
#include "pilcrow.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
}
void matrix_scan_kb(void) {
// put your looping keyboard code here
// runs every cycle (a lot)
matrix_scan_user();
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
// put your per-action keyboard code here
// runs for every action, just before processing by the firmware
return process_record_user(keycode, record);
}
void led_set_kb(uint8_t usb_led) {
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
led_set_user(usb_led);
}

@ -0,0 +1,23 @@
#ifndef PILCROW_H
#define PILCROW_H
#include "quantum.h"
// This a shortcut to help you visually see your layout.
// The following is an example using the Planck MIT layout
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39 \
) \
{ \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09 }, \
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19 }, \
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29 }, \
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39 } \
}
#endif

@ -0,0 +1,28 @@
pilcrow keyboard firmware
======================
## Quantum MK Firmware
For the full Quantum feature list, see [the parent readme](/).
## Building
Download or clone the whole firmware and navigate to the keyboards/pilcrow folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file.
Depending on which keymap you would like to use, you will have to compile slightly differently.
### Default
To build with the default keymap, simply run `make default`.
### Other Keymaps
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
```
$ make [default|jack|<name>]
```
Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.

@ -0,0 +1,67 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,168 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
#define USB_VENDOR_ID_LENOVO 0x17ef
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
/* USB Device descriptor parameter */
#define VENDOR_ID USB_VENDOR_ID_LENOVO
#define PRODUCT_ID USB_DEVICE_ID_LENOVO_CBTKBD
#define DEVICE_VER 0x0001
#define MANUFACTURER Priyadi
#define PRODUCT Promethium Keyboard
#define DESCRIPTION
/* key matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 6
/* default pin-out */
#define MATRIX_COL_PINS { B6, B7, D6, C7, F6, F7 }
#define MATRIX_ROW_PINS { D7, C6, D0, D1, F5, F4, F1, F0 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
#define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
/* PS/2 mouse */
#ifdef PS2_USE_BUSYWAIT
# define PS2_CLOCK_PORT PORTD
# define PS2_CLOCK_PIN PIND
# define PS2_CLOCK_DDR DDRD
# define PS2_CLOCK_BIT 1
# define PS2_DATA_PORT PORTD
# define PS2_DATA_PIN PIND
# define PS2_DATA_DDR DDRD
# define PS2_DATA_BIT 2
#endif
/* PS/2 mouse interrupt version */
#ifdef PS2_USE_INT
/* uses INT1 for clock line(ATMega32U4) */
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 3
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 2
#define PS2_INT_INIT() do { \
EICRA |= ((1<<ISC31) | \
(0<<ISC30)); \
} while (0)
#define PS2_INT_ON() do { \
EIMSK |= (1<<INT3); \
} while (0)
#define PS2_INT_OFF() do { \
EIMSK &= ~(1<<INT3); \
} while (0)
#define PS2_INT_VECT INT3_vect
#endif
/* PS/2 mouse USART version */
#ifdef PS2_USE_USART
/* XCK for clock line and RXD for data line */
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 5
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 2
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
/* set DDR of CLOCK as input to be slave */
#define PS2_USART_INIT() do { \
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
UCSR1C = ((1 << UMSEL10) | \
(3 << UPM10) | \
(0 << USBS1) | \
(3 << UCSZ10) | \
(0 << UCPOL1)); \
UCSR1A = 0; \
UBRR1H = 0; \
UBRR1L = 0; \
} while (0)
#define PS2_USART_RX_INT_ON() do { \
UCSR1B = ((1 << RXCIE1) | \
(1 << RXEN1)); \
} while (0)
#define PS2_USART_RX_POLL_ON() do { \
UCSR1B = (1 << RXEN1); \
} while (0)
#define PS2_USART_OFF() do { \
UCSR1C = 0; \
UCSR1B &= ~((1 << RXEN1) | \
(1 << TXEN1)); \
} while (0)
#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
#define PS2_USART_RX_DATA UDR1
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
#define PS2_USART_RX_VECT USART1_RX_vect
#endif
#endif

@ -0,0 +1,29 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
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 = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
UNICODEMAP_ENABLE = yes
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PS2_MOUSE_ENABLE = yes
PS2_USE_INT = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../../Makefile
endif

@ -0,0 +1,17 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/* bootmagic salt key */
#define BOOTMAGIC_KEY_SALT KC_ESC
/* skip bootmagic and eeconfig */
#define BOOTMAGIC_KEY_SKIP KC_SPACE
#define PREVENT_STUCK_MODIFIERS
#define RGB_DI_PIN B5
#define RGBSPS_NUM 57
#endif

@ -0,0 +1,4 @@
#!/bin/sh
sleep 10
avrdude -p m32u4 -P /dev/ttyACM0 -c avr109 -U flash:w:../../../../../.build/handwired_promethium_priyadi.hex

@ -0,0 +1,803 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "promethium.h"
#include "action_layer.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#include "musical_notes.h"
#endif
#include "eeconfig.h"
#include "process_unicode.h"
#include "quantum.h"
#include "rgbsps.h"
#include "ps2_mouse.h"
#include "ps2.h"
#define COUNT(x) (sizeof (x) / sizeof (*(x)))
// #define RGBLED_NUM 5
// struct cRGB led[RGBLED_NUM];
extern keymap_config_t keymap_config;
enum layers {
_QWERTY,
_COLEMAK,
_WORKMAN,
_PUNC,
_NUM,
_FUNC,
_EMOJI,
_GUI,
};
enum planck_keycodes {
// layouts
QWERTY = SAFE_RANGE,
COLEMAK,
WORKMAN,
// layer switchers
PUNC,
NUM,
FUNC,
EMOJI,
GUI,
// os switchers
LINUX,
WIN,
OSX,
};
// Fillers to make layering clearer
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// unicode map
enum unicode_name {
GRIN, // grinning face 😊
TJOY, // tears of joy 😂
SMILE, // grining face with smiling eyes 😁
HEART, // heart ❤
EYERT, // smiling face with heart shaped eyes 😍
CRY, // crying face 😭
SMEYE, // smiling face with smiling eyes 😊
UNAMU, // unamused 😒
KISS, // kiss 😘
HART2, // two hearts 💕
WEARY, // weary 😩
OKHND, // ok hand sign 👌
PENSV, // pensive 😔
SMIRK, // smirk 😏
RECYC, // recycle ♻
WINK, // wink 😉
THMUP, // thumb up 👍
THMDN, // thumb down 👎
PRAY, // pray 🙏
PHEW, // relieved 😌
MUSIC, // musical notes
FLUSH, // flushed 😳
CELEB, // celebration 🙌
CRY2, // crying face 😢
COOL, // smile with sunglasses 😎
NOEVS, // see no evil
NOEVH, // hear no evil
NOEVK, // speak no evil
POO, // pile of poo
EYES, // eyes
VIC, // victory hand
BHART, // broken heart
SLEEP, // sleeping face
SMIL2, // smiling face with open mouth & sweat
HUNRD, // 100
CONFU, // confused
TONGU, // face with tongue & winking eye
DISAP, // disappointed
YUMMY, // face savoring delicious food
CLAP, // hand clapping
FEAR, // face screaming in fear
HORNS, // smiling face with horns
HALO, // smiling face with halo
BYE, // waving hand
SUN, // sun
MOON, // moon
SKULL, // skull
};
const uint32_t PROGMEM unicode_map[] = {
[GRIN] = 0x1F600,
[TJOY] = 0x1F602,
[SMILE] = 0x1F601,
[HEART] = 0x2764,
[EYERT] = 0x1f60d,
[CRY] = 0x1f62d,
[SMEYE] = 0x1F60A,
[UNAMU] = 0x1F612,
[KISS] = 0x1F618,
[HART2] = 0x1F495,
[WEARY] = 0x1F629,
[OKHND] = 0x1F44C,
[PENSV] = 0x1F614,
[SMIRK] = 0x1F60F,
[RECYC] = 0x267B,
[WINK] = 0x1F609,
[THMUP] = 0x1F44D,
[THMDN] = 0x1F44E,
[PRAY] = 0x1F64F,
[PHEW] = 0x1F60C,
[MUSIC] = 0x1F3B6,
[FLUSH] = 0x1F633,
[CELEB] = 0x1F64C,
[CRY2] = 0x1F622,
[COOL] = 0x1F60E,
[NOEVS] = 0x1F648,
[NOEVH] = 0x1F649,
[NOEVK] = 0x1F64A,
[POO] = 0x1F4A9,
[EYES] = 0x1F440,
[VIC] = 0x270C,
[BHART] = 0x1F494,
[SLEEP] = 0x1F634,
[SMIL2] = 0x1F605,
[HUNRD] = 0x1F4AF,
[CONFU] = 0x1F615,
[TONGU] = 0x1F61C,
[DISAP] = 0x1F61E,
[YUMMY] = 0x1F60B,
[CLAP] = 0x1F44F,
[FEAR] = 0x1F631,
[HORNS] = 0x1F608,
[HALO] = 0x1F607,
[BYE] = 0x1F44B,
[SUN] = 0x2600,
[MOON] = 0x1F314,
[SKULL] = 0x1F480,
};
// hybrid shift - =
// #undef KC_LSFT
// #define KC_LSFT MT(MOD_LSFT, KC_MINS)
// #undef KC_RSFT
// #define KC_RSFT MT(MOD_LSFT, KC_EQL)
// hybrid right-gui & scroll lock (mapped to Compose in OS)
#undef KC_RCTL
#define KC_RCTL MT(MOD_LCTL, KC_SLCK)
// RGBSPS
const uint8_t PROGMEM LED_ALNUM[] = {
LED_Z,
LED_A,
LED_Q,
LED_W,
LED_S,
LED_X,
LED_C,
LED_D,
LED_E,
LED_R,
LED_F,
LED_V,
LED_B,
LED_G,
LED_T,
LED_N,
LED_HH,
LED_Y,
LED_U,
LED_J,
LED_M,
LED_COMM,
LED_K,
LED_I,
LED_O,
LED_L,
LED_DOT,
LED_SLSH,
LED_SCLN,
LED_P,
LED_LSPC,
LED_RSPC
};
const uint8_t PROGMEM LED_MODS[] = {
LED_TAB,
LED_ESC,
LED_LSFT,
LED_LCTL,
LED_LGUI,
LED_LALT,
LED_RALT,
LED_RGUI,
LED_BKSP,
LED_ENT,
LED_RSFT,
LED_RCTL
};
const uint8_t PROGMEM LED_FN[] = {
LED_PUNC,
LED_NUM,
LED_FUNC,
LED_EMOJI
};
const uint8_t PROGMEM LED_INDICATORS[] = {
LED_IND_EMOJI,
LED_IND_NUM,
LED_IND_FUNC,
LED_IND_BATTERY,
LED_IND_USB,
LED_IND_BLUETOOTH,
};
const uint8_t PROGMEM LED_TRACKPOINT[] = {
LED_TRACKPOINT1,
LED_TRACKPOINT2,
LED_TRACKPOINT3,
};
void led_reset(void) {
for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), 15, 6, 0);
}
for(uint8_t i = 0; i < COUNT(LED_MODS); i++) {
rgbsps_set(pgm_read_byte(&LED_MODS[i]), 15, 0, 0);
}
for(uint8_t i = 0; i < COUNT(LED_FN); i++) {
rgbsps_set(pgm_read_byte(&LED_FN[i]), 15, 15, 15);
}
}
void led_layer_normal(void) {
rgbsps_set(LED_IND_FUNC, 0, 0, 0);
rgbsps_set(LED_IND_NUM, 0, 0, 0);
rgbsps_set(LED_IND_EMOJI, 0, 0, 0);
led_reset();
rgbsps_send();
}
void led_layer_func(void) {
rgbsps_set(LED_IND_FUNC, 0, 15, 0);
rgbsps_set(LED_IND_NUM, 0, 0, 0);
rgbsps_set(LED_IND_EMOJI, 0, 0, 0);
led_reset();
for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), 0, 0, 0);
}
rgbsps_set(LED_I, 15, 0, 15);
rgbsps_set(LED_J, 15, 0, 15);
rgbsps_set(LED_K, 15, 0, 15);
rgbsps_set(LED_L, 15, 0, 15);
rgbsps_set(LED_U, 15, 0, 0);
rgbsps_set(LED_O, 15, 0, 0);
rgbsps_set(LED_COMM, 15, 0, 0);
rgbsps_set(LED_DOT, 15, 0, 0);
rgbsps_set(LED_SCLN, 15, 0, 0);
rgbsps_set(LED_P, 15, 0, 0);
rgbsps_set(LED_Q, 0, 15, 0);
rgbsps_set(LED_W, 0, 15, 0);
rgbsps_set(LED_E, 0, 15, 0);
rgbsps_set(LED_R, 0, 15, 0);
rgbsps_set(LED_A, 0, 15, 0);
rgbsps_set(LED_S, 0, 15, 0);
rgbsps_set(LED_D, 0, 15, 0);
rgbsps_set(LED_F, 0, 15, 0);
rgbsps_set(LED_Z, 0, 15, 0);
rgbsps_set(LED_X, 0, 15, 0);
rgbsps_set(LED_C, 0, 15, 0);
rgbsps_set(LED_V, 0, 15, 0);
rgbsps_send();
}
void led_layer_punc(void) {
rgbsps_set(LED_IND_FUNC, 0, 15, 0);
rgbsps_set(LED_IND_NUM, 0, 0, 15);
rgbsps_set(LED_IND_EMOJI, 0, 0, 0);
led_reset();
rgbsps_send();
}
void led_layer_num(void) {
rgbsps_set(LED_IND_FUNC, 0, 0, 0);
rgbsps_set(LED_IND_NUM, 0, 0, 15);
rgbsps_set(LED_IND_EMOJI, 0, 0, 0);
led_reset();
for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), 0, 0, 0);
}
rgbsps_set(LED_U, 0, 5, 15);
rgbsps_set(LED_I, 0, 5, 15);
rgbsps_set(LED_O, 0, 5, 15);
rgbsps_set(LED_J, 0, 5, 15);
rgbsps_set(LED_K, 0, 5, 15);
rgbsps_set(LED_L, 0, 5, 15);
rgbsps_set(LED_M, 0, 5, 15);
rgbsps_set(LED_COMM, 0, 5, 15);
rgbsps_set(LED_DOT, 0, 5, 15);
rgbsps_set(LED_FUNC, 0, 5, 15);
rgbsps_set(LED_EMOJI, 0, 10, 15);
rgbsps_set(LED_RALT, 0, 10, 15);
rgbsps_set(LED_Q, 0, 10, 15);
rgbsps_set(LED_W, 0, 10, 15);
rgbsps_set(LED_E, 0, 10, 15);
rgbsps_set(LED_R, 0, 10, 15);
rgbsps_set(LED_T, 0, 10, 15);
rgbsps_set(LED_Y, 0, 10, 15);
rgbsps_set(LED_P, 0, 10, 15);
rgbsps_set(LED_A, 0, 15, 15);
rgbsps_set(LED_S, 0, 15, 15);
rgbsps_set(LED_D, 0, 15, 15);
rgbsps_set(LED_F, 0, 15, 15);
rgbsps_set(LED_Z, 0, 15, 15);
rgbsps_set(LED_X, 0, 15, 15);
rgbsps_set(LED_C, 0, 15, 15);
rgbsps_set(LED_V, 0, 15, 15);
rgbsps_send();
}
void led_layer_emoji(void) {
for(uint8_t i = 0; i < COUNT(LED_ALNUM); i++) {
rgbsps_set(pgm_read_byte(&LED_ALNUM[i]), 15, 15, 0);
}
for(uint8_t i = 0; i < COUNT(LED_MODS); i++) {
rgbsps_set(pgm_read_byte(&LED_MODS[i]), 15, 15, 0);
}
for(uint8_t i = 0; i < COUNT(LED_FN); i++) {
rgbsps_set(pgm_read_byte(&LED_FN[i]), 15, 15, 0);
}
rgbsps_set(LED_IND_FUNC, 0, 0, 0);
rgbsps_set(LED_IND_NUM, 0, 0, 0);
rgbsps_set(LED_IND_EMOJI, 15, 15, 0);
rgbsps_set(LED_PUNC, 15, 15, 15);
rgbsps_set(LED_EMOJI, 15, 15, 15);
rgbsps_send();
}
void led_layer_gui(void) {
rgbsps_set(LED_IND_FUNC, 15, 10, 15);
rgbsps_set(LED_IND_NUM, 15, 10, 15);
rgbsps_set(LED_IND_EMOJI, 15, 10, 15);
rgbsps_send();
}
void led_init(void) {
// turn off all
rgbsps_turnoff();
// set trackpoint color
rgbsps_set(LED_TRACKPOINT1, 15, 0, 0);
rgbsps_set(LED_TRACKPOINT2, 0, 0, 15);
rgbsps_set(LED_TRACKPOINT3, 15, 0, 0);
// // hardcode indicator for now
rgbsps_set(LED_IND_BLUETOOTH, 0, 0, 15);
rgbsps_set(LED_IND_USB, 15, 15, 15);
rgbsps_set(LED_IND_BATTERY, 0, 15, 0);
led_layer_normal();
}
// keymaps
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 | ; |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = KEYMAP(
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOT, KC_ENT ,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
KC_LCTL, KC_LGUI, KC_LALT, PUNC, NUM, KC_SPC, KC_SPC, FUNC, EMOJI, KC_RALT, KC_RGUI, KC_RCTL
),
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = KEYMAP(
_______, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, _______,
_______, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, _______,
_______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* Workman
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | D | R | W | B | J | F | U | P | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | H | T | G | Y | N | E | O | I |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | M | C | V | K | K | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_WORKMAN] = KEYMAP(
_______, KC_Q, KC_D, KC_R, KC_W, KC_B, KC_J, KC_F, KC_U, KC_P, KC_QUOT, _______,
_______, KC_A, KC_S, KC_H, KC_T, KC_G, KC_Y, KC_N, KC_E, KC_O, KC_I, _______,
_______, KC_Z, KC_X, KC_M, KC_C, KC_V, KC_K, KC_L, KC_COMM, KC_DOT, KC_SLSH, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* Punc
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | ` |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | \ | - | = | < | > | ( | ) | ' | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | _ | + | { | } | [ | ] | " | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_PUNC] = KEYMAP(
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_GRV ,
XXXXXXX, XXXXXXX, KC_BSLS, KC_MINS, KC_EQL, KC_LABK, KC_RABK, KC_LPRN, KC_RPRN, KC_QUOT, XXXXXXX, XXXXXXX,
XXXXXXX, XXXXXXX, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_DQUO, XXXXXXX, XXXXXXX,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* Num
* ,-----------------------------------------------------------------------------------.
* | ^ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | @ | A | B | C | ( | ) | 4 | 5 | 6 | : |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | & | # | D | E | F | [ | ] | 1 | 2 | 3 | / | * |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | x | | | 0 | , | . | + | - |
* `-----------------------------------------------------------------------------------'
*/
[_NUM] = KEYMAP(
KC_CIRC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
KC_ESC, KC_AT, S(KC_A), S(KC_B), S(KC_C), KC_LPRN, KC_RPRN, KC_4, KC_5, KC_6, KC_COLN, KC_ENT,
KC_AMPR, KC_HASH, S(KC_D), S(KC_E), S(KC_F), KC_LBRC, KC_RBRC, KC_1, KC_2, KC_3, KC_SLSH, KC_ASTR,
_______, _______, _______, KC_X, _______, KC_SPC, KC_SPC, KC_0, KC_COMM, KC_DOT, KC_PLUS, KC_MINS
),
/* Func
* ,-----------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | | | PgUp | Up | PgDn | PgUp | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | F5 | F6 | F7 | F8 |PrtSc | | Left | Down | Right| PgDn | Ins |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F9 | F10 | F11 | F12 | | | | Home | End | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_FUNC] = KEYMAP(
XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, XXXXXXX, KC_PGUP, KC_UP, KC_PGDN, KC_PGUP, KC_DEL,
XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8,KC_PSCREEN,XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_INS,
_______, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_END, XXXXXXX, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
/* Emoji
* ,-----------------------------------------------------------------------------------.
* | | | | | | | | | | | | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_EMOJI] = KEYMAP(
X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW),
X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS),
X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH),
X(POO), X(EYES),X(HUNRD), _______,X(SKULL),X(HORNS), X(HALO), X(FEAR), _______,X(YUMMY),X(DISAP),X(NOEVK)
),
/* GUI
* ,-----------------------------------------------------------------------------------.
* | | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* |Linux | | Vol- | Mute | Vol+ | | | D- | | D+ | |Qwerty|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Win | | Prev | Play | Next | | | | | | |Colmak|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | OSX | | | | | BL- | BL+ | | | | |Workmn|
* `-----------------------------------------------------------------------------------'
*/
[_GUI] = KEYMAP(
_______, LGUI(KC_1),LGUI(KC_2),LGUI(KC_3),LGUI(KC_4),LGUI(KC_5),LGUI(KC_6),LGUI(KC_7),LGUI(KC_8),LGUI(KC_9),LGUI(KC_0), _______,
LINUX, _______, KC_VOLD, KC_MUTE, KC_VOLU,_______,_______,KC_WWW_BACK,_______,KC_WWW_FORWARD,KC_PAUS, QWERTY,
WIN, _______, KC_MPRV, KC_MPLY, KC_MNXT, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, COLEMAK,
OSX, _______, _______, _______, _______, BL_DEC, BL_INC, _______, _______, RGB_VAI, RGB_VAD, WORKMAN
),
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_workman[][2] = SONG(DVORAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float tone_linux[][2] = SONG(CAPS_LOCK_ON_SOUND);
float tone_windows[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_osx[][2] = SONG(NUM_LOCK_ON_SOUND);
float tone_click[][2] = SONG(MUSICAL_NOTE(_F3, 2));
#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) {
#ifdef AUDIO_ENABLE
// faux clicky
if (record->event.pressed) PLAY_NOTE_ARRAY(tone_click, false, 0);
#endif
switch (keycode) {
// QWERTZ style comma and dot: semicolon and colon when shifted
case KC_COMM:
if (record->event.pressed) {
bool lshifted = keyboard_report->mods & MOD_BIT(KC_LSFT);
bool rshifted = keyboard_report->mods & MOD_BIT(KC_RSFT);
if (lshifted || rshifted) {
if (lshifted) unregister_code(KC_LSFT);
if (rshifted) unregister_code(KC_RSFT);
register_code(KC_SCLN);
unregister_code(KC_SCLN);
if (lshifted) register_code(KC_LSFT);
if (rshifted) register_code(KC_RSFT);
} else {
register_code(KC_COMM);
unregister_code(KC_COMM);
}
}
return false;
break;
case KC_DOT:
if (record->event.pressed) {
if ((keyboard_report->mods & MOD_BIT(KC_LSFT)) || (keyboard_report->mods & MOD_BIT(KC_RSFT))) {
register_code(KC_SCLN);
unregister_code(KC_SCLN);
} else {
register_code(KC_DOT);
unregister_code(KC_DOT);
}
}
return false;
break;
// layout switchers
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case WORKMAN:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_workman, false, 0);
#endif
persistant_default_layer_set(1UL<<_WORKMAN);
}
return false;
break;
// layer switcher
case PUNC:
if (record->event.pressed) {
layer_on(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _GUI);
if (IS_LAYER_ON(_GUI)) {
led_layer_gui();
} else {
led_layer_punc();;
}
} else {
layer_off(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _GUI);
if (IS_LAYER_ON(_EMOJI)) {
led_layer_emoji();
} else {
led_layer_normal();;
}
}
return false;
break;
case EMOJI:
if (record->event.pressed) {
layer_on(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _GUI);
if (IS_LAYER_ON(_GUI)) {
led_layer_gui();
} else {
led_layer_emoji();;
}
} else {
layer_off(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _GUI);
if (IS_LAYER_ON(_PUNC)) {
led_layer_punc();
} else {
led_layer_normal();;
}
}
return false;
break;
case NUM:
if (record->event.pressed) {
layer_on(_NUM);
led_layer_num();
} else {
layer_off(_NUM);
led_layer_normal();
}
return false;
break;
case FUNC:
if (record->event.pressed) {
layer_on(_FUNC);
led_layer_func();
} else {
layer_off(_FUNC);
led_layer_normal();
}
return false;
break;
// OS switchers
case LINUX:
set_unicode_input_mode(UC_LNX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_linux, false, 0);
#endif
return false;
break;
case WIN:
set_unicode_input_mode(UC_WINC);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_windows, false, 0);
#endif
return false;
break;
case OSX:
set_unicode_input_mode(UC_OSX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_osx, false, 0);
#endif
return false;
break;
}
return true;
}
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
set_unicode_input_mode(UC_LNX);
led_init();
}
// void init_rgblight(void) {
// for (uint8_t i = 0; i < RGBLED_NUM; i++) {
// led[i].r = 255;
// led[i].g = 85;
// led[i].b = 0;
// }
// ws2812_setleds(led, RGBLED_NUM);
// }
#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();
}
#endif
void ps2_mouse_init_user() {
uint8_t rcv;
// set TrackPoint sensitivity
PS2_MOUSE_SEND(0xE2, "set trackpoint sensitivity: 0xE2");
PS2_MOUSE_SEND(0x81, "set trackpoint sensitivity: 0x81");
PS2_MOUSE_SEND(0x4A, "set trackpoint sensitivity: 0x4A");
PS2_MOUSE_SEND(0x49, "set trackpoint sensitivity: 0x59");
// set TrackPoint Negative Inertia factor
PS2_MOUSE_SEND(0xE2, "set negative inertia factor: 0xE2");
PS2_MOUSE_SEND(0x81, "set negative inertia factor: 0x81");
PS2_MOUSE_SEND(0x4D, "set negative inertia factor: 0x4D");
PS2_MOUSE_SEND(0x06, "set negative inertia factor: 0x06");
// set TrackPoint speed
// (transfer function upper plateau speed)
PS2_MOUSE_SEND(0xE2, "set trackpoint speed: 0xE2");
PS2_MOUSE_SEND(0x81, "set trackpoint speed: 0x81");
PS2_MOUSE_SEND(0x60, "set trackpoint speed: 0x60");
PS2_MOUSE_SEND(0x61, "set trackpoint speed: 0x61");
// inquire pts status
rcv = ps2_host_send(0xE2);
rcv = ps2_host_send(0x2C);
rcv = ps2_host_recv_response();
if ((rcv & 1) == 1) {
// if on, disable pts
rcv = ps2_host_send(0xE2);
rcv = ps2_host_send(0x47);
rcv = ps2_host_send(0x2C);
rcv = ps2_host_send(0x01);
}
}

@ -0,0 +1,22 @@
# How to add your own keymap
Folders can be named however you'd like (will be approved upon merging), or should follow the format with a preceding `_`:
_[ISO 3166-1 alpha-2 code*]_[layout variant]_[layout name/author]
\* See full list: https://en.wikipedia.org/wiki/ISO_3166-1#Officially_assigned_code_elements
and contain the following files:
* `keymap.c`
* `readme.md` *recommended*
* `config.h` *optional*, found automatically when compiling
* `Makefile` *optional*, found automatically when compling
When adding your keymap to this list, keep it organised alphabetically (select list, edit->sort lines), and use this format:
* **folder_name** description
# List of Promethium keymaps

@ -0,0 +1,6 @@
#include "promethium.h"
void matrix_init_kb(void) {
matrix_init_user();
}

@ -0,0 +1,101 @@
#ifndef PROMETHIUM_H
#define PROMETHIUM_H
#include "quantum.h"
#define PS2_INIT_DELAY 2000
#define KEYMAP( \
k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, \
k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, \
k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, \
k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c \
) \
{ \
{k11, k12, k13, k14, k15, k16}, \
{k21, k22, k23, k24, k25, k26}, \
{k31, k32, k33, k34, k35, k36}, \
{k41, k42, k43, k44, k45, k46}, \
{k17, k18, k19, k1a, k1b, k1c}, \
{k27, k28, k29, k2a, k2b, k2c}, \
{k37, k38, k39, k3a, k3b, k3c}, \
{k47, k48, k49, k4a, k4b, k4c} \
}
enum led_sequence {
LED_IND_BLUETOOTH,
LED_IND_USB,
LED_IND_BATTERY,
LED_IND_FUNC,
LED_IND_NUM,
LED_IND_EMOJI,
LED_BKSP,
LED_ENT,
LED_RSFT,
LED_RCTL,
LED_RGUI,
LED_SLSH,
LED_SCLN,
LED_P,
LED_O,
LED_L,
LED_DOT,
LED_RALT,
LED_EMOJI,
LED_COMM,
LED_K,
LED_I,
LED_U,
LED_J,
LED_M,
LED_FUNC,
LED_RSPC,
LED_N,
LED_HH,
LED_Y,
LED_TRACKPOINT3,
LED_TRACKPOINT2,
LED_TRACKPOINT1,
LED_LSPC,
LED_B,
LED_G,
LED_T,
LED_R,
LED_F,
LED_V,
LED_NUM,
LED_PUNC,
LED_C,
LED_D,
LED_E,
LED_W,
LED_S,
LED_X,
LED_LALT,
LED_LGUI,
LED_Z,
LED_A,
LED_Q,
LED_TAB,
LED_ESC,
LED_LSFT,
LED_LCTL,
};
#endif

@ -0,0 +1,13 @@
Promethium Keyboard Firmware
============================
A handwired Planck based keyboard using the Adafruit Feather 32u4 Bluefruit LE controller.
Features:
* Single piece split form factor
* Columnar stagger
* Trackpoint
* Bluetooth LE *TBD*
* Battery
* Per switch RGB LED
* Proximity sensor for energy conservation *TBD*

@ -0,0 +1,24 @@
#include "light_ws2812.h"
#include "rgbsps.h"
struct cRGB led[RGBSPS_NUM];
void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
led[index].r = r;
led[index].g = g;
led[index].b = b;
}
void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) {
for (uint16_t i = 0; i < RGBSPS_NUM; i++) {
rgbsps_set(i, r, g, b);
}
}
void rgbsps_turnoff(void) {
rgbsps_setall(0, 0, 0);
}
void rgbsps_send(void) {
ws2812_setleds(led, RGBSPS_NUM);
}

@ -0,0 +1,4 @@
void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b);
void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b);
void rgbsps_turnoff(void);
void rgbsps_send(void);

@ -0,0 +1,75 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 8000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
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 ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
UNICODEMAP_ENABLE ?= yes
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PS2_MOUSE_ENABLE ?= yes
PS2_USE_INT ?= yes
ADAFRUIT_BLE_ENABLE ?= yes
API_SYSEX_ENABLE ?= no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
SRC += $(QUANTUM_DIR)/light_ws2812.c
SRC += rgbsps.c

@ -35,19 +35,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |-----------------------------------------------------------------------------------------+
* | Caps | | | | | | | |PrtSc| Slck| Paus| Up | | |
* |-----------------------------------------------------------------------------------------+
* | | Vol-| Vol+| Mute| | | | | Home| PgUp| Left |Right| |
* | | Vol-| Vol+| Mute| | | * | / | Home| PgUp| Left |Right| |
* |-----------------------------------------------------------------------------------------+
* | | Prev| Play| Next| | | | | End |PgDwn| Down| | |
* | | Prev| Play| Next| | | + | - | End |PgDwn| Down| | |
* +-----------------------------------------------------------------------------------------+
* | | | | | |
* | | | | Stop | |
* `----------------------------------------------------------------´
*/
[FN] = KEYMAP(
KC_PWR, 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_INS, KC_DEL, \
KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \
KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \
KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_MSTP, KC_TRNS
),
/* MOUSE Layer

@ -0,0 +1 @@
OPT_DEFS += -DHHKB_JP

@ -0,0 +1,86 @@
###Keymaps with both Dvorak layout and QWER layout for HHKB JP.
1. The default layout is Dvorak.
2. Use `Tog` to toggle between Dvorak and QWER
3. Holding `NewCmd`, the original `LftCmd`, will activate the `NewCmd` layer which means `NewCmd+key` is the same as `Cmd+key` in normal QWER layout.<sup>[1](#cmdTab)</sup>
- For example, no matter you are in Dvorak layout or QWER layout, you can use `Cmd+s` to save a currently editing file.
4. `Symb` makes type symbols easier
- for example: `Symb+a` is `!`.
5. `Spc+key` equals to `Shft+key` while using `Spc` alone will yield a space as usual.
6. There's an extra `Tab` in the last line.
```
Layer DVOR:
,-----------------------------------------------------------.
|Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| |Bsp|
|-----------------------------------------------------------|
|Tab | '| ,| .| P| Y| F| G| C| R| L| /| =| |
|------------------------------------------------------` Ent|
|Ctrl | A| O| E| U| I| D| H| T| N| S| -| \| |
|-----------------------------------------------------------|
|Shft | ;| Q| J| K| X| B| M| W| V| Z| | Up| |
|-----------------------------------------------------------|
|FN| `| Alt|NewCmd|Symb| Spc |Symb|Tab|RCmd|Tog|Lft|Dwn|Rgh|
`-----------------------------------------------------------'
```
```
Layer QWER:
,-----------------------------------------------------------.
|Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| -| =| |Bsp|
|-----------------------------------------------------------|
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| |
|------------------------------------------------------` Ent|
|Ctrl | A| S| D| F| G| H| J| K| L| ;| '| \| |
|-----------------------------------------------------------|
|Shft | Z| X| C| V| B| N| M| ,| .| /| | Up| |
|-----------------------------------------------------------|
|FN| `| Alt|NewCmd|Symb| Spc |Symb|Tab|Cmd|Tog|Lft|Dwn|Rgh|
`-----------------------------------------------------------'
```
```
Layer Symb:
,-----------------------------------------------------------.
| | | | | | | | | | | | | | | |
|-----------------------------------------------------------|
| | | | [| ]| | | {| }| | | | | |
|------------------------------------------------------` |
| | !| @| #| $| %| ^| &| *| (| )| '| \| |
|-----------------------------------------------------------|
| | | | | | | | | | | | | | |
|-----------------------------------------------------------|
| | | | | | | | | | | | | |
`-----------------------------------------------------------'
```
```
Layer FUNC: HHKB mode (HHKB Fn)
,-----------------------------------------------------------.
|Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
|-----------------------------------------------------------|
|Caps | | | | | | | |Psc|Slk|Pus|Up | | |
|------------------------------------------------------` |
| |VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig| | |
|-----------------------------------------------------------|
| | | | | | | +| -|End|PgD|Dow| | | |
|-----------------------------------------------------------|
| || | | | | | | | | || | | |
`-----------------------------------------------------------'
```
```
Empty Layer:
,-----------------------------------------------------------.
| | | | | | | | | | | | | | | |
|-----------------------------------------------------------|
| | | | | | | | | | | | | | |
|------------------------------------------------------` |
| | | | | | | | | | | | | | |
|-----------------------------------------------------------|
| | | | | | | | | | | | | | |
|-----------------------------------------------------------|
| | | | | | | | | | | | | |
`-----------------------------------------------------------'
```
<a name="cmdTab">1</a>: `NewCmd + Tab` does not work, you can use `RCmd+Tab` to switch among applications.

@ -0,0 +1,60 @@
#include "hhkb.h"
#define _______ KC_TRNS
enum {
DVOR,
QWER,
NEW_CMD,
SYMB,
FUNC
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[DVOR] = KEYMAP_JP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_LBRC, KC_RBRC, KC_JYEN, KC_BSPC,
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH, KC_EQL,
KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS, KC_BSLS, KC_ENT,
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RO, KC_UP, KC_RSFT,
MO(FUNC), KC_ZKHK, KC_LALT, MO(NEW_CMD), MO(SYMB), MT(MOD_LSFT, KC_SPC), MO(SYMB), KC_TAB, KC_RGUI, TG(QWER), KC_LEFT, KC_DOWN, KC_RGHT
),
[QWER] = KEYMAP_JP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_JYEN, KC_BSPC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC,
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_ENT,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_UP, KC_RSFT,
MO(FUNC), KC_ZKHK, KC_LALT, MO(NEW_CMD), MO(SYMB), MT(MOD_LSFT, KC_SPC), MO(SYMB), KC_TAB, KC_RGUI, _______, KC_LEFT, KC_DOWN, KC_RGHT
),
[NEW_CMD] = KEYMAP_JP(
_______, LGUI(KC_1), LGUI(KC_2), LGUI(KC_3), LGUI(KC_4), LGUI(KC_5), LGUI(KC_6), LGUI(KC_7), LGUI(KC_8), LGUI(KC_9), LGUI(KC_0), _______, _______, _______, LGUI(KC_BSPC),
_______, LGUI(KC_Q), LGUI(KC_W), LGUI(KC_E), LGUI(KC_R), LGUI(KC_T), LGUI(KC_Y), LGUI(KC_U), LGUI(KC_I), LGUI(KC_O), LGUI(KC_P), LGUI(KC_LBRC), LGUI(KC_RBRC),
_______, LGUI(KC_A), LGUI(KC_S), LGUI(KC_D), LGUI(KC_F), LGUI(KC_G), LGUI(KC_H), LGUI(KC_J), LGUI(KC_K), LGUI(KC_L), _______, _______, _______, _______,
LGUI(KC_LSFT), LGUI(KC_Z), LGUI(KC_X), LGUI(KC_C), LGUI(KC_V), LGUI(KC_B), LGUI(KC_N), LGUI(KC_M), LGUI(KC_COMM), LGUI(KC_DOT), LGUI(KC_SLSH), _______, _______, _______,
_______, _______, _______, _______, _______, LGUI(KC_SPC), _______, _______, _______, _______, LGUI(KC_LEFT), LGUI(KC_DOWN), LGUI(KC_RGHT)
),
[SYMB] = KEYMAP_JP(
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, KC_LBRC, KC_RBRC, _______, _______, LSFT(KC_LBRC), LSFT(KC_RBRC), _______, _______,_______, _______,
_______, LSFT(KC_1),LSFT(KC_2),LSFT(KC_3),LSFT(KC_4), LSFT(KC_5), LSFT(KC_6), LSFT(KC_7), LSFT(KC_8), LSFT(KC_9), LSFT(KC_0), _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
),
[FUNC] = KEYMAP_JP(
KC_PWR, 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_INS, KC_DEL,
KC_CAPS, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, _______,
_______, KC_VOLD, KC_VOLU, KC_MUTE, KC_PWR, _______, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, _______, KC_PENT,
_______, _______, _______, _______, _______, _______, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, _______, _______, _______,
_______, _______, _______, _______, _______, _______ , _______, _______, _______, _______, _______, _______, _______
)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t macro_id, uint8_t opt) {
return MACRO_NONE;
}
const uint16_t PROGMEM fn_actions[] = {
};

@ -48,7 +48,7 @@
* @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit.
*/
#define CH_CFG_ST_FREQUENCY 1000
#define CH_CFG_ST_FREQUENCY 100000
/**
* @brief Time delta constant for the tick-less mode.

@ -96,7 +96,12 @@ uint8_t matrix_scan(void)
}
#endif
wait_us(1); // need wait to settle pin state
// need wait to settle pin state
// if you wait too short, or have a too high update rate
// the keyboard might freeze, or there might not be enough
// processing power to update the LCD screen properly.
// 20us, or two ticks at 100000Hz seems to be OK
wait_us(20);
// read col data
data = (palReadPort(GPIOD)>>1);

@ -1,74 +1,3 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
# CONSOLE_ENABLE ?= yes # Console for debug(+400)
# COMMAND_ENABLE ?= yes # Commands for debug and configuration
KEYBOARD_LOCK_ENABLE ?= yes # Allow locking of keyboard via magic key
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
# SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
# BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
# MIDI_ENABLE ?= YES # MIDI controls
# UNICODE_ENABLE ?= YES # Unicode
# BLUETOOTH_ENABLE ?= yes # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= yes # Enable RGB Underglow
ifndef QUANTUM_DIR
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -70,7 +70,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
)
#define RGB_DI_PIN D3
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12 // Number of LEDs
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8

@ -61,7 +61,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |-----------------------------------------------------------------------------------------+
* | | | | | | | | Psc | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | Led | Led-| Led+| | Mute| Vol+| Vol-| | | | Play | |
* | | Led | Led+| Led-| | Mute| Vol+| Vol-| | | | Play | |
* |-----------------------------------------------------------------------------------------+
* | | | | | | Prev | Stop | Next |
* `-----------------------------------------------------------------------------------------'

@ -0,0 +1,73 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "kc60.h"
#define _QWERTY 0
#define _FN 1
// Fillers to make layering more clear
#define ______ KC_TRNS
#define XXXXXXX KC_NO
// Func macro definitions.
#define S_LED FUNC(0)
#define S_LEDI FUNC(1)
#define S_LEDD FUNC(2)
// Enable these functions using FUNC(n) macro.
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_BACKLIGHT_TOGGLE(),
[1] = ACTION_BACKLIGHT_INCREASE(),
[2] = ACTION_BACKLIGHT_DECREASE()
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | \ | ` |
* |-----------------------------------------------------------------------------------------+
* | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | Bksp |
* |-----------------------------------------------------------------------------------------+
* | Ctrl | A | S | D | F | G | H | J | K | L | ; | ' | Enter |
* |-----------------------------------------------------------------------------------------+
* | Shift | Z | X | C | V | B | N | M | , | . | / | RShift | FN |
* |-----------------------------------------------------------------------------------------+
* | LGUI | LAlt | Space | RAlt | RGUI |
* `-----------------------------------------------------------------'
*/
[0] = KEYMAP( /* Basic QWERTY */
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MO(_FN), KC_RSFT, \
______, KC_LGUI, KC_LALT, KC_SPC, KC_GRV, KC_RALT, KC_RGUI, ______, ______ \
),
/* Layer 1
* ,-----------------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | Ins | Del |
* |-----------------------------------------------------------------------------------------+
* | CAPS | Led | Led-| Led+| | | | | Psc | Slck| Paus| Up | | |
* |-----------------------------------------------------------------------------------------+
* | | Vol-| Vol+| Mute| | | * | / | Home| PgUp| Left|Right| |
* |-----------------------------------------------------------------------------------------+
* | | Prev| Play| Next| | | + | - | End |PgDn| Down| | |
* |-----------------------------------------------------------------------------------------+
* | | | | Stop | |
* `-----------------------------------------------------------------'
*/
[_FN] = KEYMAP( /* Layer 1 */
______, 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_INS, \
KC_CAPS, S_LED, S_LEDI, S_LEDD, ______, ______, ______, ______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, ______, ______, \
______, KC_VOLD, KC_VOLU, KC_MUTE, ______, ______, KC_PAST, KC_PSLS,KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, ______, ______, \
______, ______, KC_MPRV, KC_MPLY, KC_MNXT,______,______,KC_PPLS,KC_PMNS,KC_END, KC_PGDN, KC_DOWN, ______,______, \
______, ______, ______, ______, KC_DEL, KC_MSTP, ______, ______, ______ \
)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
return MACRO_NONE;
};

@ -0,0 +1,9 @@
# Dbroqua HHKB like Layout
Like the HHKB but with a KC60 PCB :D.
# Programming Instructions:
Enter into programming mode and run the following command.
```
$ sudo KEYMAP=dbroqua_hhkb make dfu
```

@ -2,7 +2,7 @@
/* WS2812B RGB Underglow LED */
#define RGB_DI_PIN F5 // Based on wiring depicted in ws2812_wiring.jpg
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 16 // Number of LEDs. Change this to match your use case.
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8

@ -28,29 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PRODUCT Lets Split
#define DESCRIPTION A split keyboard for the cheap makers
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 8
#define MATRIX_COLS 6
// wiring of each half
#define MATRIX_ROW_PINS { B5, B4, E6, D7 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3 }
#define CATERINA_BOOTLOADER
// #define USE_I2C
// Use serial if not using I2C
#ifndef USE_I2C
# define USE_SERIAL
#endif
// #define EE_HANDS
#define I2C_MASTER_LEFT
// #define I2C_MASTER_RIGHT
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
@ -73,24 +50,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* ws2812 RGB LED */
#define RGB_DI_PIN D4
#define RGBLIGHT_TIMER
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
// #define NO_DEBUG
//#define NO_DEBUG
/* disable print */
// #define NO_PRINT
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
@ -99,4 +63,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#ifdef SUBPROJECT_rev1
#include "rev1/config.h"
#endif
#ifdef SUBPROJECT_rev2
#include "rev2/config.h"
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 753 KiB

@ -42,10 +42,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = KEYMAP( \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
KC_TAB, 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 , \
ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
KC_LCTL, ADJUST, KC_LALT, KC_LGUI, LOWER, KC_SPC, MT(MOD_LSFT, KC_SPC), RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
),
/* Colemak
@ -83,41 +83,17 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , \
ADJUST, 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] = KEYMAP( \
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
[3] = KEYMAP( \
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_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_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
_______, _______, _______, _______, _______, KC_BSPC, MT(MOD_LSFT, KC_BSPC), _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
),
/* 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] = KEYMAP( \
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
[4] = KEYMAP( \
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_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_NUHS, KC_NUBS, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
_______, _______, _______, _______, _______, KC_ENT, MT(MOD_LSFT, KC_ENT), _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
),
/* Adjust (Lower + Raise)
@ -134,11 +110,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_ADJUST] = KEYMAP( \
_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, RGB_TOG,RGB_MOD,RGB_HUI,RGB_HUD,RGB_SAI,RGB_SAD,RGB_VAI,RGB_VAD, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
)
};
#ifdef AUDIO_ENABLE

@ -75,7 +75,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* ws2812 RGB LED */
#define RGB_DI_PIN D4
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -75,7 +75,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* ws2812 RGB LED */
#define RGB_DI_PIN D4
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -1,32 +1 @@
#include "lets_split.h"
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void matrix_init_kb(void) {
#ifdef AUDIO_ENABLE
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
// // green led on
// DDRD |= (1<<5);
// PORTD &= ~(1<<5);
// // orange led on
// DDRB |= (1<<0);
// PORTB &= ~(1<<0);
matrix_init_user();
};
void shutdown_user(void) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
#endif
}
#include "lets_split.h"

@ -1,25 +1,13 @@
#ifndef LETS_SPLIT_H
#define LETS_SPLIT_H
#include "quantum.h"
void promicro_bootloader_jmp(bool program);
#ifdef SUBPROJECT_rev1
#include "rev1.h"
#endif
#ifdef SUBPROJECT_rev2
#include "rev2.h"
#endif
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 }, \
{ k50, k51, k52, k53, k54, k55 }, \
{ k60, k61, k62, k63, k64, k65 }, \
{ k70, k71, k72, k73, k74, k75 } \
}
#include "quantum.h"
#endif

@ -100,3 +100,16 @@ half to a computer by USB the keyboard will use QWERTY and Colemak when the
right half is connected.
Notes on Using Pro Micro 3.3V
-----------------------------
Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects
the frequency on the 3.3V board.
Also, if the slave board is producing weird characters in certain columns,
update the following line in `matrix.c` to the following:
```
// _delay_us(30); // without this wait read unstable value.
_delay_us(300); // without this wait read unstable value.
```

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,94 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x3060
#define DEVICE_VER 0x0001
#define MANUFACTURER Wootpatoot
#define PRODUCT Lets Split
#define PRODUCT Lets Split v1
#define DESCRIPTION A split keyboard for the cheap makers
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 8
#define MATRIX_COLS 6
// wiring of each half
#define MATRIX_ROW_PINS { B5, B4, E6, D7 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3 }
#define CATERINA_BOOTLOADER
// #define USE_I2C
// Use serial if not using I2C
#ifndef USE_I2C
# define USE_SERIAL
#endif
// #define EE_HANDS
#define I2C_MASTER_LEFT
// #define I2C_MASTER_RIGHT
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
// #define NO_DEBUG
/* disable print */
// #define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,32 @@
#include "lets_split.h"
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void matrix_init_kb(void) {
#ifdef AUDIO_ENABLE
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
// // green led on
// DDRD |= (1<<5);
// PORTD &= ~(1<<5);
// // orange led on
// DDRB |= (1<<0);
// PORTB &= ~(1<<0);
matrix_init_user();
};
void shutdown_user(void) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
#endif
}

@ -0,0 +1,28 @@
#ifndef REV1_H
#define REV1_H
#include "../lets_split.h"
//void promicro_bootloader_jmp(bool program);
#include "quantum.h"
//void promicro_bootloader_jmp(bool program);
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 }, \
{ k50, k51, k52, k53, k54, k55 }, \
{ k60, k61, k62, k63, k64, k65 }, \
{ k70, k71, k72, k73, k74, k75 } \
}
#endif

@ -0,0 +1,5 @@
BACKLIGHT_ENABLE = no
ifndef QUANTUM_DIR
include ../../../Makefile
endif

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,102 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x3060
#define DEVICE_VER 0x0001
#define MANUFACTURER Wootpatoot
#define PRODUCT Lets Split v2
#define DESCRIPTION A split keyboard for the cheap makers
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 8
#define MATRIX_COLS 6
// wiring of each half
#define MATRIX_ROW_PINS { D7, E6, B4, B5 }
#define MATRIX_COL_PINS { F6, F7, B1, B3, B2, B6 }
#define CATERINA_BOOTLOADER
// #define USE_I2C
// Use serial if not using I2C
#ifndef USE_I2C
# define USE_SERIAL
#endif
// #define EE_HANDS
#define I2C_MASTER_LEFT
// #define I2C_MASTER_RIGHT
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* ws2812 RGB LED */
#define RGB_DI_PIN D3
#define RGBLIGHT_TIMER
#define RGBLED_NUM 12 // Number of LEDs
#define ws2812_PORTREG PORTD
#define ws2812_DDRREG DDRD
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
// #define NO_DEBUG
/* disable print */
// #define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,32 @@
#include "lets_split.h"
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void matrix_init_kb(void) {
#ifdef AUDIO_ENABLE
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
// // green led on
// DDRD |= (1<<5);
// PORTD &= ~(1<<5);
// // orange led on
// DDRB |= (1<<0);
// PORTB &= ~(1<<0);
matrix_init_user();
};
void shutdown_user(void) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
#endif
}

@ -0,0 +1,28 @@
#ifndef REV2_H
#define REV2_H
#include "../lets_split.h"
//void promicro_bootloader_jmp(bool program);
#include "quantum.h"
//void promicro_bootloader_jmp(bool program);
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 }, \
{ k50, k51, k52, k53, k54, k55 }, \
{ k60, k61, k62, k63, k64, k65 }, \
{ k70, k71, k72, k73, k74, k75 } \
}
#endif

@ -0,0 +1,5 @@
BACKLIGHT_ENABLE = no
ifndef QUANTUM_DIR
include ../../../Makefile
endif

@ -63,11 +63,12 @@ COMMAND_ENABLE ?= yes # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= yes # Audio output on port C6
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SUBPROJECT_rev1 ?= yes
USE_I2C ?= yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,95 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER wootpatoot
#define PRODUCT maxipad
#define DESCRIPTION A custom keyboard
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 6
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
//Pro micro pinout
#define MATRIX_ROW_PINS { B6, B2, B3, B1, F7 }
#define MATRIX_COL_PINS { F4, C6, D7, F5, B4, B5 }
#define UNUSED_PINS
//Teensy 2 pinout
//#define MATRIX_ROW_PINS { B6, F7, B2, B3, B1 }
//#define MATRIX_COL_PINS { F6, C6, D7, F5, B4, B5 }
//#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
#define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,26 @@
#include "maxipad.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP( /* Base */
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, \
MO(1), KC_A, KC_S, KC_D, KC_F, KC_G, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, \
KC_LCTL, KC_LALT, MO(1), KC_ENT,KC_GRV,KC_SPC \
),
[1] = KEYMAP(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, \
KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT, 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_SPC \
),
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // MACRODOWN only works in this function
{
return MACRO_NONE;
};

@ -0,0 +1 @@
#include "maxipad.h"

@ -0,0 +1,25 @@
#ifndef MAXIPAD_H
#define MAXIPAD_H
#include "quantum.h"
// This a shortcut to help you visually see your layout.
// The following is an example using the Planck MIT layout
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, \
k10, k11, k12, k13, k14, k15, \
k20, k21, k22, k23, k24, k25, \
k30, k31, k32, k33, k34, k35, \
k40, k41, k42, k43, k44, k45 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 } \
}
#endif

@ -0,0 +1,29 @@
Maxipad keyboard firmware
## Quantum MK Firmware
For the full Quantum feature list, see [the parent readme.md](/readme.md).
If you are using a pro micro then make sure to enable USE_PRO_MICRO in the makefile
Change the config.h pinout to match your mcu!!
Download or clone the whole firmware and navigate to the keyboards/maxipad folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file.
Depending on which keymap you would like to use, you will have to compile slightly differently.
### Default
To build with the default keymap, simply run `make`.
### Other Keymaps
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `<name>.c` and see keymap document (you can find in top readme.md) and existent keymap files.
To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
```
$ make [default|jack|<name>]
```
Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.

@ -0,0 +1,76 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# comment out to disable the options.
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
# SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
# NKRO_ENABLE ?= yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
# BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
# MIDI_ENABLE ?= YES # MIDI controls
# UNICODE_ENABLE ?= YES # Unicode
# BLUETOOTH_ENABLE ?= yes # Enable Bluetooth with the Adafruit EZ-Key HID
USE_PRO_MICRO ?= yes
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,24 @@
pegasushoof keyboard firmware
=============================
## Quantum MK Firmware
For the full Quantum feature list, see [the parent README.md](/README.md).
## Building
Download or clone the whole firmware and navigate to the `keyboard/pegasushoof` folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your `.hex` file.
Depending on which keymap you would like to use, you will have to compile slightly differently.
### Default
To build all keymaps, simply run `make`, the `.hex` files will end up in the top directory.
### Specific Keymap
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `<name>/keymap.c` in the `keymaps` folder, and see keymap document (you can find in top README.md) and existent keymap files.
To build the firmware binary hex file with a keymap just enter the keymap directory and type `make`:
```
$ cd keymaps/default
$ make
```

@ -0,0 +1,46 @@
/*
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6050
#define DEVICE_VER 0x0104
#define MANUFACTURER Filco
#define PRODUCT Majestouch TKL \\w The Pegasus Hoof
#define DESCRIPTION QMK firmware for Majestouch TKL
/* key matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 18
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
#endif

@ -0,0 +1,22 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
CUSTOM_MATRIX ?= yes # Custom matrix file for the Pegasus Hoof due to the 2x74HC42
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,112 @@
/*
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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 "pegasushoof.h"
#define _______ KC_TRNS
/* Swedish keys */
#define SE_HALF KC_GRV
#define SE_PLUS KC_MINS
#define SE_ACUT KC_EQL
#define SE_AO KC_LBRC
#define SE_CIRC KC_RBRC
#define SE_QUOT KC_BSLS
#define SE_OE KC_SCLN
#define SE_AE KC_QUOT
#define SE_MINS KC_SLSH
#define SE_LTGT KC_NUBS
#define SE_LCBR RALT(KC_7)
#define SE_LBRC RALT(KC_8)
#define SE_RBRC RALT(KC_9)
#define SE_RCBR RALT(KC_0)
#define SE_PIPE RALT(SE_LTGT)
#define SE_BSLS RALT(SE_PLUS)
#define KM_BLOWRAK 0
#define KM_QWERTY 1
#define KM_MEDIA 2
#define KM_HAXHAX 3
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Layer 0: Blowrak ISO layer, a Swedish take on Dvorak */
[KM_BLOWRAK] = KEYMAP( \
KC_ESC, 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_PSCR,KC_SLCK,KC_PAUS, \
SE_HALF, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, SE_PLUS,SE_ACUT,KC_BSPC, KC_INS, KC_HOME,KC_PGUP, \
KC_TAB, SE_AO, SE_AE, SE_OE, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_COMM,SE_CIRC,SE_QUOT, KC_DEL, KC_END, KC_PGDN, \
KC_LCTRL,KC_A, KC_O, KC_E, KC_U, KC_I, KC_H, KC_D, KC_T, KC_N, KC_S, SE_MINS, KC_ENT, \
KC_LSFT, SE_LTGT,KC_DOT, KC_Q, KC_J, KC_K, KC_B, KC_X, KC_M, KC_W, KC_V, KC_Z, KC_RSFT, KC_UP, \
KC_FN0, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,KC_MENU,KC_FN1, KC_LEFT,KC_DOWN,KC_RGHT),
/* Layer 1: Standard ISO layer */
[KM_QWERTY] = KEYMAP( \
KC_ESC, 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_PSCR,KC_SLCK,KC_PAUS, \
SE_HALF, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, SE_PLUS,SE_ACUT,KC_BSPC, KC_INS, KC_HOME,KC_PGUP, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, SE_AO, SE_CIRC,SE_QUOT, KC_DEL, KC_END, KC_PGDN, \
KC_LCTRL,KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, SE_OE, SE_AE, KC_ENT, \
KC_LSFT, SE_LTGT,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, SE_MINS, KC_RSFT, KC_UP, \
KC_FN0, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,KC_MENU,KC_FN1, KC_LEFT,KC_DOWN,KC_RGHT),
/* Layer 2: Media layer */
[KM_MEDIA] = KEYMAP( \
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, KC_WAKE,KC_PWR, KC_SLEP, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,KC_VOLU, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, KC_MUTE,_______,KC_VOLD, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, KC_MPLY, \
_______,_______,_______, _______, _______,_______,RESET ,_______, KC_MPRV,KC_MSTP,KC_MNXT),
/* Layer 3: Programming layer */
[KM_HAXHAX] = KEYMAP( \
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______, \
_______,SE_LCBR,SE_PIPE,SE_RCBR,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______, \
_______,SE_LBRC,SE_BSLS,SE_RBRC,_______,_______,_______,_______,_______,_______,_______,_______, _______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______, \
_______,_______,_______, _______, _______,_______,_______,_______, _______,_______,_______),
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(KM_MEDIA),
[1] = ACTION_LAYER_TOGGLE(KM_QWERTY)
};
void matrix_scan_user(void)
{
uint8_t layer = biton32(layer_state);
switch (layer) {
case KM_BLOWRAK:
ph_caps_led_on();
ph_sclk_led_off();
break;
case KM_QWERTY:
ph_sclk_led_on();
ph_caps_led_off();
break;
}
}
/* Mixes in KM_HAXHAX via RALT modifier without shadowing the RALT key combinations. */
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
uint8_t modifiers = get_mods();
if (modifiers & MOD_BIT(KC_RALT) && record->event.pressed) {
uint16_t kc = keymap_key_to_keycode(KM_HAXHAX, record->event.key);
if (kc != KC_TRNS) {
register_code(kc);
unregister_code(kc);
return false;
}
}
return true;
}

@ -0,0 +1,22 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
CUSTOM_MATRIX ?= yes # Custom matrix file for the Pegasus Hoof due to the 2x74HC42
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,60 @@
/*
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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 "pegasushoof.h"
#define _______ KC_TRNS
#define KM_QWERTY 0
#define KM_MEDIA 1
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Layer 0: Standard ISO layer */
[KM_QWERTY] = KEYMAP( \
KC_ESC, 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_PSCR,KC_SLCK,KC_PAUS, \
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL, KC_BSPC, KC_INS, KC_HOME,KC_PGUP, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
KC_CLCK, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, \
KC_LSFT, KC_NUBS,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,KC_MENU,KC_FN0, KC_LEFT,KC_DOWN,KC_RGHT),
/* Layer 1: Function layer */
[KM_MEDIA] = KEYMAP( \
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, KC_WAKE,KC_PWR, KC_SLEP, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,KC_VOLU, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,KC_VOLD, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, KC_MPLY, \
_______,_______,_______, _______, _______,_______,RESET ,_______, KC_MPRV,KC_MSTP,KC_MNXT)
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(KM_MEDIA)
};
void led_set_user(uint8_t usb_led) {
if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
ph_caps_led_on();
} else {
ph_caps_led_off();
}
if (usb_led & (1 << USB_LED_SCROLL_LOCK)) {
ph_sclk_led_on();
} else {
ph_sclk_led_off();
}
}

@ -0,0 +1,204 @@
/*
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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 <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "wait.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
static uint8_t debouncing = DEBOUNCING_DELAY;
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static matrix_row_t read_cols(void);
static void select_row(uint8_t col);
inline uint8_t matrix_rows(void)
{
return MATRIX_ROWS;
}
inline uint8_t matrix_cols(void)
{
return MATRIX_COLS;
}
void matrix_init(void)
{
/* Column output pins */
DDRD |= 0b01111011;
/* Row input pins */
DDRC &= ~0b10000000;
DDRB &= ~0b01111111;
PORTC |= 0b10000000;
PORTB |= 0b01111111;
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
}
matrix_init_quantum();
}
uint8_t matrix_scan(void)
{
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
select_row(col);
wait_us(30);
matrix_row_t rows = read_cols();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
bool curr_bit = rows & (1<<row);
if (prev_bit != curr_bit) {
matrix_debouncing[row] ^= (matrix_row_t) 1 << col;
debouncing = DEBOUNCING_DELAY;
}
}
}
if (debouncing) {
if (--debouncing) {
wait_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
}
}
matrix_scan_quantum();
return 1;
}
bool matrix_is_modified(void)
{
if (debouncing)
return false;
return true;
}
inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
return matrix[row] & 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;
}
static matrix_row_t read_cols(void)
{
return
(PINB & (1 << 5) ? 0 : 1 << 0) |
(PINC & (1 << 7) ? 0 : 1 << 1) |
(PINB & (1 << 4) ? 0 : 1 << 2) |
(PINB & (1 << 6) ? 0 : 1 << 3) |
(PINB & (1 << 1) ? 0 : 1 << 4) |
(PINB & (1 << 0) ? 0 : 1 << 5) |
(PINB & (1 << 3) ? 0 : 1 << 6) |
(PINB & (1 << 2) ? 0 : 1 << 7);
}
static void select_row(uint8_t col)
{
switch (col) {
case 0:
PORTD = (PORTD & ~0b01111011) | 0b00110011;
break;
case 1:
PORTD = (PORTD & ~0b01111011) | 0b01110000;
break;
case 2:
PORTD = (PORTD & ~0b01111011) | 0b00010011;
break;
case 3:
PORTD = (PORTD & ~0b01111011) | 0b01101000;
break;
case 4:
PORTD = (PORTD & ~0b01111011) | 0b00001011;
break;
case 5:
PORTD = (PORTD & ~0b01111011) | 0b00111011;
break;
case 6:
PORTD = (PORTD & ~0b01111011) | 0b01111000;
break;
case 7:
PORTD = (PORTD & ~0b01111011) | 0b01100001;
break;
case 8:
PORTD = (PORTD & ~0b01111011) | 0b01101001;
break;
case 9:
PORTD = (PORTD & ~0b01111011) | 0b01110001;
break;
case 10:
PORTD = (PORTD & ~0b01111011) | 0b01101010;
break;
case 11:
PORTD = (PORTD & ~0b01111011) | 0b01100010;
break;
case 12:
PORTD = (PORTD & ~0b01111011) | 0b01111001;
break;
case 13:
PORTD = (PORTD & ~0b01111011) | 0b01100000;
break;
case 14:
PORTD = (PORTD & ~0b01111011) | 0b01000011;
break;
case 15:
PORTD = (PORTD & ~0b01111011) | 0b00011011;
break;
case 16:
PORTD = (PORTD & ~0b01111011) | 0b00100011;
break;
case 17:
PORTD = (PORTD & ~0b01111011) | 0b00101011;
break;
}
}

@ -0,0 +1,51 @@
/*
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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 "pegasushoof.h"
__attribute__ ((weak))
void matrix_init_user(void) {
};
__attribute__ ((weak))
void matrix_scan_user(void) {
}
__attribute__ ((weak))
bool process_action_user(keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {
}
void matrix_init_kb(void) {
matrix_init_user();
}
void matrix_scan_kb(void) {
matrix_scan_user();
}
bool process_action_kb(keyrecord_t *record) {
return process_action_user(record);
}
void led_set_kb(uint8_t usb_led) {
led_set_user(usb_led);
}

@ -0,0 +1,51 @@
/*
Copyright 2016 Daniel Svensson <dsvensson@gmail.com>
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/>.
*/
#ifndef PEGASUSHOOF_H
#define PEGASUSHOOF_H
#include "matrix.h"
#include "quantum.h"
#define ___ KC_NO
#define KEYMAP( \
KG6, KH4, KI4, KI2, KI6, KP5, KL6, KM2, KM4, KO4, KO5, KO6, KO0, KN5, KN7, KP7, \
KG4, KG5, KH5, KI5, KJ5, KJ4, KK4, KK5, KL5, KM5, KF5, KF4, KL4, KO2, KR4, KC4, KE4, \
KG2, KG7, KH7, KI7, KJ7, KJ2, KK2, KK7, KL7, KM7, KF7, KF2, KL2, KO3, KQ4, KC5, KE5, \
KH2, KG3, KH3, KI3, KJ3, KJ6, KK6, KK3, KL3, KM3, KF3, KF6, KO1, \
KB2, KH6, KG1, KH1, KI1, KJ1, KJ0, KK0, KK1, KL1, KM1, KF0, KB3, KC6, \
KP4, KD2, KN6, KQ6, KN0, KA3, KM0, KP1, KC0, KQ0, KR0 \
) { /* 00-A 01-B 02-C 03-D 04-E 05-F 06-G 07-H 08-I 09-J 10-K 11-L 12-M 13-N 14-O 15-P 16-Q 17-R */ \
/* 0 */ { ___ , ___ , KC0 , ___ , ___ , KF0 , ___ , ___ , ___ , KJ0 , KK0 , ___ , KM0 , KN0 , KO0 , ___ , KQ0 , KR0 }, \
/* 1 */ { ___ , ___ , ___ , ___ , ___ , ___ , KG1 , KH1 , KI1 , KJ1 , KK1 , KL1 , KM1 , ___ , KO1 , KP1 , ___ , ___ }, \
/* 2 */ { ___ , KB2 , ___ , KD2 , ___ , KF2 , KG2 , KH2 , KI2 , KJ2 , KK2 , KL2 , KM2 , ___ , KO2 , ___ , ___ , ___ }, \
/* 3 */ { KA3 , KB3 , ___ , ___ , ___ , KF3 , KG3 , KH3 , KI3 , KJ3 , KK3 , KL3 , KM3 , ___ , KO3 , ___ , ___ , ___ }, \
/* 4 */ { ___ , ___ , KC4 , ___ , KE4 , KF4 , KG4 , KH4 , KI4 , KJ4 , KK4 , KL4 , KM4 , ___ , KO4 , KP4 , KQ4 , KR4 }, \
/* 5 */ { ___ , ___ , KC5 , ___ , KE5 , KF5 , KG5 , KH5 , KI5 , KJ5 , KK5 , KL5 , KM5 , KN5 , KO5 , KP5 , ___ , ___ }, \
/* 6 */ { ___ , ___ , KC6 , ___ , ___ , KF6 , KG6 , KH6 , KI6 , KJ6 , KK6 , KL6 , ___ , KN6 , KO6 , ___ , KQ6 , ___ }, \
/* 7 */ { ___ , ___ , ___ , ___ , ___ , KF7 , KG7 , KH7 , KI7 , KJ7 , KK7 , KL7 , KM7 , KN7 , ___ , KP7 , ___ , ___ }, \
}
inline void ph_caps_led_on(void) { DDRC |= (1<<6); PORTC &= ~(1<<6); }
inline void ph_caps_led_off(void) { DDRC &= ~(1<<6); PORTC &= ~(1<<6); }
inline void ph_sclk_led_on(void) { DDRC |= (1<<5); PORTC &= ~(1<<5); }
inline void ph_sclk_led_off(void) { DDRC &= ~(1<<5); PORTC &= ~(1<<5); }
#endif

@ -0,0 +1,67 @@
# MCU name
MCU = atmega32u2
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
CUSTOM_MATRIX ?= yes
SRC = matrix.c

@ -63,7 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Underlight configuration
*/
#define RGB_DI_PIN E2
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 20 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -36,6 +36,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS
#define AUDIO_VOICES
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */

@ -1,4 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in

@ -1,4 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in

@ -109,15 +109,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | F11 | F12 | F13 | F14 | F15 | F16 | F17 | F18 | F19 | F20 | Vol- |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | F21 | F22 | F23 | F24 | | | Lock | | | | |
* | | F21 | F22 | F23 | F24 | | | Power| | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | Prev | Mute | Play | Next | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_FUNC] = {
{RESET, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, S(LALT(KC_VOLU))},
{XXXXXXX, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, S(LALT(KC_VOLD))},
{_______, KC_F21, KC_F22, KC_F23, KC_F24, XXXXXXX, XXXXXXX, S(LCTL(KC_POWER)), XXXXXXX, XXXXXXX, XXXXXXX, _______},
{RESET, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_VOLU},
{XXXXXXX, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_VOLD},
{_______, KC_F21, KC_F22, KC_F23, KC_F24, XXXXXXX, XXXXXXX, KC_POWER, XXXXXXX, XXXXXXX, XXXXXXX, _______},
{_______, _______, _______, _______, KC_MPRV, KC_MUTE, KC_MPLY, KC_MNXT, _______, _______, _______, _______}
}

@ -5,8 +5,8 @@
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
@ -16,10 +16,11 @@ AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
API_SYSEX_ENABLE = yes # Enable SYSEX API (+5390)
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,6 +1,9 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#define NO_DEBUG
#define NO_PRINT
#include "../../config.h"
#define LEADER_TIMEOUT 300

@ -62,6 +62,7 @@
- How about Alt-F1 thru Alt-F8?
- What's the keystroke to get from X to console these days?
- A layer for doing console switching would not be a bad idea
- I haven't got page-up/page-down, let's have that...
*/
enum layers {
@ -94,6 +95,7 @@ enum macro_id {
#define SHIFTQUOTE MT(MOD_RSFT, KC_QUOT)
#define ALTRIGHT MT(MOD_LALT, KC_RGHT)
#define MVERSION M(M_VERSION)
#define ALTSLASH LALT(KC_SLSH)
/* Note that Planck has dimensions 4 rows x 12 columns */
@ -109,14 +111,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_RAISE] = { /* RAISE */
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{_______, 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, QWERTY, KEYPAD, KEYPAD, RESET, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, QWERTY, KEYPAD, KEYPAD, ALTSLASH,_______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_VOLD, KC_VOLU, KC_PGUP}
},
[_LOWER] = { /* 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_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, QWERTY, KEYPAD, KEYPAD, RESET, _______},
{_______, KEYPAD, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, QWERTY, KEYPAD, KEYPAD, ALTSLASH, _______},
{_______, KEYPAD, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_VOLD, KC_VOLU, KC_PGUP}
},
[_KEYPAD] = { /* Key Pad */
{KC_ESC, USERNAME, MVERSION, KC_F10, KC_F11, KC_F12, KC_PGUP, KC_KP_ENTER, KC_7, KC_8, KC_9, KC_BSPC},

@ -1,25 +1,3 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -107,7 +107,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_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_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
@ -125,7 +125,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_RAISE] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{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_NUHS, KC_NUBS, _______, _______, _______},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},

@ -9,7 +9,7 @@
/* ws2812 RGB LED */
#define RGB_DI_PIN B1
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -1,4 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in

@ -1,4 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in

@ -0,0 +1,180 @@
// This is the personal keymap of Jeremy Cowgar (@jcowgar). It is written for the programmer.
// Configuration options
#define PREVENT_STUCK_MODIFIERS
#include "planck.h"
#include "action_layer.h"
#include "eeconfig.h"
// Each layer gets a name for readability, which is then used in the keymap matrix below.
enum my_layers {
ALPH = 0,
NUMS,
CURS,
SYMB,
FKEY
};
// Each macro gets a name for readability.
enum my_keycodes {
MY_ABVE = SAFE_RANGE,
MY_BELW,
MY_TERM,
MY_DEQL, // /=
MY_MEQL, // *=
MY_SEQL, // -=
MY_PEQL, // +=
MY_NEQL, // !=
MY_LTGT, // <>
MY_DPIP, // ||
MY_DAMP, // &&
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[ALPH] = {
{KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LBRC, KC_RBRC, KC_Y, KC_U, KC_I, KC_O, KC_P},
{KC_A, KC_S, KC_D, KC_F, KC_G, KC_LPRN, KC_RPRN, KC_H, KC_J, KC_K, KC_L, KC_SCLN},
{SFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_LCBR, KC_RCBR, KC_N, KC_M, KC_COMM, KC_DOT, SFT_T(KC_SLSH)},
{CTL_T(KC_TAB), OSL(FKEY), OSL(NUMS), OSL(SYMB), KC_SPC, ALT_T(KC_BSPC), GUI_T(KC_DELT), KC_ENT, OSL(SYMB), OSL(CURS), TG(CURS), CTL_T(KC_ESC)}
},
[NUMS] = {
{KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_COMM, KC_7, KC_8, KC_9, KC_SLSH},
{KC_LSFT, KC_LGUI, KC_LALT, KC_LCTL, KC_NO, KC_TRNS, KC_TRNS, KC_LPRN, KC_4, KC_5, KC_6, KC_ASTR},
{KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_RPRN, KC_1, KC_2, KC_3, KC_MINS},
{KC_NO, KC_NO, KC_TRNS, TG(NUMS), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_DOT, KC_EQL, KC_PLUS}
},
[CURS] = {
{KC_MPLY, KC_BSPC, KC_UP, KC_DELT, KC_PGUP, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO},
{KC_VOLU, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_TRNS, KC_TRNS, KC_NO, KC_LCTL, KC_LALT, KC_LGUI, KC_LSFT},
{KC_VOLD, KC_NO, MY_ABVE, MY_TERM, KC_NO, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_LSFT},
{KC_MUTE, KC_NO, MY_BELW, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_NO}
},
[SYMB] = {
{MY_DEQL, MY_MEQL, MY_SEQL, MY_PEQL, MY_NEQL, KC_NO, KC_NO, MY_LTGT, KC_LABK, KC_RABK, KC_COLN, KC_DLR},
{KC_SLSH, KC_ASTR, KC_MINS, KC_PLUS, KC_EQL, KC_NO, KC_PIPE, MY_DPIP, KC_GRV, KC_QUOT, KC_DQUO, KC_HASH},
{KC_BSLS, KC_CIRC, KC_PERC, KC_UNDS, KC_NO, KC_NO, KC_AMPR, MY_DAMP, KC_TILD, KC_AT, KC_EXLM, KC_QUES},
{KC_NO, KC_NO, KC_NO, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO}
},
[FKEY] = {
{KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F9, KC_F10, KC_F11, KC_F12},
{KC_LSFT, KC_LGUI, KC_LALT, KC_LCTL, KC_NO, KC_NO, KC_NO, KC_NO, KC_F5, KC_F6, KC_F7, KC_F8},
{KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F1, KC_F2, KC_F3, KC_F4},
{KC_NO, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}
}
};
void press_key(uint16_t key) {
register_code(key);
unregister_code(key);
}
void press_two_keys(uint16_t key1, uint16_t key2) {
register_code(key1);
register_code(key2);
unregister_code(key2);
unregister_code(key1);
}
void press_three_keys(uint16_t key1, uint16_t key2, uint16_t key3) {
register_code(key1);
register_code(key2);
register_code(key3);
unregister_code(key3);
unregister_code(key2);
unregister_code(key1);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case MY_BELW:
if (record->event.pressed) {
press_two_keys(KC_LGUI, KC_RGHT);
press_key(KC_ENT);
}
return false;
case MY_ABVE:
if (record->event.pressed) {
press_two_keys(KC_LGUI, KC_LEFT);
press_key(KC_ENT);
press_key(KC_UP);
}
return false;
case MY_TERM:
if (record->event.pressed) {
press_three_keys(KC_LGUI, KC_LSFT, KC_ENT);
}
return false;
case MY_DEQL: // /=
if (record->event.pressed) {
press_key(KC_SLSH);
press_key(KC_EQL);
}
return false;
case MY_MEQL: // *=
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_ASTR);
press_key(KC_EQL);
}
return false;
case MY_SEQL: // -=
if (record->event.pressed) {
press_key(KC_MINS);
press_key(KC_EQL);
}
return false;
case MY_PEQL: // +=
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_PLUS);
press_key(KC_EQL);
}
return false;
case MY_NEQL: // !=
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_EXLM);
press_key(KC_EQL);
}
return false;
case MY_LTGT: // <>
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_LABK);
press_two_keys(KC_LSFT, KC_RABK);
}
return false;
case MY_DPIP: // ||
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_PIPE);
press_two_keys(KC_LSFT, KC_PIPE);
}
return false;
case MY_DAMP: // &&
if (record->event.pressed) {
press_two_keys(KC_LSFT, KC_AMPR);
press_two_keys(KC_LSFT, KC_AMPR);
}
return false;
}
return true;
}

@ -0,0 +1,85 @@
Jeremy Cowgar's Planck Keymap
=============================
I am a programmer by trade and suffer from the beginning stages of RSI. As a programmer, I use letters, symbols and cursor navigation most often. To prevent strange finger gymnastics, I wrote a script to rank which non-letter characters occurred in my primary source projects most often and then placed these characters in the easiest to reach locations, within reason and for me. I made heavy use of momentary layer toggling.
Layers
------
The key mapping is made up of 5 layers: Letters, Symbols, Navigation, Numbers, and Function Keys.
The layout can be viewed visually at:
http://www.keyboard-layout-editor.com/#/gists/319474e5e2d199e583371ed1d2aec316
* Purple buttons are dual function keys.
* Green buttons are layer momentary toggle keys.
* Red buttons are layer persistent toggle keys.
The keys have multiple symbols:
* Upper left: standard layer, the letter layer
* Upper right: function layer
* Lower left: navigation layer
* Lower right: symbol layer
The symbols in the layout editor are not entirely clear.
The Z and ? keys double as shift keys. Hold for a shift, tap for a Z or ?
The bottom row from left to right:
* Tab when pressed, Control when held. It also is the volume mute key when in the "Navigation" layer
* Function layer momentary toggle
* Number layer momentary toggle
* Symbol layer momentary toggle. When in the "Number" layer, this key also makes the "Number" layer sticky for using the 10 key for quite a bit of entry
* Space
* Backspace when tapped, Option when held
* Delete when tapped, Command when held
* Return
* Symbol layer momentary toggle. When in the "Number" layer, key also is the zero key.
* Navigation layer momentary toggle
* Navigation layer toggle. This was included for when you are browsing a website, document or otherwise wish to stay in navigation mode. When in the "Number" layer, the key is the = symbol
* Escape when pressed, Control when held. When in the "Number" layer, the key is the + symbol
General Notes
-------------
The letter layer is separated by 2 center rows of keys. This spreads the hands out a little further which helps not twist the wrists as much. The 2 center rows are [], (), [], and Ctrl and Alt keys.
The symbol layer keys are accessed by the thumbs. They are the closest to the thumbs, instead of the number toggle, because in my code I found I used symbols much more often than numbers. There are two symbol layer keys because the symbols spread across the right and left half of the keyboard. Thus, some symbols are easier hit with the left hand modifier or right hand modifier.
The number layer key is only accessible by the left thumb because all of the number keys are on the right side of the keyboard. When in the number layer, you can press the key to the right to make that layer sticky when you are going to do a lot of number entry.
The function layer key is only accessible by the left thumb because all of the function keys are on the right side of the keyboard.
The navigation layer key is only accessible by the right thumb because all of the navigation keys are on the left side of the keyboard. You can press the key to the right of the navigation layer to make the navigation layer sticky when you are doing a lot of navigation, reading a web page for example.
When using the number or navigation layers, the same hand that accesses the momentary layer toggle key also has the 4 primary modifiers under their home row.
* Pointer finger is control
* Middle finger is option
* Ring finger is command
* Pinky finger is shift
This is so you can easily press Cmd+Shift+F4 or when navigating, select text or words of text by pressing Shift+Control, for example.
Some keys are duplicated. For example, () are available in easy to reach locations while in the Number layer because they are often used in math.
The symbol layer has additional helpers for programming including a single keys that enter /=, \*=, -=, +=, !=, <>, ||, and &&. It also includes three special Return keys on the left:
* Up CR which moves the cursor up, to the end of the line and then presses CR
* Down CR which moves the cursor to the end of the line and then presses CR
* Right ; which moves the cursor to the end of the line and presses ; for C styled languages, such as JavaScript which is a primary language I use
Word of Warning
---------------
I have been using the keymap for some time now and believe it to be a good keymap. There are a few things through the week that I wonder if it would have been better if this key were moved to that location.
This keymap may change for further optimization.
Please Give Feedback!
---------------------
I am very interested in your feedback. Send me a message here on GitHub, r/jcowgar or @jcowgar.

@ -1,4 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options

@ -0,0 +1,25 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
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 = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
UNICODEMAP_ENABLE = yes # Unicode map
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
API_SYSEX_ENABLE = no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,492 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "planck.h"
#include "action_layer.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#include "musical_notes.h"
#endif
#include "eeconfig.h"
#include "process_unicode.h"
#include "quantum.h"
extern keymap_config_t keymap_config;
enum layers {
_QWERTY,
_COLEMAK,
_WORKMAN,
_PUNC,
_NUM,
_FUNC,
_EMOJI,
_GUI,
};
enum planck_keycodes {
// layouts
QWERTY = SAFE_RANGE,
COLEMAK,
WORKMAN,
// layer switchers
PUNC,
NUM,
FUNC,
EMOJI,
GUI,
// os switchers
LINUX,
WIN,
OSX,
};
// Fillers to make layering clearer
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// unicode map
enum unicode_name {
GRIN, // grinning face 😊
TJOY, // tears of joy 😂
SMILE, // grining face with smiling eyes 😁
HEART, // heart ❤
EYERT, // smiling face with heart shaped eyes 😍
CRY, // crying face 😭
SMEYE, // smiling face with smiling eyes 😊
UNAMU, // unamused 😒
KISS, // kiss 😘
HART2, // two hearts 💕
WEARY, // weary 😩
OKHND, // ok hand sign 👌
PENSV, // pensive 😔
SMIRK, // smirk 😏
RECYC, // recycle ♻
WINK, // wink 😉
THMUP, // thumb up 👍
THMDN, // thumb down 👎
PRAY, // pray 🙏
PHEW, // relieved 😌
MUSIC, // musical notes
FLUSH, // flushed 😳
CELEB, // celebration 🙌
CRY2, // crying face 😢
COOL, // smile with sunglasses 😎
NOEVS, // see no evil
NOEVH, // hear no evil
NOEVK, // speak no evil
POO, // pile of poo
EYES, // eyes
VIC, // victory hand
BHART, // broken heart
SLEEP, // sleeping face
SMIL2, // smiling face with open mouth & sweat
HUNRD, // 100
CONFU, // confused
TONGU, // face with tongue & winking eye
DISAP, // disappointed
YUMMY, // face savoring delicious food
CLAP, // hand clapping
FEAR, // face screaming in fear
HORNS, // smiling face with horns
HALO, // smiling face with halo
BYE, // waving hand
SUN, // sun
MOON, // moon
SKULL, // skull
};
const uint32_t PROGMEM unicode_map[] = {
[GRIN] = 0x1F600,
[TJOY] = 0x1F602,
[SMILE] = 0x1F601,
[HEART] = 0x2764,
[EYERT] = 0x1f60d,
[CRY] = 0x1f62d,
[SMEYE] = 0x1F60A,
[UNAMU] = 0x1F612,
[KISS] = 0x1F618,
[HART2] = 0x1F495,
[WEARY] = 0x1F629,
[OKHND] = 0x1F44C,
[PENSV] = 0x1F614,
[SMIRK] = 0x1F60F,
[RECYC] = 0x267B,
[WINK] = 0x1F609,
[THMUP] = 0x1F44D,
[THMDN] = 0x1F44E,
[PRAY] = 0x1F64F,
[PHEW] = 0x1F60C,
[MUSIC] = 0x1F3B6,
[FLUSH] = 0x1F633,
[CELEB] = 0x1F64C,
[CRY2] = 0x1F622,
[COOL] = 0x1F60E,
[NOEVS] = 0x1F648,
[NOEVH] = 0x1F649,
[NOEVK] = 0x1F64A,
[POO] = 0x1F4A9,
[EYES] = 0x1F440,
[VIC] = 0x270C,
[BHART] = 0x1F494,
[SLEEP] = 0x1F634,
[SMIL2] = 0x1F605,
[HUNRD] = 0x1F4AF,
[CONFU] = 0x1F615,
[TONGU] = 0x1F61C,
[DISAP] = 0x1F61E,
[YUMMY] = 0x1F60B,
[CLAP] = 0x1F44F,
[FEAR] = 0x1F631,
[HORNS] = 0x1F608,
[HALO] = 0x1F607,
[BYE] = 0x1F44B,
[SUN] = 0x2600,
[MOON] = 0x1F314,
[SKULL] = 0x1F480,
};
// hybrid shift - =
// #undef KC_LSFT
// #define KC_LSFT MT(MOD_LSFT, KC_MINS)
// #undef KC_RSFT
// #define KC_RSFT MT(MOD_LSFT, KC_EQL)
// hybrid right-gui & scroll lock (mapped to Compose in OS)
#undef KC_RCTL
#define KC_RCTL MT(MOD_LCTL, KC_SLCK)
// keymaps
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 | ; |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_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},
{KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOT, KC_ENT },
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT},
{KC_LCTL, KC_LGUI, KC_LALT, PUNC, NUM, KC_SPC, KC_SPC, FUNC, EMOJI, KC_RALT, KC_RGUI, KC_RCTL}
},
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = {
{_______, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, _______},
{_______, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, _______},
{_______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
/* Workman
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | D | R | W | B | J | F | U | P | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | H | T | G | Y | N | E | O | I |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | M | C | V | K | K | , | . | / |Shift |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt | Punc | Num | Space | Func |Emoji |AltGr | GUI | Ctrl |
* `-----------------------------------------------------------------------------------'
*/
[_WORKMAN] = {
{_______, KC_Q, KC_D, KC_R, KC_W, KC_B, KC_J, KC_F, KC_U, KC_P, KC_QUOT, _______},
{_______, KC_A, KC_S, KC_H, KC_T, KC_G, KC_Y, KC_N, KC_E, KC_O, KC_I, _______},
{_______, KC_Z, KC_X, KC_M, KC_C, KC_V, KC_K, KC_L, KC_COMM, KC_DOT, KC_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
/* Punc
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | ` |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | \ | - | = | < | > | ( | ) | ' | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | _ | + | { | } | [ | ] | " | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_PUNC] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_GRV },
{XXXXXXX, XXXXXXX, KC_BSLS, KC_MINS, KC_EQL, KC_LABK, KC_RABK, KC_LPRN, KC_RPRN, KC_QUOT, XXXXXXX, XXXXXXX},
{XXXXXXX, XXXXXXX, KC_PIPE, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_DQUO, XXXXXXX, XXXXXXX},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
/* Num
* ,-----------------------------------------------------------------------------------.
* | ^ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | @ | A | B | C | ( | ) | 4 | 5 | 6 | : |Enter |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | & | # | D | E | F | [ | ] | 1 | 2 | 3 | / | * |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | x | | | 0 | , | . | + | - |
* `-----------------------------------------------------------------------------------'
*/
[_NUM] = {
{KC_CIRC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{ KC_ESC, KC_AT, S(KC_A), S(KC_B), S(KC_C), KC_LPRN, KC_RPRN, KC_4, KC_5, KC_6, KC_COLN, KC_ENT},
{KC_AMPR, KC_HASH, S(KC_D), S(KC_E), S(KC_F), KC_LBRC, KC_RBRC, KC_1, KC_2, KC_3, KC_SLSH, KC_ASTR},
{_______, _______, _______, KC_X, _______, KC_SPC, KC_SPC, KC_0, KC_COMM, KC_DOT, KC_PLUS, KC_MINS}
},
/* Func
* ,-----------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | | | PgUp | Up | PgDn | PgUp | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | F5 | F6 | F7 | F8 |PrtSc | | Left | Down | Right| PgDn | Ins |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F9 | F10 | F11 | F12 | | | | Home | End | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_FUNC] = {
{XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, XXXXXXX, KC_PGUP, KC_UP, KC_PGDN, KC_PGUP, KC_DEL},
{XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8,KC_PSCREEN,XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_INS},
{_______, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_END, XXXXXXX, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
/* Emoji
* ,-----------------------------------------------------------------------------------.
* | | | | | | | | | | | | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_EMOJI] = {
{X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW)},
{X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS)},
{X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH)},
{ X(POO), X(EYES),X(HUNRD), _______,X(SKULL),X(HORNS), X(HALO), X(FEAR), _______,X(YUMMY),X(DISAP),X(NOEVK)}
},
/* GUI
* ,-----------------------------------------------------------------------------------.
* | | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* |Linux | | Vol- | Mute | Vol+ | | | D- | | D+ | |Qwerty|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Win | | Prev | Play | Next | | | | | | |Colmak|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | OSX | | | | | BL- | BL+ | | | | |Workmn|
* `-----------------------------------------------------------------------------------'
*/
[_GUI] = {
{_______, LGUI(KC_1),LGUI(KC_2),LGUI(KC_3),LGUI(KC_4),LGUI(KC_5),LGUI(KC_6),LGUI(KC_7),LGUI(KC_8),LGUI(KC_9),LGUI(KC_0), _______},
{ LINUX, _______, KC_VOLD, KC_MUTE, KC_VOLU,_______,_______,KC_WWW_BACK,_______,KC_WWW_FORWARD,_______, QWERTY},
{ WIN, _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, _______, _______, _______, _______, _______, COLEMAK},
{ OSX, _______, _______, _______, _______, BL_DEC, BL_INC, _______, _______, _______, _______, WORKMAN}
},
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_workman[][2] = SONG(DVORAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float tone_linux[][2] = SONG(CAPS_LOCK_ON_SOUND);
float tone_windows[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_osx[][2] = SONG(NUM_LOCK_ON_SOUND);
float tone_click[][2] = SONG(MUSICAL_NOTE(_F3, 2));
float tone_release[][2] = SONG(MUSICAL_NOTE(_A3, 2));
#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) {
// faux clicky
// if (record->event.pressed) PLAY_NOTE_ARRAY(tone_click, false, 0);
#ifdef AUDIO_ENABLE
if (record->event.pressed) {
PLAY_NOTE_ARRAY(tone_click, false, 0);
} else {
PLAY_NOTE_ARRAY(tone_release, false, 0);
}
#endif
switch (keycode) {
// QWERTZ style comma and dot: semicolon and colon when shifted
case KC_COMM:
if (record->event.pressed) {
bool lshifted = keyboard_report->mods & MOD_BIT(KC_LSFT);
bool rshifted = keyboard_report->mods & MOD_BIT(KC_RSFT);
if (lshifted || rshifted) {
if (lshifted) unregister_code(KC_LSFT);
if (rshifted) unregister_code(KC_RSFT);
register_code(KC_SCLN);
unregister_code(KC_SCLN);
if (lshifted) register_code(KC_LSFT);
if (rshifted) register_code(KC_RSFT);
} else {
register_code(KC_COMM);
unregister_code(KC_COMM);
}
}
return false;
break;
case KC_DOT:
if (record->event.pressed) {
if ((keyboard_report->mods & MOD_BIT(KC_LSFT)) || (keyboard_report->mods & MOD_BIT(KC_RSFT))) {
register_code(KC_SCLN);
unregister_code(KC_SCLN);
} else {
register_code(KC_DOT);
unregister_code(KC_DOT);
}
}
return false;
break;
// layout switcher
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case WORKMAN:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_workman, false, 0);
#endif
persistant_default_layer_set(1UL<<_WORKMAN);
}
return false;
break;
// layer switchers
case PUNC:
if (record->event.pressed) {
layer_on(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _GUI);
} else {
layer_off(_PUNC);
update_tri_layer(_PUNC, _EMOJI, _GUI);
}
return false;
break;
case EMOJI:
if (record->event.pressed) {
layer_on(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _GUI);
} else {
layer_off(_EMOJI);
update_tri_layer(_PUNC, _EMOJI, _GUI);
}
return false;
break;
case NUM:
if (record->event.pressed) {
layer_on(_NUM);
} else {
layer_off(_NUM);
}
return false;
break;
case FUNC:
if (record->event.pressed) {
layer_on(_FUNC);
} else {
layer_off(_FUNC);
}
return false;
break;
// OS switchers
case LINUX:
set_unicode_input_mode(UC_LNX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_linux, false, 0);
#endif
return false;
break;
case WIN:
set_unicode_input_mode(UC_WINC);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_windows, false, 0);
#endif
return false;
break;
case OSX:
set_unicode_input_mode(UC_OSX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_osx, false, 0);
#endif
return false;
break;
}
return true;
}
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
set_unicode_input_mode(UC_LNX);
}
#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();
}
#endif

@ -0,0 +1,11 @@
# Priyadi's Planck Layout
Features:
- Supports QWERTY, Colemak and Workman layouts.
- Cursor and nav cluster on home row.
- Hybrid number row and numpad, located on home row.
- Number layer supports hexadecimal input.
- Left and right side modifiers.
- Emoji layer. An entire layer filled with common emojis.
- Faux-clickey (poor man's replacement for Cherry blue switches)

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
@ -21,4 +24,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -16,10 +19,11 @@ AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
API_SYSEX_ENABLE = no # Disable extra stuff for ergodoxen
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
@ -22,4 +25,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -0,0 +1,29 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
PRINTING_ENABLE = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,23 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
# define SERIAL_UART_BAUD 19200
# define SERIAL_UART_DATA UDR1
# define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
# define SERIAL_UART_RXD_VECT USART1_RX_vect
# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
# define SERIAL_UART_INIT() do { \
/* baud rate */ \
UBRR1L = SERIAL_UART_UBRR; \
/* baud rate */ \
UBRR1H = SERIAL_UART_UBRR >> 8; \
/* enable TX */ \
UCSR1B = _BV(TXEN1); \
/* 8-bit data */ \
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
sei(); \
} while(0)
#endif

@ -0,0 +1,314 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "planck.h"
#include "action_layer.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
#include "eeconfig.h"
extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _PLOVER 5
#define _ADJUST 16
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV
};
// Fillers to make layering more clear
#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},
{KC_ESC, 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 },
{BACKLIT, 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},
{KC_ESC, 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},
{KC_ESC, 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_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* 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_BSPC},
{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_NUHS, 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| | Print|no prnt | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{_______, RESET, _______, PRINT_ON, PRINT_OFF, _______, _______, _______, _______, _______, _______, 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);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
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);
}
return false;
break;
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);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
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);
}
return false;
break;
case EXT_PLV:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_plover_gb, false, 0);
#endif
layer_off(_PLOVER);
}
return false;
break;
}
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

@ -1,3 +1,6 @@
# Please remove if no longer applicable
$(warning THIS FILE MAY BE TOO LARGE FOR YOUR KEYBOARD)
$(warning Please disable some options in the Makefile to resolve)
# Build Options

@ -5,7 +5,7 @@
/* ws2812 RGB LED */
#define RGB_DI_PIN D1
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 28 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -1,66 +0,0 @@
-------- begin --------
avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiling: ../../keyboards/planck/planck.c [OK]
Compiling: ../../keyboards/planck/keymaps/experimental/keymap.c [WARNINGS]
|
| ../../keyboards/planck/keymaps/experimental/keymap.c: In function 'action_get_macro':
| ../../keyboards/planck/keymaps/experimental/keymap.c:227:17: warning: implicit declaration of function 'breathing_speed_set' [-Wimplicit-function-declaration]
| breathing_speed_set(2);
| ^
| ../../keyboards/planck/keymaps/experimental/keymap.c:228:17: warning: implicit declaration of function 'breathing_pulse' [-Wimplicit-function-declaration]
| breathing_pulse();
| ^
|
Compiling: ../../quantum/quantum.c [OK]
Compiling: ../../quantum/keymap.c [OK]
Compiling: ../../quantum/keycode_config.c [OK]
Compiling: ../../quantum/matrix.c [OK]
Compiling: ../../quantum/audio/audio.c [OK]
Compiling: ../../quantum/audio/voices.c [OK]
Compiling: ../../quantum/audio/luts.c [OK]
Compiling: ../../tmk_core/protocol/lufa/lufa.c [OK]
Compiling: ../../tmk_core/protocol/lufa/descriptor.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Class/Common/HIDParser.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/ConfigDescriptors.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/DeviceStandardReq.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/Events.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/HostStandardReq.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/USBTask.c [OK]
Compiling: ../../tmk_core/common/host.c [OK]
Compiling: ../../tmk_core/common/keyboard.c [OK]
Compiling: ../../tmk_core/common/action.c [OK]
Compiling: ../../tmk_core/common/action_tapping.c [OK]
Compiling: ../../tmk_core/common/action_macro.c [OK]
Compiling: ../../tmk_core/common/action_layer.c [OK]
Compiling: ../../tmk_core/common/action_util.c [OK]
Compiling: ../../tmk_core/common/print.c [OK]
Compiling: ../../tmk_core/common/debug.c [OK]
Compiling: ../../tmk_core/common/util.c [OK]
Compiling: ../../tmk_core/common/avr/suspend.c [OK]
Assembling: ../../tmk_core/common/avr/xprintf.S [OK]
Compiling: ../../tmk_core/common/avr/timer.c [OK]
Compiling: ../../tmk_core/common/avr/bootloader.c [OK]
Compiling: ../../tmk_core/common/magic.c [OK]
Compiling: ../../tmk_core/common/avr/eeconfig.c [OK]
Compiling: ../../tmk_core/common/mousekey.c [OK]
Compiling: ../../tmk_core/common/command.c [OK]
Compiling: ../../tmk_core/common/backlight.c [OK]
Linking: .build/planck_experimental.elf [ERRORS]
|
| .build/obj_planck_experimental/keyboards/planck/keymaps/experimental/keymap.o: In function `action_get_macro':
| C:\Users\Fred Wales\Documents\Programming\qmk_firmware\keyboards\planck/../../keyboards/planck/keymaps/experimental/keymap.c:240: undefined reference to `breathing_speed_set'
| C:\Users\Fred Wales\Documents\Programming\qmk_firmware\keyboards\planck/../../keyboards/planck/keymaps/experimental/keymap.c:241: undefined reference to `breathing_pulse'
| collect2.exe: error: ld returned 1 exit status
|

@ -16,4 +16,4 @@ void matrix_init_kb(void) {
PORTE |= (1<<6);
matrix_init_user();
}
}

@ -51,17 +51,18 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= yes # MIDI controls
AUDIO_ENABLE ?= yes # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight.
API_SYSEX_ENABLE = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -37,6 +37,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS
#define AUDIO_VOICES
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */
@ -63,7 +65,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* ws2812 RGB LED */
#define RGB_DI_PIN D1
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 28 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -1,25 +1,3 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = yes # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -4,5 +4,6 @@
#include "../../config.h"
#define FORCE_NKRO 1
#define PREVENT_STUCK_MODIFIERS
#endif

@ -13,13 +13,18 @@
#define _QWERTY 0
#define _LOWER 3
#define _RAISE 4
#define _MQWERTY 5
#define _MLOWER 8
#define _MRAISE 9
#define _ADJUST 16
enum preonic_keycodes {
QWERTY = SAFE_RANGE,
LOWER,
RAISE,
BACKLIT
MQWERTY,
MLOWER,
MRAISE
};
// Fillers to make layering more clear
@ -38,7 +43,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| < | Z | X | C | V | B | N | M | . | , | - |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | GUI | Alt |AltGr |Lower | Space| Enter|Raise | Left | Down | Up |Right |
* | Ctrl | Alt | GUI |AltGr |Lower | Space| Enter|Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = {
@ -46,7 +51,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
{KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, NO_AM },
{KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, NO_AE, NO_OSLH},
{KC_LSFT, NO_LESS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_DOT, KC_COMM, NO_MINS},
{KC_LCTL, KC_LGUI, KC_LALT, NO_ALGR, LOWER, KC_SPC, KC_ENT, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
{KC_LCTL, KC_LALT, KC_LGUI, NO_ALGR, LOWER, KC_SPC, KC_ENT, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
@ -59,7 +64,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | |VolDwn| | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | |Bspc | | | | | |
* | | | | | | |Bspc | | |PgDn |PgUp | |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
@ -67,7 +72,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
{_______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, _______, _______, NO_TILD},
{_______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, LSFT(KC_BSLS)},
{_______, NO_PIPE, _______, _______, _______, _______, _______, _______, KC_VOLD, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, KC_BSPC, _______, _______, _______, _______, _______}
{_______, _______, _______, _______, _______, _______, KC_BSPC, _______, _______, KC_PGDN, KC_PGUP, _______}
},
/* Raise
@ -76,11 +81,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | |Mouse^| | | | |ScrlUp| | | ^ |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | |Mouse<|MouseV|Mouse>| | |MLC |MMC |MRC | ' | " |
* | | |Mouse<|MouseV|Mouse>| | |MLC |MMC |MRC | ' | ¨ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | > | | | | | | |ScrlDown| : | ; | _ |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | |Bspc | | | | | | |
* | | | | | |Bspc | | | | PgDn | PgUp | |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
@ -88,7 +93,70 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
{_______, _______, _______, KC_MS_U, _______, _______, _______, _______, KC_WH_U, _______, _______, NO_CIRC},
{_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, KC_BTN1, KC_BTN3, KC_BTN2, NO_APOS, NO_QUOT},
{_______, NO_GRTR, _______, _______, _______, _______, _______, _______, KC_WH_D, NO_COLN, NO_SCLN, NO_UNDS},
{_______, _______, _______, _______, _______, KC_BSPC, _______, _______, _______, _______, _______, _______}
{_______, _______, _______, _______, _______, KC_BSPC, _______, _______, _______, KC_PGDN, KC_PGUP, _______}
},
/* Mac Qwerty
* ,-----------------------------------------------------------------------------------.
* | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | + | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Esc | Q | W | E | R | T | Y | U | I | O | P | Å |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Tab | A | S | D | F | G | H | J | K | L | Ö | Ä |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| < | Z | X | C | V | B | N | M | . | , | - |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Ctrl | Alt | GUI |AltGr |Lower | Space| Enter|Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_MQWERTY] = {
{KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, NO_PLUS, KC_BSPC},
{KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, NO_AM },
{KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, NO_AE, NO_OSLH},
{KC_LSFT, NO_LESS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_DOT, KC_COMM, NO_MINS},
{KC_LCTL, KC_LALT, KC_LGUI, NO_ALGR, MLOWER, KC_SPC, KC_ENT, MRAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Mac Lower
* ,-----------------------------------------------------------------------------------.
* | | @ | £ | $ | | | { | [ | ] | } | \ | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | |VolUp | | | ~ |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | |LastS |PauseP|NextS | | * |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | |VolDwn| | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | |Bspc | | |PgDn |PgUp | |
* `-----------------------------------------------------------------------------------'
*/
[_MLOWER] = {
{_______, NO_AT, NO_PND, NO_DLR, _______, _______, LSFT(LALT(KC_8)), NO_LBRC, NO_RBRC, LSFT(LALT(KC_9)), LSFT(LALT(KC_7)), KC_DEL},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, _______, _______, NO_TILD},
{_______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, LSFT(KC_BSLS)},
{_______, NO_LBRC, _______, _______, _______, _______, _______, _______, KC_VOLD, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, KC_BSPC, _______, _______, KC_PGDN, KC_PGUP, _______}
},
/* Mac Raise
* ,-----------------------------------------------------------------------------------.
* | ! | " | # | ¤ | % | & | / | ( | ) | = | ? | Ins |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | |Mouse^| | | | |ScrlUp| | | ^ |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | |Mouse<|MouseV|Mouse>| | |MLC |MMC |MRC | ' | ¨ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | > | | | | | | |ScrlDown| : | ; | _ |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | |Bspc | | | | PgDn | PgUp | |
* `-----------------------------------------------------------------------------------'
*/
[_MRAISE] = {
{LSFT(KC_1),NO_QUO2,LSFT(KC_3), NO_BULT,LSFT(KC_5), NO_AMPR, NO_SLSH, NO_LPRN, NO_RPRN, NO_EQL, NO_QUES, KC_INS},
{_______, _______, _______, KC_MS_U, _______, _______, _______, _______, KC_WH_U, _______, _______, NO_CIRC},
{_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, KC_BTN1, KC_BTN3, KC_BTN2, NO_APOS, NO_QUOT},
{_______, NO_GRTR, _______, _______, _______, _______, _______, _______, KC_WH_D, NO_COLN, NO_SCLN, NO_UNDS},
{_______, _______, _______, _______, _______, KC_BSPC, _______, _______, _______, KC_PGDN, KC_PGUP, _______}
},
/* Adjust (Lower + Raise)
@ -97,18 +165,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | Reset| | | | | | | | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | | | | | | | | | |Rsft |
* | | | | | | | | | | | |Rshift|
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |MusOn |MusOff| | | | | | | | | Reset|
* | |MusOn |MusOff| | | | |NrmMode|MacMode| | | Reset|
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* | | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12},
{_______, _______, _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT},
{_______, MU_ON, MU_OFF, _______, _______, _______, _______, _______, _______, _______, _______, RESET },
{_______, MU_ON, MU_OFF, _______, _______, _______, _______, TO(0), TO(5), _______, _______, RESET },
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}
@ -117,14 +185,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef AUDIO_ENABLE
float tone_startup[][2] = {
{NOTE_B5, 20},
{NOTE_B6, 8},
{NOTE_DS6, 20},
{NOTE_B6, 8}
{NOTE_D5, 8},
{NOTE_E6, 8},
{NOTE_D6, 8},
{NOTE_E5, 8}
};
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
@ -139,9 +205,6 @@ 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);
}
return false;
@ -166,14 +229,29 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
return false;
break;
case BACKLIT:
case MQWERTY:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<_MQWERTY);
}
return false;
break;
case MLOWER:
if (record->event.pressed) {
layer_on(_MLOWER);
update_tri_layer(_MLOWER, _MRAISE, _ADJUST);
} else {
layer_off(_MLOWER);
update_tri_layer(_MLOWER, _MRAISE, _ADJUST);
}
return false;
break;
case MRAISE:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
layer_on(_MRAISE);
update_tri_layer(_MLOWER, _MRAISE, _ADJUST);
} else {
unregister_code(KC_RSFT);
layer_off(_MRAISE);
update_tri_layer(_MLOWER, _MRAISE, _ADJUST);
}
return false;
break;

@ -1,3 +1,15 @@
# Jacwib's preonic keymap.
Designed for use with a swedish language.
Version 1.1:
Added PgUp and PgDn keys.
Also added "Mac mode". Unsure if it even works. Might however be able to test soon.
Version 1.2:
Changed around alt and super keys.
Made "Mac mode" function, and tested it! (It works)

@ -63,7 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* ws2812 RGB LED */
#define RGB_DI_PIN D1
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 28 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -53,17 +53,18 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= yes # MIDI controls
AUDIO_ENABLE ?= yes # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight.
API_SYSEX_ENABLE ?= yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -67,7 +67,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define RGB_DI_PIN E2
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -0,0 +1,152 @@
#include "satan.h"
#include "action_layer.h"
#include "rgblight.h"
#define _DEFAULT 0
#define _FN 1
#define _SFX 2
enum planck_keycodes {
DEFAULT = SAFE_RANGE
};
// Fillers to make layering more clear
#define ______ KC_TRNS
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty gui/alt/space/alt/gui
* ,-----------------------------------------------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | \ | ` |
* |-----------------------------------------------------------------------------------------+
* | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | Bksp |
* |-----------------------------------------------------------------------------------------+
* | Ctrl | A | S | D | F | G | H | J | K | L | ; | ' | Enter |
* |-----------------------------------------------------------------------------------------+
* | Shift | Z | X | C | V | B | N | M | , | . | / | RShift | FN |
* |-----------------------------------------------------------------------------------------+
* |LGUI | LAlt | Space | RAlt |RGUI |
* `-----------------------------------------------------------------'
*/
[_DEFAULT] = KEYMAP_HHKB( /* Basic QWERTY */
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC,KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN), \
______, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI, ______, ______ \
),
/* FN Layer
* ,-----------------------------------------------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | Ins | Del |
* |-----------------------------------------------------------------------------------------+
* | CAPS | BL- | BL+ | BL | | | | | Psc | Slck| Paus| Up | | |
* |-----------------------------------------------------------------------------------------+
* | | Vol-| Vol+| Mute| | | * | / | Home| PgUp| Left|Right| |
* |-----------------------------------------------------------------------------------------+
* | | Prev| Play| Next| | | + | - | End |PgDn| Down| | |
* |-----------------------------------------------------------------------------------------+
* | | | | Stop | |
* `-----------------------------------------------------------------'
*/
[_FN] = KEYMAP_HHKB( /* Layer 1 */
TG(_SFX), 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_INS, KC_DEL, \
KC_CAPS, ______, ______, ______, ______, ______, ______, ______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, ______, ______, \
______, KC_VOLD,KC_VOLU,KC_MUTE,______, ______, KC_PAST,KC_PSLS,KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, ______, \
______, KC_MPRV,KC_MPLY,KC_MNXT,______, ______, KC_PPLS,KC_PMNS,KC_END, KC_PGDN, KC_DOWN, ______, ______, \
______, ______, ______, ______, KC_MSTP, ______, ______, ______ \
),
/* SFX Layer
* ,-----------------------------------------------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | BL- | BL+ | BL | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | RGBT| RGBM| | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | Hue+| Hue-| Sat+| Sat-| Val+| Val-| | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | | | |
* `-----------------------------------------------------------------'
*/
[_SFX] = KEYMAP_HHKB(
______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, BL_DEC, BL_INC, BL_TOGG,______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, F(0), F(1), ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, \
______, F(2), F(3), F(4), F(5), F(6), F(7), ______, ______, ______, ______, ______, ______, \
______, ______, ______, ______, ______, ______, ______, ______ \
)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
return MACRO_NONE;
};
enum function_id {
RGBLED_TOGGLE,
RGBLED_STEP_MODE,
RGBLED_INCREASE_HUE,
RGBLED_DECREASE_HUE,
RGBLED_INCREASE_SAT,
RGBLED_DECREASE_SAT,
RGBLED_INCREASE_VAL,
RGBLED_DECREASE_VAL
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(RGBLED_TOGGLE),
[1] = ACTION_FUNCTION(RGBLED_STEP_MODE),
[2] = ACTION_FUNCTION(RGBLED_INCREASE_HUE),
[3] = ACTION_FUNCTION(RGBLED_DECREASE_HUE),
[4] = ACTION_FUNCTION(RGBLED_INCREASE_SAT),
[5] = ACTION_FUNCTION(RGBLED_DECREASE_SAT),
[6] = ACTION_FUNCTION(RGBLED_INCREASE_VAL),
[7] = ACTION_FUNCTION(RGBLED_DECREASE_VAL)
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
switch (id) {
case RGBLED_TOGGLE:
if (record->event.pressed) {
rgblight_toggle();
}
break;
case RGBLED_INCREASE_HUE:
if (record->event.pressed) {
rgblight_increase_hue();
}
break;
case RGBLED_DECREASE_HUE:
if (record->event.pressed) {
rgblight_decrease_hue();
}
break;
case RGBLED_INCREASE_SAT:
if (record->event.pressed) {
rgblight_increase_sat();
}
break;
case RGBLED_DECREASE_SAT:
if (record->event.pressed) {
rgblight_decrease_sat();
}
break;
case RGBLED_INCREASE_VAL:
if (record->event.pressed) {
rgblight_increase_val();
}
break;
case RGBLED_DECREASE_VAL:
if (record->event.pressed) {
rgblight_decrease_val();
}
break;
case RGBLED_STEP_MODE:
if (record->event.pressed) {
rgblight_step();
}
break;
}
}

@ -0,0 +1,9 @@
# Dbroqua HHKB like Layout
Like the HHKB but with a Satan GH60 PCB :D.
# Programming Instructions:
Enter into programming mode and run the following command.
```
$ sudo KEYMAP=dbroqua_hhkb make dfu
```

@ -32,21 +32,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FL), \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_MENU, KC_RCTL),
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, KC_RALT, KC_MENU, KC_RCTL),
[_FL] = KEYMAP_HHKB(
#ifdef RGBLIGHT_ENABLE
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, RESET, \
KC_CAPS, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, _______, KC_DEL, \
_______, KC_VOLD, KC_VOLU, KC_MUTE, _______, _______, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \
_______, _______, _______, _______, _______, _______, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______),
#else
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, RESET, \
KC_CAPS, _______, RGB_TOG,RGB_MOD,RGB_HUI, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, _______, KC_DEL, \
_______, KC_VOLD, RGB_HUD,RGB_SAI,RGB_SAD, _______, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \
_______, RGB_VAI,RGB_VAD,_______, _______, _______, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______),
#else
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, RESET, \
KC_CAPS, _______, _______, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, _______, KC_DEL, \
_______, KC_VOLD, KC_VOLU, KC_MUTE, _______, _______, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \
_______, _______, _______, _______, _______, _______, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______),
#endif
};

@ -0,0 +1,280 @@
#include "subatomic.h"
#include "action_layer.h"
#include "eeconfig.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum subatomic_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
BACKLIT
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-------------------------------------------------------------------------------------------------.
* | Ins | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | Del |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | - | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | = | Esc | A | S | D | F | G | H | J | K | L | ; | " |Enter |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | Pg Up| Shift| Z | X | C | V | B | N | M | , | . | / | Home | End |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | Pg Dn| Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up | Right| \ |
* `-------------------------------------------------------------------------------------------------'
*/
[_QWERTY] = {
{KC_TRNS, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TRNS},
{KC_TRNS, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL, KC_TRNS},
{KC_TRNS, KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_TRNS},
{KC_TRNS, 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_TRNS},
{KC_TRNS, BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS}
},
/* Colemak
* ,-------------------------------------------------------------------------------------------------.
* | Ins | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | Del |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | - | Tab | Q | W | F | P | G | J | L | U | Y | ; | [ | ] |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | = | Esc | A | R | S | T | D | H | N | E | I | O | " |Enter |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | Pg Up| Shift| Z | X | C | V | B | K | M | , | . | / | Home | End |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | Pg Dn| Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up | Right| \ |
* `-------------------------------------------------------------------------------------------------'
*/
[_COLEMAK] = {
{KC_TRNS, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TRNS},
{KC_TRNS, KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_DEL, KC_TRNS},
{KC_TRNS, KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, KC_TRNS},
{KC_TRNS, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, KC_TRNS},
{KC_TRNS, BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS}
},
/* Dvorak
* ,-------------------------------------------------------------------------------------------------.
* | Ins | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | Del |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | [ | Tab | " | , | . | P | Y | F | G | C | R | L | / | = |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | ] | Esc | A | O | E | U | I | D | H | T | N | S | - |Enter |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | Pg Up| Shift| ; | Q | J | K | X | B | M | W | V | Z | Home | End |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | Pg Dn| Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up | Right| \ |
* `-------------------------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_TRNS, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TRNS},
{KC_TRNS, KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_DEL, KC_TRNS},
{KC_TRNS, KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, KC_TRNS},
{KC_TRNS, KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT, KC_TRNS},
{KC_TRNS, BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_TRNS}
},
/* Lower
* ,-------------------------------------------------------------------------------------------------.
* | | ~ | F1 | F3 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | _ | Tab | ! | @ | # | $ | % | ^ | & | * | ( | ) | { | } |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | + | Esc | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | | Shift| F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | Next | Vol- | Vol+ | Play | |
* `-------------------------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_TRNS, 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_TRNS},
{KC_TRNS, 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_TRNS},
{KC_TRNS, 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_TRNS},
{KC_TRNS, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______,KC_TRNS},
{KC_TRNS, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, KC_TRNS}
},
/* Raise
* ,-------------------------------------------------------------------------------------------------.
* | | ~ | F1 | F3 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | _ | Tab | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | { | } |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | + | Esc | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | | |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | | Shift| F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | Next | Vol- | Vol+ | | Play |
* `-------------------------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_TRNS, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TRNS},
{KC_TRNS, 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_TRNS},
{KC_TRNS, 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_TRNS},
{KC_TRNS, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, KC_TRNS},
{KC_TRNS, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, KC_TRNS}
},
/* Adjust (Lower + Raise)
* ,-------------------------------------------------------------------------------------------------.
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | | | Reset| | | | | | | | | | | |
* |------+------+------+------+------+------+-------------+------+------+------+------+------+------|
* | | | | |Aud on|AudOff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | | |
* |------+------+------+------+------+------+------|------+------+------+------+------+------+------|
* | | |Voice-|Voice+|Mus on|MusOff|MidiOn|MidOff| | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | | |
* `-------------------------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{KC_TRNS, 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_TRNS},
{KC_TRNS, _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, KC_TRNS},
{KC_TRNS, _______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, KC_TRNS},
{KC_TRNS, _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______, KC_TRNS},
{KC_TRNS, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_TRNS}
}
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = {
{NOTE_B5, 20},
{NOTE_B6, 8},
{NOTE_DS6, 20},
{NOTE_B6, 8}
};
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_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);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
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);
}
return false;
break;
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);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
}
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

@ -67,7 +67,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*#define RGB_DI_PIN E2
#define RGBLIGHT_TIMER
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 2 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17

@ -31,7 +31,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
#define DEBOUNCING_DELAY 0
#define MATRIX_MASKED
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST

@ -2,7 +2,7 @@
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # Console for debug(+400)
@ -18,4 +18,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -121,6 +121,7 @@ enum keyboard_macros {
#define M_CP_CT M(MACRO_COPY_CUT)
#define M_COPY KC_FN1
#define SC_UNDO LCTL(KC_Z)
#define SC_REDO LCTL(KC_Y)
@ -141,35 +142,46 @@ enum keyboard_macros {
#define ________________ _______, _______
#define XXXXXXXXXXXXXXXX XXXXXXX, XXXXXXX
const matrix_row_t matrix_mask[MATRIX_ROWS] =
{
// 1098765432109876543210987654321
0b0000000001111111101111011111111,
0b0000000001111111111111111111111,
0b0000000001111111111111111111111,
0b0000000001111111111111111111111,
0b0000000001010111111111111111111,
0b0000000001111101111111101011111,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] =
{
/* LAYER = LAYER_QWERTY
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| FN | PRINT | SCR LK | PAUSE | | F1 | F2 | F3 | F4 | XXXXXX | F5 | F6 | F7 | F8 | XXXXXX | F9 | F10 | F11 | F12 | | VOL DN | MUTE | VOL UP | BACKLT |
| VOL DN | MUTE | VOL UP | BACKLT | | F1 | F2 | F3 | F4 | XXXXXX | F5 | F6 | F7 | F8 | XXXXXX | F9 | F10 | F11 | F12 | | PRINT | SCR LK | PAUSE | FN |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| M1 | INS | HOME | PG UP | | ESC | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | = | BACKSP | | NUM LK | KP / | KP * | KP - |
| NUM LK | KP / | KP * | KP - | | ESC | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | = | BACKSP | | INS | HOME | PG UP | M1 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| M2 | DEL | END | PG DN | | TAB | TAB | Q | W | E | R | T | Y | U | I | O | P | - | \ | | KP 7 | KP 8 | KP 9 | KP + |
| KP 7 | KP 8 | KP 9 | KP + | | TAB | TAB | Q | W | E | R | T | Y | U | I | O | P | - | \ | | DEL | END | PG DN | M2 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| M3 | UL | UP | UR | | CAP LK | BACKSP | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | o | KP 4 | KP 5 | KP 6 | KP + |
| KP 4 | KP 5 | KP 6 | KP + | | CAP LK | BACKSP | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | o | CP/CT | UNDO | PASTE | M3 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| M4 | LEFT | CP/CT | RIGHT | | LSHIFT | LSHIFT | Z | X | C | V | B | N | M | , | . | / | RSHIFT | RSHIFT | | KP 1 | KP 2 | KP 3 | KP Ent |
| KP 1 | KP 2 | KP 3 | KP Ent | | LSHIFT | LSHIFT | Z | X | C | V | B | N | M | , | . | / | RSHIFT | RSHIFT | | XXXXXX | UP | XXXXXX | M4 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| M5 | DL | DOWN | DR | | LCTRL | XXXXXX | XXXXXX | LWIN | LALT | LOWER | SPACE . SPACE | UPPER | OSHIFT | RALT | APP | XXXXXX | RCTRL | | KP 0 | KP , | KP . | KP Ent |
| KP 0 | KP , | KP . | KP Ent | | LCTRL | XXXXXX | LWIN | XXXXXX | LALT | UPPER | SPACE . SPACE | LOWER | OSHIFT | RALT | APP | XXXXXX | RCTRL | | LEFT | DOWN | RIGHT | M5 |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
*/
KEYMAP(LAYER_QWERTY, \
M_HELP , KC_PSCR, KC_SLCK, KC_PAUS, KC_F1 , KC_F2 , KC_F3 , KC_F4 , XXXXXXX, KC_F5 , KC_F6 , KC_F7 , KC_F8 , XXXXXXX, KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_VOLD, KC_MUTE, KC_VOLU, M_BACKL, \
M_M1 , KC_INS , KC_HOME, KC_PGUP, KC_ESC , KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_EQL , KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, \
M_M2 , KC_DEL , KC_END , KC_PGDN, KC_TAB , KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_MINS, KC_BSLS, KC_KP_7, KC_KP_8, KC_KP_9, KC_PPLS, \
M_M3 , M_UL , KC_UP , M_UR , KC_CAPS, KC_BSPC, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_ENT , KC_KP_4, KC_KP_5, KC_KP_6, KC_PPLS, \
M_M4 , KC_LEFT, M_CP_CT, KC_RGHT, KC_LSFT, KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_RSFT, KC_KP_1, KC_KP_2, KC_KP_3, KC_PENT, \
M_M5 , M_DL , KC_DOWN, M_DR , KC_LCTL, XXXXXXX, XXXXXXX, KC_LGUI, KC_LALT, M_LOWER, KC_SPC , KC_SPC , M_UPPER, OS_SHFT, KC_RALT, KC_APP , XXXXXXX, KC_RCTL, KC_KP_0, KC_PCMM, KC_PDOT, KC_PENT \
KC_VOLD, KC_MUTE, KC_VOLU, M_BACKL, KC_F1 , KC_F2 , KC_F3 , KC_F4 , XXXXXXX, KC_F5 , KC_F6 , KC_F7 , KC_F8 , XXXXXXX, KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_PSCR, KC_SLCK, KC_PAUS, M_HELP , \
KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, KC_ESC , KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_EQL , KC_BSPC, KC_INS , KC_HOME, KC_PGUP, M_M1 , \
KC_KP_7, KC_KP_8, KC_KP_9, KC_PPLS, KC_TAB , KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , KC_MINS, KC_BSLS, KC_DEL , KC_END , KC_PGDN, M_M2 , \
KC_KP_4, KC_KP_5, KC_KP_6, KC_PPLS, KC_CAPS, KC_BSPC, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, KC_ENT , M_CP_CT, SC_UNDO, SC_PSTE, M_M3 , \
KC_KP_1, KC_KP_2, KC_KP_3, KC_PENT, KC_LSFT, KC_LSFT, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_RSFT, KC_RSFT, XXXXXXX, KC_UP , XXXXXXX, M_M4 , \
KC_KP_0, KC_PCMM, KC_PDOT, KC_PENT, KC_LCTL, XXXXXXX, KC_LGUI, XXXXXXX, KC_LALT, M_UPPER, KC_SPC , KC_SPC , M_LOWER, OS_SHFT, KC_RALT, KC_APP , XXXXXXX, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, M_M5 \
),
/* LAYER = LAYER_LOWER
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| ______ | ______ | ______ | ______ | | F13 | F14 | F15 | F16 | XXXXXX | F17 | F18 | F19 | F20 | XXXXXX | F21 | F22 | F23 | F24 | | ______ | MUTE A | ______ | ______ |
| ______ | MUTE A | ______ | ______ | | F13 | F14 | F15 | F16 | XXXXXX | F17 | F18 | F19 | F20 | XXXXXX | F21 | F22 | F23 | F24 | | ______ | ______ | ______ | ______ |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
@ -180,20 +192,20 @@ KEYMAP(LAYER_QWERTY, \
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| ______ | ______ | ______ | ______ | | ______ | ______ | | | & | ! | ~ | ; | : | = | < | > | ? | ______ | ______ | | ______ | ______ | ______ | ______ |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| ______ | ______ | ______ | ______ | | ______ | XXXXXX | XXXXXX | ______ | ______ | ______ | ______ . ______ | LOWER | ______ | ______ | ______ | XXXXXX | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ . ______ | LOWER | ______ | ______ | ______ | XXXXXX | ______ | | ______ | ______ | ______ | ______ |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
*/
KEYMAP(LAYER_LOWER, \
_______, _______, _______, _______, KC_F13 , KC_F14 , KC_F15 , KC_F16 , XXXXXXX, KC_F17 , KC_F18 , KC_F19 , KC_F20 , XXXXXXX, KC_F21 , KC_F22 , KC_F23 , KC_F24 , _______, M_MUTEA, _______, _______, \
_______, M_MUTEA, _______, _______, KC_F13 , KC_F14 , KC_F15 , KC_F16 , XXXXXXX, KC_F17 , KC_F18 , KC_F19 , KC_F20 , XXXXXXX, KC_F21 , KC_F22 , KC_F23 , KC_F24 , _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_DLR , KC_LCBR, KC_LBRC, KC_LPRN, KC_PERC, KC_HASH, KC_RPRN, KC_RBRC, KC_RCBR, KC_AT , _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_CIRC, KC_ASTR, KC_PLUS, KC_MINS, KC_SLSH, KC_BSLS, KC_UNDS, KC_QUOT, KC_DQT , KC_GRV , _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_PIPE, KC_AMPR, KC_EXLM, KC_TILD, KC_SCLN, KC_COLN, KC_EQL , KC_LT , KC_GT , KC_QUES, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, M_LOWER, _______, _______, _______, XXXXXXX, _______, _______, _______, _______, _______ \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, M_LOWER, _______, _______, _______, XXXXXXX, _______, _______, _______, _______, _______ \
),
/* LAYER = LAYER_UPPER
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| ______ | ______ | ______ | ______ | | F13 | F14 | F15 | F16 | XXXXXX | F17 | F18 | F19 | F20 | XXXXXX | F21 | F22 | F23 | F24 | | ______ | MUTE A | ______ | ______ |
| ______ | MUTE A | ______ | ______ | | F13 | F14 | F15 | F16 | XXXXXX | F17 | F18 | F19 | F20 | XXXXXX | F21 | F22 | F23 | F24 | | ______ | ______ | ______ | ______ |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
@ -204,44 +216,44 @@ KEYMAP(LAYER_LOWER, \
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| ______ | ______ | ______ | ______ | | ______ | ______ | F9 | F10 | F11 | F12 | SCR LK | KP 0 | KP 1 | KP 2 | KP 3 | KP Ent | ______ | ______ | | ______ | ______ | ______ | ______ |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| ______ | ______ | ______ | ______ | | ______ | XXXXXX | XXXXXX | ______ | ______ | UPPER | KP 0 . KP 0 | ______ | RALT | KP . | KP Ent | XXXXXX | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | UPPER | KP 0 . KP 0 | ______ | RALT | KP . | KP Ent | XXXXXX | ______ | | ______ | ______ | ______ | ______ |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
*/
KEYMAP(LAYER_UPPER, \
_______, _______, _______, _______, KC_F13 , KC_F14 , KC_F15 , KC_F16 , XXXXXXX, KC_F17 , KC_F18 , KC_F19 , KC_F20 , XXXXXXX, KC_F21 , KC_F22 , KC_F23 , KC_F24 , _______, M_MUTEA, _______, _______, \
_______, M_MUTEA, _______, _______, KC_F13 , KC_F14 , KC_F15 , KC_F16 , XXXXXXX, KC_F17 , KC_F18 , KC_F19 , KC_F20 , XXXXXXX, KC_F21 , KC_F22 , KC_F23 , KC_F24 , _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_NLCK, KC_PSLS, KC_KP_7, KC_KP_8, KC_KP_9, KC_PMNS, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_CAPS, KC_PAST, KC_KP_4, KC_KP_5, KC_KP_6, KC_PPLS, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_SLCK, KC_KP_0, KC_KP_1, KC_KP_2, KC_KP_3, KC_PENT, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, _______, _______, M_UPPER, KC_KP_0, KC_KP_0, _______, KC_RALT, KC_PDOT, KC_PENT, XXXXXXX, _______, _______, _______, _______, _______ \
_______, _______, _______, _______, _______, _______, _______, _______, _______, M_UPPER, KC_KP_0, KC_KP_0, _______, KC_RALT, KC_PDOT, KC_PENT, XXXXXXX, _______, _______, _______, _______, _______ \
),
/* LAYER = LAYER_MOUSE
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| MS BT1 | MS AC0 | MS WHU | MS AC2 | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | MS AC0 | MS WHU | MS AC2 | MS BT1 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| MS BT2 | MS WHL | MS WHD | MS WHU | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | MS WHL | MS WHD | MS WHU | MS BT2 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| MS BT3 | MS UL | MS U | MS UR | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | o | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | o | MS BT1 | MS BT2 | MS BT3 | MS BT3 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| o |--------|--------|--------+--------|
| MS BT4 | MS L | MS BT1 | MS R | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | ______ | | XXXXXX | MS U | XXXXXX | MS BT4 |
|--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------| |--------|--------|--------+--------|
| MS BT5 | MS DL | MS D | MS DR | | ______ | ______ | ______ | ______ | ______ | ______ | ______ . ______ | ______ | ______ | ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ |
| ______ | ______ | ______ | ______ | | ______ | ______ | ______ | ______ | ______ | ______ | ______ . ______ | ______ | ______ | ______ | ______ | ______ | ______ | | MS L | MS D | MS R | MS BT5 |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
*/
KEYMAP(LAYER_MOUSE, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
KC_BTN1, KC_ACL0, KC_WH_U, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
KC_BTN2, KC_WH_L, KC_WH_D, KC_WH_U, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
KC_BTN3, M_MS_UL, KC_MS_U, M_MS_UR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
KC_BTN4, KC_MS_L, KC_BTN1, KC_MS_R, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
KC_BTN5, M_MS_DL, KC_MS_D, M_MS_DR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ACL0, KC_WH_U, KC_ACL2, KC_BTN1, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_WH_L, KC_WH_D, KC_WH_U, KC_BTN2, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BTN1, KC_BTN2, KC_BTN3, KC_BTN3, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_MS_U, XXXXXXX, KC_BTN4, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_BTN5 \
),
/* LAYER = LAYER_ADJUST
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| XXXXXX | XXXXXX | XXXXXX | XXXXXX | | HELP 1 | HELP 2 | HELP 3 | HELP 4 | XXXXXX | HELP 5 | HELP 6 | HELP 7 | HELP 8 | XXXXXX | HELP 9 | HELP 0 | XXXXXX | XXXXXX | | VOICE- | AUDIO | VOICE+ | MUSIC |
| VOICE- | AUDIO | VOICE+ | MUSIC | | HELP 1 | HELP 2 | HELP 3 | HELP 4 | XXXXXX | HELP 5 | HELP 6 | HELP 7 | HELP 8 | XXXXXX | HELP 9 | HELP 0 | XXXXXX | XXXXXX | | XXXXXX | XXXXXX | XXXXXX | XXXXXX |
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
.-----------------------------------. .-----------------------------------------------------------------------------------------------------------------------------. .-----------------------------------.
| XXXXXX | XXXXXX | XXXXXX | XXXXXX | | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | XXXXXX | | XXXXXX | XXXXXX | XXXXXX | XXXXXX |
@ -256,14 +268,13 @@ KEYMAP(LAYER_MOUSE, \
'-----------------------------------' '-----------------------------------------------------------------------------------------------------------------------------' '-----------------------------------'
*/
KEYMAP(LAYER_ADJUST, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, M_HELP1, M_HELP2, M_HELP3, M_HELP4, XXXXXXX, M_HELP5, M_HELP6, M_HELP7, M_HELP8, XXXXXXX, M_HELP9, M_HELP0, XXXXXXX, XXXXXXX, MUV_DE , AU_TOG , MUV_IN , MU_TOG , \
MUV_DE , AU_TOG , MUV_IN , MU_TOG , M_HELP1, M_HELP2, M_HELP3, M_HELP4, XXXXXXX, M_HELP5, M_HELP6, M_HELP7, M_HELP8, XXXXXXX, M_HELP9, M_HELP0, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RESET , XXXXXXX, M_MOUSE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, M_UPPER, XXXXXXX, XXXXXXX, M_LOWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX \
),
};
#ifdef AUDIO_ENABLE
@ -296,6 +307,7 @@ void persistant_default_layer_set(uint16_t default_layer)
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_MODS_ONESHOT(MOD_LSFT),
[1] = ACTION_MACRO_TAP(MACRO_COPY_CUT),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
@ -305,68 +317,84 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
switch(id)
{
case MACRO_HELP_1:
if (record->event.pressed)
{
uprint("H1");
}
break;
case MACRO_HELP_2:
if (record->event.pressed)
{
uprint("H2");
}
break;
case MACRO_HELP_3:
if (record->event.pressed)
{
uprint("H3");
}
break;
case MACRO_HELP_4:
if (record->event.pressed)
{
uprint("H4");
}
break;
case MACRO_HELP_5:
if (record->event.pressed)
{
uprint("H5");
}
break;
case MACRO_HELP_6:
if (record->event.pressed)
{
uprint("H6");
}
break;
case MACRO_HELP_7:
if (record->event.pressed)
{
uprint("H7");
}
break;
case MACRO_HELP_8:
if (record->event.pressed)
{
uprint("H8");
}
break;
case MACRO_HELP_9:
if (record->event.pressed)
{
uprint("H9");
}
break;
case MACRO_COPY_CUT:
if (record->event.pressed) {
register_code(KC_LCTL);
if (record->tap.count == 1) {
register_code(KC_C);
unregister_code(KC_C);
}
else if (record->tap.count == 2) {
register_code(KC_X);
unregister_code(KC_X);
}
unregister_code(KC_LCTL);
}
break;
// case MACRO_HELP_1:
// if (record->event.pressed)
// {
// uprint("H1");
// }
// break;
// case MACRO_HELP_2:
// if (record->event.pressed)
// {
// uprint("H2");
// }
// break;
// case MACRO_HELP_3:
// if (record->event.pressed)
// {
// uprint("H3");
// }
// break;
// case MACRO_HELP_4:
// if (record->event.pressed)
// {
// uprint("H4");
// }
// break;
// case MACRO_HELP_5:
// if (record->event.pressed)
// {
// uprint("H5");
// }
// break;
// case MACRO_HELP_6:
// if (record->event.pressed)
// {
// uprint("H6");
// }
// break;
// case MACRO_HELP_7:
// if (record->event.pressed)
// {
// uprint("H7");
// }
// break;
// case MACRO_HELP_8:
// if (record->event.pressed)
// {
// uprint("H8");
// }
// break;
// case MACRO_HELP_9:
// if (record->event.pressed)
// {
// uprint("H9");
// }
// break;
case MACRO_BREATH_TOGGLE:
if (record->event.pressed)
@ -566,12 +594,12 @@ void led_set_user(uint8_t usb_led)
void startup_user()
{
_delay_ms(10); // gets rid of tick
PLAY_NOTE_ARRAY(tone_my_startup, false, STACCATO);
// PLAY_NOTE_ARRAY(tone_my_startup, false, STACCATO);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_my_goodbye, false, STACCATO);
// PLAY_NOTE_ARRAY(tone_my_goodbye, false, STACCATO);
_delay_ms(2000);
stop_all_notes();
}

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

@ -0,0 +1,68 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER XIUDI
#define PRODUCT XD60
#define DESCRIPTION XD60 Keyboard by XIUDI
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 14
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }
#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* number of backlight levels */
#define BACKLIGHT_LEVELS 3
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
#endif

@ -0,0 +1,64 @@
#include "xd60.h"
#include "action_layer.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// 0: Base Layer
KEYMAP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_DEL, \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RGUI, KC_RALT, KC_LEFT, KC_DOWN, KC_RIGHT),
// 1: Function Layer
KEYMAP(
RESET, 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_F13, KC_F14, \
KC_NO, KC_WH_U, KC_UP, KC_WH_D, KC_BSPC,KC_HOME,KC_CALC,KC_NO, KC_INS, KC_NO, KC_PSCR, KC_SLCK, KC_PAUS, KC_DEL, \
KC_NO, KC_LEFT, KC_DOWN, KC_RIGHT,KC_DEL, KC_END, KC_PGDN,KC_NO, KC_NO, KC_NO, KC_HOME, KC_PGUP, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_NO, KC_APP, BL_TOGG,BL_DEC, BL_INC, KC_VOLD,KC_VOLU,KC_MUTE, KC_END, KC_PGDN, KC_RSFT, KC_PGUP, KC_NO, \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, F(0), KC_HOME, KC_PGDOWN,KC_END),
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(1), // to Fn overlay
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
void matrix_scan_user(void) {
// Layer LED indicators
uint32_t layer = layer_state;
if (layer & (1<<1)) {
xd60_esc_led_on();
} else {
xd60_esc_led_off();
}
/*
if (layer & (1<<2)) {
xd60_poker_leds_on();
xd60_esc_led_on();
} else {
xd60_poker_leds_off();
xd60_esc_led_off();
}
*/
};

@ -0,0 +1,9 @@
# Default Keymap for XIUDI's 60% XD60 PCB
![Default Keymap for XD60](https://img.alicdn.com/imgextra/i1/1713761720/TB2K0gTalPxQeBjy1XcXXXHzVXa_!!1713761720.png)
## Additional Notes
Default Keymap for XD60 as indicated on the original sale page.
## Build
To build the default keymap, simply run `make xd60-default`.

@ -0,0 +1,60 @@
#include "xd60.h"
#include "action_layer.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// 0: Base Layer
KEYMAP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
F(0), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_DEL, \
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, KC_RALT, KC_LEFT, KC_DOWN, KC_RIGHT),
// 1: Function Layer
KEYMAP(
RESET, 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_F13, KC_F14, \
KC_CAPS, KC_MPRV, KC_UP, KC_MNXT, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, BL_STEP, BL_TOGG, KC_DEL, \
F(0), KC_LEFT, KC_DOWN, KC_RIGHT,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_VOLD, KC_MUTE, KC_VOLU,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_RSFT, KC_PGUP, KC_INS, \
KC_LCTL, KC_LALT, KC_LGUI, KC_MPLY, KC_RGUI, KC_RALT, KC_HOME, KC_PGDOWN,KC_END),
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(1), // to Fn overlay
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
void matrix_scan_user(void) {
// Layer LED indicators
uint32_t layer = layer_state;
if (layer & (1<<1)) {
xd60_wasd_leds_on();
xd60_fn_led_on();
xd60_esc_led_on();
xd60_poker_leds_on();
} else {
xd60_wasd_leds_off();
xd60_fn_led_off();
xd60_esc_led_off();
xd60_poker_leds_off();
}
};

@ -0,0 +1,13 @@
# QMK Firmware for XIUDI's 60% XD60 PCB
![Top View of XD60 Keyboard, with DSA Dolch keycaps](./top-view.JPG)
![Angled View of XD60 Keyboard Arrow Cluster, with DSA Dolch keycaps](./arrow-cluster.JPG)
## Quantum MK Firmware
For the full Quantum feature list, see [the parent readme.md](/readme.md).
## Additional Notes
The XD60 is essentially a GH60 rev. C, with support for a right-hand arrow cluster. Includes full compatibility with GH60 expansion boards. Board also supports in-switch LEDs (two-pin, single colour), as well as WS2182 LED strips for underglow lighting. Default keymap included, matching configuration on sale page.
## Build
To build the default keymap, simply run `make xd60-default`.

@ -0,0 +1,65 @@
# MCU name
# MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
# LUFA specific
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -0,0 +1,25 @@
#include "xd60.h"
void led_set_kb(uint8_t usb_led) {
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
xd60_caps_led_on();
} else {
xd60_caps_led_off();
}
// if (usb_led & (1<<USB_LED_NUM_LOCK)) {
// xd60_esc_led_on();
// } else {
// xd60_esc_led_off();
// }
// if (usb_led & (1<<USB_LED_SCROLL_LOCK)) {
// xd60_fn_led_on();
// } else {
// xd60_fn_led_off();
// }
led_set_user(usb_led);
}

@ -0,0 +1,43 @@
#ifndef XD60_H
#define XD60_H
#include "quantum.h"
#include "led.h"
/* XD60 LEDs
* GPIO pads
* 0 F7 WASD LEDs
* 1 F6 ESC LED
* 2 F5 FN LED
* 3 F4 POKER Arrow LEDs
* B2 Capslock LED
* B0 not connected
*/
inline void xd60_caps_led_on(void) { DDRB |= (1<<2); PORTB &= ~(1<<2); }
inline void xd60_poker_leds_on(void) { DDRF |= (1<<4); PORTF &= ~(1<<4); }
inline void xd60_fn_led_on(void) { DDRF |= (1<<5); PORTF &= ~(1<<5); }
inline void xd60_esc_led_on(void) { DDRF |= (1<<6); PORTF &= ~(1<<6); }
inline void xd60_wasd_leds_on(void) { DDRF |= (1<<7); PORTF &= ~(1<<7); }
inline void xd60_caps_led_off(void) { DDRB &= ~(1<<2); PORTB &= ~(1<<2); }
inline void xd60_poker_leds_off(void) { DDRF &= ~(1<<4); PORTF &= ~(1<<4); }
inline void xd60_fn_led_off(void) { DDRF &= ~(1<<5); PORTF &= ~(1<<5); }
inline void xd60_esc_led_off(void) { DDRF &= ~(1<<6); PORTF &= ~(1<<6); }
inline void xd60_wasd_leds_off(void) { DDRF &= ~(1<<7); PORTF &= ~(1<<7); }
/* XD60 Keymap Definition Macro */
#define KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K49, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K47, K3D, K3C, \
K40, K41, K42, K45, K4A, K4B, K48, K4C, K4D \
) { \
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
{ K40, K41, K42, KC_NO,KC_NO,K45, KC_NO,K47, K48, K49, K4A, K4B, K4C, K4D } \
}
#endif

@ -0,0 +1,179 @@
#include "api.h"
#include "quantum.h"
void dword_to_bytes(uint32_t dword, uint8_t * bytes) {
bytes[0] = (dword >> 24) & 0xFF;
bytes[1] = (dword >> 16) & 0xFF;
bytes[2] = (dword >> 8) & 0xFF;
bytes[3] = (dword >> 0) & 0xFF;
}
uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index) {
return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3];
}
__attribute__ ((weak))
bool process_api_quantum(uint8_t length, uint8_t * data) {
return process_api_keyboard(length, data);
}
__attribute__ ((weak))
bool process_api_keyboard(uint8_t length, uint8_t * data) {
return process_api_user(length, data);
}
__attribute__ ((weak))
bool process_api_user(uint8_t length, uint8_t * data) {
return true;
}
void process_api(uint16_t length, uint8_t * data) {
// SEND_STRING("\nRX: ");
// for (uint8_t i = 0; i < length; i++) {
// send_byte(data[i]);
// SEND_STRING(" ");
// }
if (!process_api_quantum(length, data))
return;
switch (data[0]) {
case MT_SET_DATA:
switch (data[1]) {
case DT_DEFAULT_LAYER: {
eeconfig_update_default_layer(data[2]);
default_layer_set((uint32_t)(data[2]));
break;
}
case DT_KEYMAP_OPTIONS: {
eeconfig_update_keymap(data[2]);
break;
}
case DT_RGBLIGHT: {
#ifdef RGBLIGHT_ENABLE
uint32_t rgblight = bytes_to_dword(data, 2);
rgblight_update_dword(rgblight);
#endif
break;
}
}
case MT_GET_DATA:
switch (data[1]) {
case DT_HANDSHAKE: {
MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0);
break;
}
case DT_DEBUG: {
uint8_t debug_bytes[1] = { eeprom_read_byte(EECONFIG_DEBUG) };
MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1);
break;
}
case DT_DEFAULT_LAYER: {
uint8_t default_bytes[1] = { eeprom_read_byte(EECONFIG_DEFAULT_LAYER) };
MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1);
break;
}
case DT_CURRENT_LAYER: {
uint8_t layer_state_bytes[4];
dword_to_bytes(layer_state, layer_state_bytes);
MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4);
break;
}
case DT_AUDIO: {
#ifdef AUDIO_ENABLE
uint8_t audio_bytes[1] = { eeprom_read_byte(EECONFIG_AUDIO) };
MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1);
#else
MT_GET_DATA_ACK(DT_AUDIO, NULL, 0);
#endif
break;
}
case DT_BACKLIGHT: {
#ifdef BACKLIGHT_ENABLE
uint8_t backlight_bytes[1] = { eeprom_read_byte(EECONFIG_BACKLIGHT) };
MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1);
#else
MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0);
#endif
break;
}
case DT_RGBLIGHT: {
#ifdef RGBLIGHT_ENABLE
uint8_t rgblight_bytes[4];
dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes);
MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4);
#else
MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0);
#endif
break;
}
case DT_KEYMAP_OPTIONS: {
uint8_t keymap_bytes[1] = { eeconfig_read_keymap() };
MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1);
break;
}
case DT_KEYMAP_SIZE: {
uint8_t keymap_size[2] = {MATRIX_ROWS, MATRIX_COLS};
MT_GET_DATA_ACK(DT_KEYMAP_SIZE, keymap_size, 2);
break;
}
// This may be too much
// case DT_KEYMAP: {
// uint8_t keymap_data[MATRIX_ROWS * MATRIX_COLS * 4 + 3];
// keymap_data[0] = data[2];
// keymap_data[1] = MATRIX_ROWS;
// keymap_data[2] = MATRIX_COLS;
// for (int i = 0; i < MATRIX_ROWS; i++) {
// for (int j = 0; j < MATRIX_COLS; j++) {
// keymap_data[3 + (i*MATRIX_COLS*2) + (j*2)] = pgm_read_word(&keymaps[data[2]][i][j]) >> 8;
// keymap_data[3 + (i*MATRIX_COLS*2) + (j*2) + 1] = pgm_read_word(&keymaps[data[2]][i][j]) & 0xFF;
// }
// }
// MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, MATRIX_ROWS * MATRIX_COLS * 4 + 3);
// // uint8_t keymap_data[5];
// // keymap_data[0] = data[2];
// // keymap_data[1] = data[3];
// // keymap_data[2] = data[4];
// // keymap_data[3] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) >> 8;
// // keymap_data[4] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) & 0xFF;
// // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, 5);
// break;
// }
default:
break;
}
break;
case MT_SET_DATA_ACK:
case MT_GET_DATA_ACK:
break;
case MT_SEND_DATA:
break;
case MT_SEND_DATA_ACK:
break;
case MT_EXE_ACTION:
break;
case MT_EXE_ACTION_ACK:
break;
case MT_TYPE_ERROR:
break;
default: ; // command not recognised
SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length);
break;
// #ifdef RGBLIGHT_ENABLE
// case 0x27: ; // RGB LED functions
// switch (*data++) {
// case 0x00: ; // Update HSV
// rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]);
// break;
// case 0x01: ; // Update RGB
// break;
// case 0x02: ; // Update mode
// rgblight_mode(data[0]);
// break;
// }
// break;
// #endif
}
}

@ -0,0 +1,59 @@
#ifndef _API_H_
#define _API_H_
#include "lufa.h"
enum MESSAGE_TYPE {
MT_GET_DATA = 0x10, // Get data from keyboard
MT_GET_DATA_ACK = 0x11, // returned data to process (ACK)
MT_SET_DATA = 0x20, // Set data on keyboard
MT_SET_DATA_ACK = 0x21, // returned data to confirm (ACK)
MT_SEND_DATA = 0x30, // Sending data/action from keyboard
MT_SEND_DATA_ACK = 0x31, // returned data/action confirmation (ACK)
MT_EXE_ACTION = 0x40, // executing actions on keyboard
MT_EXE_ACTION_ACK =0x41, // return confirmation/value (ACK)
MT_TYPE_ERROR = 0x80 // type not recofgnised (ACK)
};
enum DATA_TYPE {
DT_NONE = 0x00,
DT_HANDSHAKE,
DT_DEFAULT_LAYER,
DT_CURRENT_LAYER,
DT_KEYMAP_OPTIONS,
DT_BACKLIGHT,
DT_RGBLIGHT,
DT_UNICODE,
DT_DEBUG,
DT_AUDIO,
DT_QUANTUM_ACTION,
DT_KEYBOARD_ACTION,
DT_USER_ACTION,
DT_KEYMAP_SIZE,
DT_KEYMAP
};
void dword_to_bytes(uint32_t dword, uint8_t * bytes);
uint32_t bytes_to_dword(uint8_t * bytes, uint8_t index);
#define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length)
#define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length)
#define MT_SET_DATA(data_type, data, length) SEND_BYTES(MT_SET_DATA, data_type, data, length)
#define MT_SET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SET_DATA_ACK, data_type, data, length)
#define MT_SEND_DATA(data_type, data, length) SEND_BYTES(MT_SEND_DATA, data_type, data, length)
#define MT_SEND_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SEND_DATA_ACK, data_type, data, length)
#define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length)
#define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length)
void process_api(uint16_t length, uint8_t * data);
__attribute__ ((weak))
bool process_api_quantum(uint8_t length, uint8_t * data);
__attribute__ ((weak))
bool process_api_keyboard(uint8_t length, uint8_t * data);
__attribute__ ((weak))
bool process_api_user(uint8_t length, uint8_t * data);
#endif

@ -0,0 +1,57 @@
#include "api_sysex.h"
#include "sysex_tools.h"
#include "print.h"
void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
// SEND_STRING("\nTX: ");
// for (uint8_t i = 0; i < length; i++) {
// send_byte(bytes[i]);
// SEND_STRING(" ");
// }
if (length > API_SYSEX_MAX_SIZE) {
xprintf("Sysex msg too big %d %d %d", message_type, data_type, length);
return;
}
// The buffer size required is calculated as the following
// API_SYSEX_MAX_SIZE is the maximum length
// In addition to that we have a two byte message header consisting of the message_type and data_type
// This has to be encoded with an additional overhead of one byte for every starting 7 bytes
// We just add one extra byte in case it's not divisible by 7
// Then we have an unencoded header consisting of 4 bytes
// Plus a one byte terminator
const unsigned message_header = 2;
const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header;
const unsigned encoding_overhead = unencoded_message / 7 + 1;
const unsigned encoded_size = unencoded_message + encoding_overhead;
const unsigned unencoded_header = 4;
const unsigned terminator = 1;
const unsigned buffer_size = encoded_size + unencoded_header + terminator;
uint8_t buffer[encoded_size + unencoded_header + terminator];
// The unencoded header
buffer[0] = 0xF0;
buffer[1] = 0x00;
buffer[2] = 0x00;
buffer[3] = 0x00;
// We copy the message to the end of the array, this way we can do an inplace encoding, using the same
// buffer for both input and output
const unsigned message_size = length + message_header;
uint8_t* unencoded_start = buffer + buffer_size - message_size;
uint8_t* ptr = unencoded_start;
*(ptr++) = message_type;
*(ptr++) = data_type;
memcpy(ptr, bytes, length);
unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size);
unsigned final_size = unencoded_header + encoded_length + terminator;
buffer[final_size - 1] = 0xF7;
midi_send_array(&midi_device, final_size, buffer);
// SEND_STRING("\nTD: ");
// for (uint8_t i = 0; i < encoded_length + 5; i++) {
// send_byte(buffer[i]);
// SEND_STRING(" ");
// }
}

@ -0,0 +1,10 @@
#ifndef _API_SYSEX_H_
#define _API_SYSEX_H_
#include "api.h"
void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length);
#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l)
#endif

@ -77,6 +77,7 @@ static bool audio_initialized = false;
audio_config_t audio_config;
uint16_t envelope_index = 0;
bool glissando = true;
void audio_init()
{
@ -205,13 +206,17 @@ ISR(TIMER3_COMPA_vect)
freq = frequencies[voice_place];
#endif
} else {
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, 440/frequency/12/2);
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, -440/frequency/12/2);
if (glissando) {
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, 440/frequency/12/2);
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, -440/frequency/12/2);
} else {
frequency = frequencies[voices - 1];
}
} else {
frequency = frequencies[voices - 1];
}
}
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {

@ -6,6 +6,7 @@
extern uint16_t envelope_index;
extern float note_timbre;
extern float polyphony_rate;
extern bool glissando;
voice_type voice = default_voice;
@ -18,7 +19,7 @@ void voice_iterate() {
}
void voice_deiterate() {
voice = (voice - 1) % number_of_voices;
voice = (voice - 1 + number_of_voices) % number_of_voices;
}
float voice_envelope(float frequency) {
@ -27,11 +28,122 @@ float voice_envelope(float frequency) {
switch (voice) {
case default_voice:
glissando = true;
note_timbre = TIMBRE_50;
polyphony_rate = 0;
break;
#ifdef AUDIO_VOICES
case something:
glissando = false;
polyphony_rate = 0;
switch (compensated_index) {
case 0 ... 9:
note_timbre = TIMBRE_12;
break;
case 10 ... 19:
note_timbre = TIMBRE_25;
break;
case 20 ... 200:
note_timbre = .125 + .125;
break;
default:
note_timbre = .125;
break;
}
break;
case drums:
glissando = false;
polyphony_rate = 0;
// switch (compensated_index) {
// case 0 ... 10:
// note_timbre = 0.5;
// break;
// case 11 ... 20:
// note_timbre = 0.5 * (21 - compensated_index) / 10;
// break;
// default:
// note_timbre = 0;
// break;
// }
// frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
if (frequency < 80.0) {
} else if (frequency < 160.0) {
// Bass drum: 60 - 100 Hz
frequency = (rand() % (int)(40)) + 60;
switch (envelope_index) {
case 0 ... 10:
note_timbre = 0.5;
break;
case 11 ... 20:
note_timbre = 0.5 * (21 - envelope_index) / 10;
break;
default:
note_timbre = 0;
break;
}
} else if (frequency < 320.0) {
// Snare drum: 1 - 2 KHz
frequency = (rand() % (int)(1000)) + 1000;
switch (envelope_index) {
case 0 ... 5:
note_timbre = 0.5;
break;
case 6 ... 20:
note_timbre = 0.5 * (21 - envelope_index) / 15;
break;
default:
note_timbre = 0;
break;
}
} else if (frequency < 640.0) {
// Closed Hi-hat: 3 - 5 KHz
frequency = (rand() % (int)(2000)) + 3000;
switch (envelope_index) {
case 0 ... 15:
note_timbre = 0.5;
break;
case 16 ... 20:
note_timbre = 0.5 * (21 - envelope_index) / 5;
break;
default:
note_timbre = 0;
break;
}
} else if (frequency < 1280.0) {
// Open Hi-hat: 3 - 5 KHz
frequency = (rand() % (int)(2000)) + 3000;
switch (envelope_index) {
case 0 ... 35:
note_timbre = 0.5;
break;
case 36 ... 50:
note_timbre = 0.5 * (51 - envelope_index) / 15;
break;
default:
note_timbre = 0;
break;
}
}
break;
case butts_fader:
glissando = true;
polyphony_rate = 0;
switch (compensated_index) {
case 0 ... 9:
@ -79,6 +191,7 @@ float voice_envelope(float frequency) {
case duty_osc:
// This slows the loop down a substantial amount, so higher notes may freeze
glissando = true;
polyphony_rate = 0;
switch (compensated_index) {
default:
@ -93,6 +206,7 @@ float voice_envelope(float frequency) {
break;
case duty_octave_down:
glissando = true;
polyphony_rate = 0;
note_timbre = (envelope_index % 2) * .125 + .375 * 2;
if ((envelope_index % 4) == 0)
@ -101,6 +215,7 @@ float voice_envelope(float frequency) {
note_timbre = 0;
break;
case delayed_vibrato:
glissando = true;
polyphony_rate = 0;
note_timbre = TIMBRE_50;
#define VOICE_VIBRATO_DELAY 150
@ -155,11 +270,11 @@ float voice_envelope(float frequency) {
// note_timbre = 0.25;
// break;
#endif
default:
break;
}
return frequency;
}

@ -11,6 +11,9 @@ float voice_envelope(float frequency);
typedef enum {
default_voice,
#ifdef AUDIO_VOICES
something,
drums,
butts_fader,
octave_crunch,
duty_osc,
@ -21,6 +24,7 @@ typedef enum {
// duty_fourth_down,
// duty_third_down,
// duty_fifth_third_down,
#endif
number_of_voices // important that this is last
} voice_type;

@ -5,55 +5,56 @@
#define COL2ROW 0
#define ROW2COL 1
/* I/O pins */
#define B0 0x30
#define B1 0x31
#define B2 0x32
#define B3 0x33
#define B4 0x34
#define B5 0x35
#define B6 0x36
#define B7 0x37
#define C0 0x60
#define C1 0x61
#define C2 0x62
#define C3 0x63
#define C4 0x64
#define C5 0x65
#define C6 0x66
#define C7 0x67
#define D0 0x90
#define D1 0x91
#define D2 0x92
#define D3 0x93
#define D4 0x94
#define D5 0x95
#define D6 0x96
#define D7 0x97
#define E0 0xC0
#define E1 0xC1
#define E2 0xC2
#define E3 0xC3
#define E4 0xC4
#define E5 0xC5
#define E6 0xC6
#define E7 0xC7
#define F0 0xF0
#define F1 0xF1
#define F2 0xF2
#define F3 0xF3
#define F4 0xF4
#define F5 0xF5
#define F6 0xF6
#define F7 0xF7
#define A0 0x00
#define A1 0x01
#define A2 0x02
#define A3 0x03
#define A4 0x04
#define A5 0x05
#define A6 0x06
#define A7 0x07
#ifndef F0
#define B0 0x30
#define B1 0x31
#define B2 0x32
#define B3 0x33
#define B4 0x34
#define B5 0x35
#define B6 0x36
#define B7 0x37
#define C0 0x60
#define C1 0x61
#define C2 0x62
#define C3 0x63
#define C4 0x64
#define C5 0x65
#define C6 0x66
#define C7 0x67
#define D0 0x90
#define D1 0x91
#define D2 0x92
#define D3 0x93
#define D4 0x94
#define D5 0x95
#define D6 0x96
#define D7 0x97
#define E0 0xC0
#define E1 0xC1
#define E2 0xC2
#define E3 0xC3
#define E4 0xC4
#define E5 0xC5
#define E6 0xC6
#define E7 0xC7
#define F0 0xF0
#define F1 0xF1
#define F2 0xF2
#define F3 0xF3
#define F4 0xF4
#define F5 0xF5
#define F6 0xF6
#define F7 0xF7
#define A0 0x00
#define A1 0x01
#define A2 0x02
#define A3 0x03
#define A4 0x04
#define A5 0x05
#define A6 0x06
#define A7 0x07
#endif
/* USART configuration */
#ifdef BLUETOOTH_ENABLE
@ -76,53 +77,9 @@
} while(0)
# else
# error "USART configuration is needed."
# endif
#endif
// I'm fairly sure these aren't needed, but oh well - Jack
/*
* PS/2 Interrupt configuration
*/
#ifdef PS2_USE_INT
/* uses INT1 for clock line(ATMega32U4) */
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 1
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 0
#define PS2_INT_INIT() do { \
EICRA |= ((1<<ISC11) | \
(0<<ISC10)); \
} while (0)
#define PS2_INT_ON() do { \
EIMSK |= (1<<INT1); \
} while (0)
#define PS2_INT_OFF() do { \
EIMSK &= ~(1<<INT1); \
} while (0)
#define PS2_INT_VECT INT1_vect
#endif
/*
* PS/2 Busywait configuration
*/
#ifdef PS2_USE_BUSYWAIT
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 1
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 0
#endif
#endif
#define API_SYSEX_MAX_SIZE 32
#endif

@ -38,306 +38,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RESET QK_RESET
#endif
/* translates key to keycode */
#include "quantum_keycodes.h"
// translates key to keycode
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
// translates function id to action
uint16_t keymap_function_id_to_action( uint16_t function_id );
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];
enum quantum_keycodes {
// Ranges used in shortucuts - not to be used directly
QK_TMK = 0x0000,
QK_TMK_MAX = 0x00FF,
QK_MODS = 0x0100,
QK_LCTL = 0x0100,
QK_LSFT = 0x0200,
QK_LALT = 0x0400,
QK_LGUI = 0x0800,
QK_RCTL = 0x1100,
QK_RSFT = 0x1200,
QK_RALT = 0x1400,
QK_RGUI = 0x1800,
QK_MODS_MAX = 0x1FFF,
QK_FUNCTION = 0x2000,
QK_FUNCTION_MAX = 0x2FFF,
QK_MACRO = 0x3000,
QK_MACRO_MAX = 0x3FFF,
QK_LAYER_TAP = 0x4000,
QK_LAYER_TAP_MAX = 0x4FFF,
QK_TO = 0x5000,
QK_TO_MAX = 0x50FF,
QK_MOMENTARY = 0x5100,
QK_MOMENTARY_MAX = 0x51FF,
QK_DEF_LAYER = 0x5200,
QK_DEF_LAYER_MAX = 0x52FF,
QK_TOGGLE_LAYER = 0x5300,
QK_TOGGLE_LAYER_MAX = 0x53FF,
QK_ONE_SHOT_LAYER = 0x5400,
QK_ONE_SHOT_LAYER_MAX = 0x54FF,
QK_ONE_SHOT_MOD = 0x5500,
QK_ONE_SHOT_MOD_MAX = 0x55FF,
#ifndef DISABLE_CHORDING
QK_CHORDING = 0x5600,
QK_CHORDING_MAX = 0x56FF,
#endif
QK_MOD_TAP = 0x6000,
QK_MOD_TAP_MAX = 0x6FFF,
QK_TAP_DANCE = 0x7100,
QK_TAP_DANCE_MAX = 0x71FF,
#ifdef UNICODE_ENABLE
QK_UNICODE = 0x8000,
QK_UNICODE_MAX = 0xFFFF,
#endif
// Loose keycodes - to be used directly
RESET = 0x7000,
DEBUG,
MAGIC_SWAP_CONTROL_CAPSLOCK,
MAGIC_CAPSLOCK_TO_CONTROL,
MAGIC_SWAP_LALT_LGUI,
MAGIC_SWAP_RALT_RGUI,
MAGIC_NO_GUI,
MAGIC_SWAP_GRAVE_ESC,
MAGIC_SWAP_BACKSLASH_BACKSPACE,
MAGIC_HOST_NKRO,
MAGIC_SWAP_ALT_GUI,
MAGIC_UNSWAP_CONTROL_CAPSLOCK,
MAGIC_UNCAPSLOCK_TO_CONTROL,
MAGIC_UNSWAP_LALT_LGUI,
MAGIC_UNSWAP_RALT_RGUI,
MAGIC_UNNO_GUI,
MAGIC_UNSWAP_GRAVE_ESC,
MAGIC_UNSWAP_BACKSLASH_BACKSPACE,
MAGIC_UNHOST_NKRO,
MAGIC_UNSWAP_ALT_GUI,
MAGIC_TOGGLE_NKRO,
// Leader key
#ifndef DISABLE_LEADER
KC_LEAD,
#endif
// Audio on/off/toggle
AU_ON,
AU_OFF,
AU_TOG,
// Music mode on/off/toggle
MU_ON,
MU_OFF,
MU_TOG,
// Music voice iterate
MUV_IN,
MUV_DE,
// Midi mode on/off
MIDI_ON,
MIDI_OFF,
// Backlight functionality
BL_0,
BL_1,
BL_2,
BL_3,
BL_4,
BL_5,
BL_6,
BL_7,
BL_8,
BL_9,
BL_10,
BL_11,
BL_12,
BL_13,
BL_14,
BL_15,
BL_DEC,
BL_INC,
BL_TOGG,
BL_STEP,
// RGB functionality
RGB_TOG,
RGB_MOD,
RGB_HUI,
RGB_HUD,
RGB_SAI,
RGB_SAD,
RGB_VAI,
RGB_VAD,
// Left shift, open paren
KC_LSPO,
// Right shift, close paren
KC_RSPC,
// always leave at the end
SAFE_RANGE
};
// Ability to use mods in layouts
#define LCTL(kc) (kc | QK_LCTL)
#define LSFT(kc) (kc | QK_LSFT)
#define LALT(kc) (kc | QK_LALT)
#define LGUI(kc) (kc | QK_LGUI)
#define RCTL(kc) (kc | QK_RCTL)
#define RSFT(kc) (kc | QK_RSFT)
#define RALT(kc) (kc | QK_RALT)
#define RGUI(kc) (kc | QK_RGUI)
#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI)
#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT)
#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI)
#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
#define MOD_HYPR 0xf
#define MOD_MEH 0x7
// Aliases for shifted symbols
// Each key has a 4-letter code, and some have longer aliases too.
// While the long aliases are descriptive, the 4-letter codes
// make for nicer grid layouts (everything lines up), and are
// the preferred style for Quantum.
#define KC_TILD LSFT(KC_GRV) // ~
#define KC_TILDE KC_TILD
#define KC_EXLM LSFT(KC_1) // !
#define KC_EXCLAIM KC_EXLM
#define KC_AT LSFT(KC_2) // @
#define KC_HASH LSFT(KC_3) // #
#define KC_DLR LSFT(KC_4) // $
#define KC_DOLLAR KC_DLR
#define KC_PERC LSFT(KC_5) // %
#define KC_PERCENT KC_PERC
#define KC_CIRC LSFT(KC_6) // ^
#define KC_CIRCUMFLEX KC_CIRC
#define KC_AMPR LSFT(KC_7) // &
#define KC_AMPERSAND KC_AMPR
#define KC_ASTR LSFT(KC_8) // *
#define KC_ASTERISK KC_ASTR
#define KC_LPRN LSFT(KC_9) // (
#define KC_LEFT_PAREN KC_LPRN
#define KC_RPRN LSFT(KC_0) // )
#define KC_RIGHT_PAREN KC_RPRN
#define KC_UNDS LSFT(KC_MINS) // _
#define KC_UNDERSCORE KC_UNDS
#define KC_PLUS LSFT(KC_EQL) // +
#define KC_LCBR LSFT(KC_LBRC) // {
#define KC_LEFT_CURLY_BRACE KC_LCBR
#define KC_RCBR LSFT(KC_RBRC) // }
#define KC_RIGHT_CURLY_BRACE KC_RCBR
#define KC_LABK LSFT(KC_COMM) // <
#define KC_LEFT_ANGLE_BRACKET KC_LABK
#define KC_RABK LSFT(KC_DOT) // >
#define KC_RIGHT_ANGLE_BRACKET KC_RABK
#define KC_COLN LSFT(KC_SCLN) // :
#define KC_COLON KC_COLN
#define KC_PIPE LSFT(KC_BSLS) // |
#define KC_LT LSFT(KC_COMM) // <
#define KC_GT LSFT(KC_DOT) // >
#define KC_QUES LSFT(KC_SLSH) // ?
#define KC_QUESTION KC_QUES
#define KC_DQT LSFT(KC_QUOT) // "
#define KC_DOUBLE_QUOTE KC_DQT
#define KC_DQUO KC_DQT
#define KC_DELT KC_DELETE // Del key (four letter code)
// Alias for function layers than expand past FN31
#define FUNC(kc) (kc | QK_FUNCTION)
// Aliases
#define S(kc) LSFT(kc)
#define F(kc) FUNC(kc)
#define M(kc) (kc | QK_MACRO)
#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
// L-ayer, T-ap - 256 keycode max, 16 layer max
#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
#define AG_SWAP MAGIC_SWAP_ALT_GUI
#define AG_NORM MAGIC_UNSWAP_ALT_GUI
#define BL_ON BL_9
#define BL_OFF BL_0
#define MI_ON MIDI_ON
#define MI_OFF MIDI_OFF
// GOTO layer - 16 layers max
// when:
// ON_PRESS = 1
// ON_RELEASE = 2
// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
// keycode modeled after the old version, kept below for this.
/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */
#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4))
// Momentary switch layer - 256 layer max
#define MO(layer) (layer | QK_MOMENTARY)
// Set default layer - 256 layer max
#define DF(layer) (layer | QK_DEF_LAYER)
// Toggle to layer - 256 layer max
#define TG(layer) (layer | QK_TOGGLE_LAYER)
// One-shot layer - 256 layer max
#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
// One-shot mod
#define OSM(mod) (mod | QK_ONE_SHOT_MOD)
// M-od, T-ap - 256 keycode max
#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8))
#define CTL_T(kc) MT(MOD_LCTL, kc)
#define SFT_T(kc) MT(MOD_LSFT, kc)
#define ALT_T(kc) MT(MOD_LALT, kc)
#define GUI_T(kc) MT(MOD_LGUI, kc)
#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal
#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl
#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui
#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
#define KC_HYPR HYPR(KC_NO)
#define KC_MEH MEH(KC_NO)
#ifdef UNICODE_ENABLE
// For sending unicode codes.
// You may not send codes over 7FFF -- this supports most of UTF8.
// To have a key that sends out Œ, go UC(0x0152)
#define UNICODE(n) (n | QK_UNICODE)
#define UC(n) UNICODE(n)
#endif
#endif

@ -48,12 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key)
action_t action;
uint8_t action_layer, when, mod;
// The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason
const uint16_t* actions = fn_actions;
switch (keycode) {
case KC_FN0 ... KC_FN31:
action.code = pgm_read_word(&actions[FN_INDEX(keycode)]);
action.code = keymap_function_id_to_action(FN_INDEX(keycode));
break;
case KC_A ... KC_EXSEL:
case KC_LCTRL ... KC_RGUI:
@ -79,7 +77,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)
case QK_FUNCTION ... QK_FUNCTION_MAX: ;
// Is a shortcut for function action_layer, pull last 12bits
// This means we have 4,096 FN macros at our disposal
action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]);
action.code = keymap_function_id_to_action( (int)keycode & 0xFFF );
break;
case QK_MACRO ... QK_MACRO_MAX:
action.code = ACTION_MACRO(keycode & 0xFF);
@ -163,9 +161,17 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
{
}
/* translates key to keycode */
// translates key to keycode
__attribute__ ((weak))
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
{
// Read entire word (16bits)
return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
}
// translates function id to action
__attribute__ ((weak))
uint16_t keymap_function_id_to_action( uint16_t function_id )
{
return pgm_read_word(&fn_actions[function_id]);
}

@ -0,0 +1,58 @@
#ifndef KEYMAP_BR_ABNT2_H
#define KEYMAP_BR_ABNT2_H
#include "keymap_common.h"
/* Scan codes for the Brazilian ABNT2 keyboard layout */
#define BR_CCDL KC_SCLN // Ç same scancode as ;: on US layout
#define BR_SCLN KC_SLSH // ;: same scancode as /? on US layout
#define BR_QUOT KC_GRV // '" same scancode as `~ on US layout
#define BR_TILD KC_QUOT // ~^ dead keys, same scancode as '" on US layout
#define BR_ACUT KC_LBRC // ´` dead keys, same scancode as [{ on US layout
#define BR_LBRC KC_RBRC // [{ same scancode as ]} on US layout
#define BR_RBRC KC_BSLS // ]} same scancode as \| on US layout
#define BR_BSLS KC_NUBS // \| uses the non-US hash scancode (#~, sometimes §±)
#define BR_SLSH KC_INT1 // /? uses the INTL1 scancode
#define BR_COLN LSFT(BR_SCLN) // shifted :
#define BR_DQT LSFT(BR_QUOT) // shifted "
#define BR_CIRC LSFT(BR_TILD) // shifted ^ (dead key)
#define BR_GRAV LSFT(BR_ACUT) // shifted ` (dead key)
#define BR_LCBR LSFT(BR_LBRC) // shifted {
#define BR_RCBR LSFT(BR_RBRC) // shifted }
#define BR_PIPE LSFT(BR_BSLS) // shifted |
#define BR_QUES LSFT(BR_SLSH) // shifted ?
#define BR_TRMA LSFT(KC_6) // shifted ¨ (dead key - trema accent)
// On the ABNT2 the keypad comma and the keypad dot scancodes are switched
// (presumably because in Brazil comma is used as the decimal separator)
#define BR_KPDT KC_KP_COMMA // keypad .
#define BR_KPCM KC_KP_DOT // keypad ,
#define BR_1UP LALT(KC_1) // 1 superscript ¹ alt+1
#define BR_2UP LALT(KC_2) // 2 superscript ² alt+2
#define BR_3UP LALT(KC_3) // 3 superscript ³ alt+3
#define BR_PND LALT(KC_4) // Pound sign £ alt+4
#define BR_CENT LALT(KC_5) // Cent sign ¢ alt+5
#define BR_NOT LALT(KC_6) // Not sign ¬ alt+6
#define BR_SECT LALT(KC_EQL) // Section sign § alt+=
#define BR_FORD LALT(BR_LBRC) // Feminine Ordinal Sign ª alt+[
#define BR_MORD LALT(BR_RBRC) // Masculine Ordinal Sign º alt+]
#define BR_DGRE LALT(BR_SLSH) // Degree sign ° alt+/
#define BR_EURO LALT(KC_E) // Euro sign € alt+e
#define BR_NDTD LALT(BR_TILD) // Non-dead key tilde ~ alt+~
#define BR_NDAC LALT(BR_ACUT) // Non-dead key acute accent ´ alt+´
#define BR_NDGV LALT(BR_QUOT) // Non-dead key grave accent ` alt+'
#define BR_NDCR LALT(BR_CIRC) // Non-dead key circumflex accent ^ alt+^ (alt+shift+~)
#define BR_NDTR LALT(BR_TRMA) // Non-dead key trema accent ¨ alt+¨ (alt+shift+6)
// For 101-key keyboard layouts, the ABNT2 layout allows
// the slash and question mark to be typed using alt+q and alt+w.
// The shortcuts are provided here for completeness' sake,
// but it's recommended to use BR_SLSH and BR_QUES instead
#define BR_ASLS LALT(KC_Q)
#define BR_AQST LALT(KC_W)
#endif

@ -0,0 +1,82 @@
#ifndef KEYMAP_DVP_H
#define KEYMAP_DVP_H
#include "keymap.h"
// Normal characters
#define DP_DLR KC_GRV
#define DP_AMPR KC_1
#define DP_LBRC KC_2
#define DP_LCBR KC_3
#define DP_RCBR KC_4
#define DP_LPRN KC_5
#define DP_EQL KC_6
#define DP_ASTR KC_7
#define DP_RPRN KC_8
#define DP_PLUS KC_9
#define DP_RBRC KC_0
#define DP_EXLM KC_MINS
#define DP_HASH KC_EQL
#define DP_SCLN KC_Q
#define DP_COMM KC_W
#define DP_DOT KC_E
#define DP_P KC_R
#define DP_Y KC_T
#define DP_F KC_Y
#define DP_G KC_U
#define DP_C KC_I
#define DP_R KC_O
#define DP_L KC_P
#define DP_SLSH KC_LBRC
#define DP_AT KC_RBRC
#define DP_BSLS KC_BSLS
#define DP_A KC_A
#define DP_O KC_S
#define DP_E KC_D
#define DP_U KC_F
#define DP_I KC_G
#define DP_D KC_H
#define DP_H KC_J
#define DP_T KC_K
#define DP_N KC_L
#define DP_S KC_SCLN
#define DP_MINS KC_QUOT
#define DP_QUOT KC_Z
#define DP_Q KC_X
#define DP_J KC_C
#define DP_K KC_V
#define DP_X KC_B
#define DP_B KC_N
#define DP_M KC_M
#define DP_W KC_COMM
#define DP_V KC_DOT
#define DP_Z KC_SLSH
// Shifted characters
#define DP_TILD LSFT(DP_DLR)
#define DP_PERC LSFT(DP_AMPR)
#define DP_7 LSFT(DP_LBRC)
#define DP_5 LSFT(DP_LCBR)
#define DP_3 LSFT(DP_RCBR)
#define DP_1 LSFT(DP_LPRN)
#define DP_9 LSFT(DP_EQL)
#define DP_0 LSFT(DP_ASTR)
#define DP_2 LSFT(DP_RPRN)
#define DP_4 LSFT(DP_PLUS)
#define DP_6 LSFT(DP_RBRC)
#define DP_8 LSFT(DP_EXLM)
#define DP_GRV LSFT(DP_HASH)
#define DP_COLN LSFT(DP_SCLN)
#define DP_LABK LSFT(DP_COMM)
#define DP_RABK LSFT(DP_DOT)
#define DP_QUES LSFT(DP_SLSH)
#define DP_CIRC LSFT(DP_AT)
#define DP_PIPE LSFT(DP_BSLS)
#define DP_UNDS LSFT(DP_MINS)
#define DP_DQUO LSFT(DP_QUOT)
#endif

@ -0,0 +1,62 @@
/* JP106-layout (Japanese Standard)
*
* For more information, see
* http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html
* note: This website is written in Japanese.
*/
#ifndef KEYMAP_JP_H
#define KEYMAP_JP_H
#include "keymap.h"
#define JP_ZHTG KC_GRV // hankaku/zenkaku|kanzi
#define JP_YEN KC_INT3 // yen, |
#define JP_CIRC KC_EQL // ^, ~
#define JP_AT KC_LBRC // @, `
#define JP_LBRC KC_RBRC // [, {
#define JP_COLN KC_QUOT // :, *
#define JP_RBRC KC_NUHS // ], }
#define JP_BSLS KC_INT1 // \, _
#define JP_MHEN KC_INT5 // muhenkan
#define JP_HENK KC_INT4 // henkan
#define JP_KANA KC_INT2 // katakana/hiragana|ro-mazi
//Aliases for shifted symbols
#define JP_DQT LSFT(KC_2) // "
#define JP_AMPR LSFT(KC_6) // &
#define JP_QUOT LSFT(KC_7) // '
#define JP_LPRN LSFT(KC_8) // (
#define JP_RPRN LSFT(KC_9) // )
#define JP_EQL LSFT(KC_MINS) // =
#define JP_TILD LSFT(JP_CIRC) // ~
#define JP_PIPE LSFT(JP_YEN) // |
#define JP_GRV LSFT(JP_AT) // `
#define JP_LCBR LSFT(JP_LBRC) // {
#define JP_PLUS LSFT(KC_SCLN) // +
#define JP_ASTR LSFT(JP_COLN) // *
#define JP_RCBR LSFT(JP_RBRC) // }
#define JP_UNDS LSFT(JP_BSLS) // _
// These symbols are correspond to US101-layout.
#define JP_MINS KC_MINS // -
#define JP_SCLN KC_SCLN // ;
#define JP_COMM KC_COMM // ,
#define JP_DOT KC_DOT // .
#define JP_SLSH KC_SLSH // /
// shifted
#define JP_EXLM KC_EXLM // !
#define JP_HASH KC_HASH // #
#define JP_DLR KC_DLR // $
#define JP_PERC KC_PERC // %
#define JP_LT KC_LT // <
#define JP_GT KC_GT // >
#define JP_QUES KC_QUES // ?
#endif

@ -13,7 +13,7 @@
#define NO_ACUT KC_EQL
#define NO_AM KC_LBRC
#define NO_QUOT KC_RBRC
#define NO_QUOT KC_RBRC // this is the "umlaut" char on Nordic keyboards, Apple layout
#define NO_AE KC_SCLN
#define NO_OSLH KC_QUOT
#define NO_APOS KC_NUHS

@ -16,14 +16,128 @@
#include <util/delay.h>
#include "debug.h"
#ifdef RGBW_BB_TWI
// Port for the I2C
#define I2C_DDR DDRD
#define I2C_PIN PIND
#define I2C_PORT PORTD
// Pins to be used in the bit banging
#define I2C_CLK 0
#define I2C_DAT 1
#define I2C_DATA_HI()\
I2C_DDR &= ~ (1 << I2C_DAT);\
I2C_PORT |= (1 << I2C_DAT);
#define I2C_DATA_LO()\
I2C_DDR |= (1 << I2C_DAT);\
I2C_PORT &= ~ (1 << I2C_DAT);
#define I2C_CLOCK_HI()\
I2C_DDR &= ~ (1 << I2C_CLK);\
I2C_PORT |= (1 << I2C_CLK);
#define I2C_CLOCK_LO()\
I2C_DDR |= (1 << I2C_CLK);\
I2C_PORT &= ~ (1 << I2C_CLK);
#define I2C_DELAY 1
void I2C_WriteBit(unsigned char c)
{
if (c > 0)
{
I2C_DATA_HI();
}
else
{
I2C_DATA_LO();
}
I2C_CLOCK_HI();
_delay_us(I2C_DELAY);
I2C_CLOCK_LO();
_delay_us(I2C_DELAY);
if (c > 0)
{
I2C_DATA_LO();
}
_delay_us(I2C_DELAY);
}
// Inits bitbanging port, must be called before using the functions below
//
void I2C_Init()
{
I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
I2C_CLOCK_HI();
I2C_DATA_HI();
_delay_us(I2C_DELAY);
}
// Send a START Condition
//
void I2C_Start()
{
// set both to high at the same time
I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK));
_delay_us(I2C_DELAY);
I2C_DATA_LO();
_delay_us(I2C_DELAY);
I2C_CLOCK_LO();
_delay_us(I2C_DELAY);
}
// Send a STOP Condition
//
void I2C_Stop()
{
I2C_CLOCK_HI();
_delay_us(I2C_DELAY);
I2C_DATA_HI();
_delay_us(I2C_DELAY);
}
// write a byte to the I2C slave device
//
unsigned char I2C_Write(unsigned char c)
{
for (char i = 0; i < 8; i++)
{
I2C_WriteBit(c & 128);
c <<= 1;
}
I2C_WriteBit(0);
_delay_us(I2C_DELAY);
_delay_us(I2C_DELAY);
// _delay_us(I2C_DELAY);
//return I2C_ReadBit();
return 0;
}
#endif
// Setleds for standard RGB
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds)
void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
{
// ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin));
ws2812_setleds_pin(ledarray,leds, _BV(RGB_DI_PIN & 0xF));
}
void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask)
void inline ws2812_setleds_pin(LED_TYPE *ledarray, uint16_t leds, uint8_t pinmask)
{
// ws2812_DDRREG |= pinmask; // Enable DDR
// new universal format (DDR)
@ -34,14 +148,41 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin
}
// Setleds for SK6812RGBW
void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
void inline ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t leds)
{
#ifdef RGBW_BB_TWI
uint8_t sreg_prev, twcr_prev;
sreg_prev=SREG;
twcr_prev=TWCR;
cli();
TWCR &= ~(1<<TWEN);
I2C_Init();
I2C_Start();
I2C_Write(0x84);
uint16_t datlen = leds<<2;
uint8_t curbyte;
uint8_t * data = (uint8_t*)ledarray;
while (datlen--) {
curbyte=*data++;
I2C_Write(curbyte);
}
I2C_Stop();
SREG=sreg_prev;
TWCR=twcr_prev;
#endif
// ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
// new universal format (DDR)
_SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
_delay_us(80);
#ifndef RGBW_BB_TWI
_delay_us(80);
#endif
}
void ws2812_sendarray(uint8_t *data,uint16_t datlen)
@ -123,7 +264,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
cli();
while (datlen--) {
curbyte=*data++;
curbyte=(*data++);
asm volatile(
" ldi %0,8 \n\t"

@ -16,6 +16,14 @@
#include <avr/io.h>
#include <avr/interrupt.h>
//#include "ws2812_config.h"
//#include "i2cmaster.h"
#ifdef RGBW
#define LED_TYPE struct cRGBW
#else
#define LED_TYPE struct cRGB
#endif
/*
* Structure of the LED array
@ -42,9 +50,9 @@ struct cRGBW { uint8_t g; uint8_t r; uint8_t b; uint8_t w;};
* - Wait 50<EFBFBD>s to reset the LEDs
*/
void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds);
void ws2812_setleds_pin (struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask);
void ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t number_of_leds);
void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds);
void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask);
void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
/*
* Old interface / Internal functions

@ -25,37 +25,65 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "timer.h"
/* Set 0 if debouncing isn't needed */
#ifndef DEBOUNCING_DELAY
# define DEBOUNCING_DELAY 5
#endif
static uint8_t debouncing = DEBOUNCING_DELAY;
#if (DEBOUNCING_DELAY > 0)
static uint16_t debouncing_time;
static bool debouncing = false;
#endif
#if (MATRIX_COLS <= 8)
# define print_matrix_header() print("\nr/c 01234567\n")
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
# define matrix_bitpop(i) bitpop(matrix[i])
# define ROW_SHIFTER ((uint8_t)1)
#elif (MATRIX_COLS <= 16)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
# define matrix_bitpop(i) bitpop16(matrix[i])
# define ROW_SHIFTER ((uint16_t)1)
#elif (MATRIX_COLS <= 32)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
# define matrix_bitpop(i) bitpop32(matrix[i])
# define ROW_SHIFTER ((uint32_t)1)
#endif
#ifdef MATRIX_MASKED
extern const matrix_row_t matrix_mask[];
#endif
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_raw[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
#if DIODE_DIRECTION == ROW2COL
static matrix_row_t matrix_reversed[MATRIX_COLS];
static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS];
#endif
#if MATRIX_COLS > 16
#define SHIFTER 1UL
#else
#define SHIFTER 1
#if (DIODE_DIRECTION == COL2ROW)
static void init_cols(void);
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
static void unselect_rows(void);
static void select_row(uint8_t row);
static void unselect_row(uint8_t row);
#else // ROW2COL
static void init_rows(void);
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
static void unselect_cols(void);
static void unselect_col(uint8_t col);
static void select_col(uint8_t col);
#endif
static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);
__attribute__ ((weak))
void matrix_init_quantum(void) {
matrix_init_kb();
@ -95,7 +123,7 @@ uint8_t matrix_cols(void) {
}
// void matrix_power_up(void) {
// #if DIODE_DIRECTION == COL2ROW
// #if (DIODE_DIRECTION == COL2ROW)
// for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
// /* DDRxn */
// _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
@ -119,19 +147,26 @@ uint8_t matrix_cols(void) {
// }
void matrix_init(void) {
// To use PORTF disable JTAG with writing JTD bit twice within four cycles.
#ifdef __AVR_ATmega32U4__
#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
MCUCR |= _BV(JTD);
MCUCR |= _BV(JTD);
#endif
// initialize row and col
#if (DIODE_DIRECTION == COL2ROW)
unselect_rows();
init_cols();
#else // ROW2COL
unselect_cols();
init_rows();
#endif
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_raw[i] = 0;
matrix_debouncing[i] = 0;
}
@ -141,71 +176,60 @@ void matrix_init(void) {
uint8_t matrix_scan(void)
{
#if DIODE_DIRECTION == COL2ROW
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
select_row(i);
wait_us(30); // without this wait read unstable value.
matrix_row_t cols = read_cols();
if (matrix_debouncing[i] != cols) {
matrix_debouncing[i] = cols;
if (debouncing) {
debug("bounce!: "); debug_hex(debouncing); debug("\n");
}
debouncing = DEBOUNCING_DELAY;
}
unselect_rows();
}
#if (DIODE_DIRECTION == COL2ROW)
if (debouncing) {
if (--debouncing) {
wait_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
// Set row, read cols
for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
# if (DEBOUNCING_DELAY > 0)
bool matrix_changed = read_cols_on_row(matrix_debouncing, current_row);
if (matrix_changed) {
debouncing = true;
debouncing_time = timer_read();
}
}
# else
read_cols_on_row(matrix, current_row);
# endif
}
#else
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
select_row(i);
wait_us(30); // without this wait read unstable value.
matrix_row_t rows = read_cols();
if (matrix_reversed_debouncing[i] != rows) {
matrix_reversed_debouncing[i] = rows;
if (debouncing) {
debug("bounce!: "); debug_hex(debouncing); debug("\n");
#else // ROW2COL
// Set col, read rows
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
# if (DEBOUNCING_DELAY > 0)
bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
if (matrix_changed) {
debouncing = true;
debouncing_time = timer_read();
}
debouncing = DEBOUNCING_DELAY;
}
unselect_rows();
# else
read_rows_on_col(matrix, current_col);
# endif
}
if (debouncing) {
if (--debouncing) {
wait_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
matrix_reversed[i] = matrix_reversed_debouncing[i];
#endif
# if (DEBOUNCING_DELAY > 0)
if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
debouncing = false;
}
}
for (uint8_t y = 0; y < MATRIX_ROWS; y++) {
matrix_row_t row = 0;
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
row |= ((matrix_reversed[x] & (1<<y)) >> y) << x;
}
matrix[y] = row;
}
#endif
# endif
matrix_scan_quantum();
return 1;
}
bool matrix_is_modified(void)
{
#if (DEBOUNCING_DELAY > 0)
if (debouncing) return false;
#endif
return true;
}
@ -218,15 +242,22 @@ bool matrix_is_on(uint8_t row, uint8_t col)
inline
matrix_row_t matrix_get_row(uint8_t row)
{
// Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
// switch blocker installed and the switch is always pressed.
#ifdef MATRIX_MASKED
return matrix[row] & matrix_mask[row];
#else
return matrix[row];
#endif
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
print_matrix_header();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print_matrix_row(row);
print("\n");
}
}
@ -235,63 +266,148 @@ uint8_t matrix_key_count(void)
{
uint8_t count = 0;
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
count += bitpop16(matrix[i]);
count += matrix_bitpop(i);
}
return count;
}
#if (DIODE_DIRECTION == COL2ROW)
static void init_cols(void)
{
#if DIODE_DIRECTION == COL2ROW
for(int x = 0; x < MATRIX_COLS; x++) {
int pin = col_pins[x];
#else
for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#endif
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
uint8_t pin = col_pins[x];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
}
static matrix_row_t read_cols(void)
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
{
matrix_row_t result = 0;
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[current_row];
#if DIODE_DIRECTION == COL2ROW
for(int x = 0; x < MATRIX_COLS; x++) {
int pin = col_pins[x];
#else
for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#endif
result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x);
// Clear data in matrix row
current_matrix[current_row] = 0;
// Select row and wait for row selecton to stabilize
select_row(current_row);
wait_us(30);
// For each col...
for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
// Select the col pin to read (active low)
uint8_t pin = col_pins[col_index];
uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
// Populate the matrix row with the state of the col pin
current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
}
return result;
// Unselect row
unselect_row(current_row);
return (last_row_value != current_matrix[current_row]);
}
static void select_row(uint8_t row)
{
uint8_t pin = row_pins[row];
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
}
static void unselect_row(uint8_t row)
{
uint8_t pin = row_pins[row];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
static void unselect_rows(void)
{
#if DIODE_DIRECTION == COL2ROW
for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#else
for(int x = 0; x < MATRIX_COLS; x++) {
int pin = col_pins[x];
#endif
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
uint8_t pin = row_pins[x];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
}
static void select_row(uint8_t row)
#else // ROW2COL
static void init_rows(void)
{
for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
uint8_t pin = row_pins[x];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
}
#if DIODE_DIRECTION == COL2ROW
int pin = row_pins[row];
#else
int pin = col_pins[row];
#endif
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF);
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF);
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
{
bool matrix_changed = false;
// Select col and wait for col selecton to stabilize
select_col(current_col);
wait_us(30);
// For each row...
for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
{
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[row_index];
// Check row pin state
if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
{
// Pin LO, set col bit
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
}
else
{
// Pin HI, clear col bit
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
}
// Determine if the matrix changed state
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
{
matrix_changed = true;
}
}
// Unselect col
unselect_col(current_col);
return matrix_changed;
}
static void select_col(uint8_t col)
{
uint8_t pin = col_pins[col];
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
}
static void unselect_col(uint8_t col)
{
uint8_t pin = col_pins[col];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
static void unselect_cols(void)
{
for(uint8_t x = 0; x < MATRIX_COLS; x++) {
uint8_t pin = col_pins[x];
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI
}
}
#endif

@ -0,0 +1,37 @@
#pragma once
// Some helpers for controlling gpio pins
#include <avr/io.h>
enum {
PinDirectionInput = 0,
PinDirectionOutput = 1,
PinLevelHigh = 1,
PinLevelLow = 0,
};
// ex: pinMode(B0, PinDirectionOutput);
static inline void pinMode(uint8_t pin, int mode) {
uint8_t bv = _BV(pin & 0xf);
if (mode == PinDirectionOutput) {
_SFR_IO8((pin >> 4) + 1) |= bv;
} else {
_SFR_IO8((pin >> 4) + 1) &= ~bv;
_SFR_IO8((pin >> 4) + 2) &= ~bv;
}
}
// ex: digitalWrite(B0, PinLevelHigh);
static inline void digitalWrite(uint8_t pin, int mode) {
uint8_t bv = _BV(pin & 0xf);
if (mode == PinLevelHigh) {
_SFR_IO8((pin >> 4) + 2) |= bv;
} else {
_SFR_IO8((pin >> 4) + 2) &= ~bv;
}
}
// Return true if the pin is HIGH
// digitalRead(B0)
static inline bool digitalRead(uint8_t pin) {
return _SFR_IO8(pin >> 4) & _BV(pin & 0xf);
}

@ -1,8 +1,8 @@
#include "process_music.h"
bool music_activated = false;
uint8_t starting_note = 0x0C;
int offset = 7;
uint8_t music_starting_note = 0x0C;
int music_offset = 7;
// music sequencer
static bool music_sequence_recording = false;
@ -115,7 +115,16 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
return false;
}
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row));
#ifdef MUSIC_MODE_CHROMATIC
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(MATRIX_ROWS - record->event.key.row));
#elif defined(MUSIC_MODE_GUITAR)
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 7)*5.0/12);
#elif defined(MUSIC_MODE_VIOLIN)
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 5)*7.0/12);
#else
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + SCALE[record->event.key.col + music_offset])/12.0+(MATRIX_ROWS - record->event.key.row));
#endif
if (record->event.pressed) {
play_note(freq, 0xF);
if (music_sequence_recording) {

@ -0,0 +1,254 @@
#include "process_printer.h"
#include "action_util.h"
bool printing_enabled = false;
uint8_t character_shift = 0;
void enabled_printing() {
printing_enabled = true;
serial_init();
}
void disable_printing() {
printing_enabled = false;
}
uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29};
// uint8_t keycode_to_ascii[0xFF][2];
// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
void print_char(char c) {
USB_Disable();
serial_send(c);
USB_Init();
}
void print_box_string(uint8_t text[]) {
uint8_t len = strlen(text);
uint8_t out[len * 3 + 8];
out[0] = 0xDA;
for (uint8_t i = 0; i < len; i++) {
out[i+1] = 0xC4;
}
out[len + 1] = 0xBF;
out[len + 2] = '\n';
out[len + 3] = 0xB3;
for (uint8_t i = 0; i < len; i++) {
out[len + 4 + i] = text[i];
}
out[len * 2 + 4] = 0xB3;
out[len * 2 + 5] = '\n';
out[len * 2 + 6] = 0xC0;
for (uint8_t i = 0; i < len; i++) {
out[len * 2 + 7 + i] = 0xC4;
}
out[len * 3 + 7] = 0xD9;
out[len * 3 + 8] = '\n';
print_string(out);
}
void print_string(char c[]) {
for(uint8_t i = 0; i < strlen(c); i++)
print_char(c[i]);
}
bool process_printer(uint16_t keycode, keyrecord_t *record) {
if (keycode == PRINT_ON) {
enabled_printing();
return false;
}
if (keycode == PRINT_OFF) {
disable_printing();
return false;
}
if (printing_enabled) {
switch(keycode) {
case KC_EXLM ... KC_RPRN:
case KC_UNDS:
case KC_PLUS:
case KC_LCBR:
case KC_RCBR:
case KC_PIPE:
case KC_TILD:
keycode &= 0xFF;
case KC_LSFT:
case KC_RSFT:
if (record->event.pressed) {
character_shift++;
} else {
character_shift--;
}
return false;
break;
}
switch(keycode) {
case KC_F1:
if (record->event.pressed) {
print_box_string("This is a line of text!");
}
return false;
case KC_ESC:
if (record->event.pressed) {
print_char(0x1B);
}
return false;
break;
case KC_SPC:
if (record->event.pressed) {
print_char(0x20);
}
return false;
break;
case KC_A ... KC_Z:
if (record->event.pressed) {
if (character_shift) {
print_char(0x41 + (keycode - KC_A));
} else {
print_char(0x61 + (keycode - KC_A));
}
}
return false;
break;
case KC_1 ... KC_0:
if (record->event.pressed) {
if (character_shift) {
print_char(shifted_numbers[keycode - KC_1]);
} else {
print_char(0x30 + ((keycode - KC_1 + 1) % 10));
}
}
return false;
break;
case KC_ENT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x0C);
} else {
print_char(0x0A);
}
}
return false;
break;
case KC_BSPC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x18);
} else {
print_char(0x1A);
}
}
return false;
break;
case KC_DOT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3E);
} else {
print_char(0x2E);
}
}
return false;
break;
case KC_COMM:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3C);
} else {
print_char(0x2C);
}
}
return false;
break;
case KC_SLSH:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3F);
} else {
print_char(0x2F);
}
}
return false;
break;
case KC_QUOT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x22);
} else {
print_char(0x27);
}
}
return false;
break;
case KC_GRV:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7E);
} else {
print_char(0x60);
}
}
return false;
break;
case KC_MINS:
if (record->event.pressed) {
if (character_shift) {
print_char(0x5F);
} else {
print_char(0x2D);
}
}
return false;
break;
case KC_EQL:
if (record->event.pressed) {
if (character_shift) {
print_char(0x2B);
} else {
print_char(0x3D);
}
}
return false;
break;
case KC_LBRC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7B);
} else {
print_char(0x5B);
}
}
return false;
break;
case KC_RBRC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7D);
} else {
print_char(0x5D);
}
}
return false;
break;
case KC_BSLS:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7C);
} else {
print_char(0x5C);
}
}
return false;
break;
}
}
return true;
}

@ -0,0 +1,8 @@
#ifndef PROCESS_PRINTER_H
#define PROCESS_PRINTER_H
#include "quantum.h"
#include "protocol/serial.h"
#endif

@ -0,0 +1,260 @@
#include "process_printer.h"
#include "action_util.h"
bool printing_enabled = false;
uint8_t character_shift = 0;
#define SERIAL_PIN_DDR DDRD
#define SERIAL_PIN_PORT PORTD
#define SERIAL_PIN_MASK _BV(PD3)
#define SERIAL_DELAY 52
inline static
void serial_delay(void) {
_delay_us(SERIAL_DELAY);
}
inline static
void serial_high(void) {
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
}
inline static
void serial_low(void) {
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
}
inline static
void serial_output(void) {
SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
}
void enabled_printing() {
printing_enabled = true;
serial_output();
serial_high();
}
void disable_printing() {
printing_enabled = false;
}
uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29};
// uint8_t keycode_to_ascii[0xFF][2];
// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F};
void print_char(char c) {
uint8_t b = 8;
serial_output();
while( b-- ) {
if(c & (1 << b)) {
serial_high();
} else {
serial_low();
}
serial_delay();
}
}
void print_string(char c[]) {
for(uint8_t i = 0; i < strlen(c); i++)
print_char(c[i]);
}
bool process_printer(uint16_t keycode, keyrecord_t *record) {
if (keycode == PRINT_ON) {
enabled_printing();
return false;
}
if (keycode == PRINT_OFF) {
disable_printing();
return false;
}
if (printing_enabled) {
switch(keycode) {
case KC_EXLM ... KC_RPRN:
case KC_UNDS:
case KC_PLUS:
case KC_LCBR:
case KC_RCBR:
case KC_PIPE:
case KC_TILD:
keycode &= 0xFF;
case KC_LSFT:
case KC_RSFT:
if (record->event.pressed) {
character_shift++;
} else {
character_shift--;
}
return false;
break;
}
switch(keycode) {
case KC_F1:
if (record->event.pressed) {
print_string("This is a line of text!\n\n\n");
}
return false;
case KC_ESC:
if (record->event.pressed) {
print_char(0x1B);
}
return false;
break;
case KC_SPC:
if (record->event.pressed) {
print_char(0x20);
}
return false;
break;
case KC_A ... KC_Z:
if (record->event.pressed) {
if (character_shift) {
print_char(0x41 + (keycode - KC_A));
} else {
print_char(0x61 + (keycode - KC_A));
}
}
return false;
break;
case KC_1 ... KC_0:
if (record->event.pressed) {
if (character_shift) {
print_char(shifted_numbers[keycode - KC_1]);
} else {
print_char(0x30 + ((keycode - KC_1 + 1) % 10));
}
}
return false;
break;
case KC_ENT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x0C);
} else {
print_char(0x0A);
}
}
return false;
break;
case KC_BSPC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x18);
} else {
print_char(0x1A);
}
}
return false;
break;
case KC_DOT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3E);
} else {
print_char(0x2E);
}
}
return false;
break;
case KC_COMM:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3C);
} else {
print_char(0x2C);
}
}
return false;
break;
case KC_SLSH:
if (record->event.pressed) {
if (character_shift) {
print_char(0x3F);
} else {
print_char(0x2F);
}
}
return false;
break;
case KC_QUOT:
if (record->event.pressed) {
if (character_shift) {
print_char(0x22);
} else {
print_char(0x27);
}
}
return false;
break;
case KC_GRV:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7E);
} else {
print_char(0x60);
}
}
return false;
break;
case KC_MINS:
if (record->event.pressed) {
if (character_shift) {
print_char(0x5F);
} else {
print_char(0x2D);
}
}
return false;
break;
case KC_EQL:
if (record->event.pressed) {
if (character_shift) {
print_char(0x2B);
} else {
print_char(0x3D);
}
}
return false;
break;
case KC_LBRC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7B);
} else {
print_char(0x5B);
}
}
return false;
break;
case KC_RBRC:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7D);
} else {
print_char(0x5D);
}
}
return false;
break;
case KC_BSLS:
if (record->event.pressed) {
if (character_shift) {
print_char(0x7C);
} else {
print_char(0x5C);
}
}
return false;
break;
}
}
return true;
}

@ -42,6 +42,11 @@ void unicode_input_start (void) {
register_code(KC_PPLS);
unregister_code(KC_PPLS);
break;
case UC_WINC:
register_code(KC_RALT);
unregister_code(KC_RALT);
register_code(KC_U);
unregister_code(KC_U);
}
wait_ms(UNICODE_TYPE_DELAY);
}
@ -78,6 +83,52 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
return true;
}
#ifdef UNICODEMAP_ENABLE
__attribute__((weak))
const uint32_t PROGMEM unicode_map[] = {
};
void register_hex32(uint32_t hex) {
uint8_t onzerostart = 1;
for(int i = 7; i >= 0; i--) {
if (i <= 3) {
onzerostart = 0;
}
uint8_t digit = ((hex >> (i*4)) & 0xF);
if (digit == 0) {
if (onzerostart == 0) {
register_code(hex_to_keycode(digit));
unregister_code(hex_to_keycode(digit));
}
} else {
register_code(hex_to_keycode(digit));
unregister_code(hex_to_keycode(digit));
onzerostart = 0;
}
}
}
__attribute__((weak))
void unicode_map_input_error() {}
bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
const uint32_t* map = unicode_map;
uint16_t index = keycode & 0x7FF;
uint32_t code = pgm_read_dword_far(&map[index]);
if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
// when character is out of range supported by the OS
unicode_map_input_error();
} else {
unicode_input_start();
register_hex32(code);
unicode_input_finish();
}
}
return true;
}
#endif
#ifdef UCIS_ENABLE
qk_ucis_state_t qk_ucis_state;

@ -3,10 +3,11 @@
#include "quantum.h"
#define UC_OSX 0
#define UC_LNX 1
#define UC_WIN 2
#define UC_BSD 3
#define UC_OSX 0 // Mac OS X
#define UC_LNX 1 // Linux
#define UC_WIN 2 // Windows 'HexNumpad'
#define UC_BSD 3 // BSD (not implemented)
#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
#ifndef UNICODE_TYPE_DELAY
#define UNICODE_TYPE_DELAY 10
@ -20,6 +21,11 @@ void register_hex(uint16_t hex);
bool process_unicode(uint16_t keycode, keyrecord_t *record);
#ifdef UNICODEMAP_ENABLE
void unicode_map_input_error(void);
bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
#endif
#ifdef UCIS_ENABLE
#ifndef UCIS_MAX_SYMBOL_LENGTH
#define UCIS_MAX_SYMBOL_LENGTH 32

@ -1,5 +1,9 @@
#include "quantum.h"
#ifndef TAPPING_TERM
#define TAPPING_TERM 200
#endif
static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
switch (code) {
case QK_MODS ... QK_MODS_MAX:
@ -17,6 +21,8 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
if (code & QK_LGUI)
f(KC_LGUI);
if (code < QK_RMODS_MIN) return;
if (code & QK_RCTL)
f(KC_RCTL);
if (code & QK_RSFT)
@ -75,6 +81,7 @@ void reset_keyboard(void) {
#endif
static bool shift_interrupted[2] = {0, 0};
static uint16_t scs_timer = 0;
bool process_record_quantum(keyrecord_t *record) {
@ -128,6 +135,12 @@ bool process_record_quantum(keyrecord_t *record) {
#endif
#ifdef UCIS_ENABLE
process_ucis(keycode, record) &&
#endif
#ifdef PRINTING_ENABLE
process_printer(keycode, record) &&
#endif
#ifdef UNICODEMAP_ENABLE
process_unicode_map(keycode, record) &&
#endif
true)) {
return false;
@ -280,6 +293,7 @@ bool process_record_quantum(keyrecord_t *record) {
case KC_LSPO: {
if (record->event.pressed) {
shift_interrupted[0] = false;
scs_timer = timer_read ();
register_mods(MOD_BIT(KC_LSFT));
}
else {
@ -289,7 +303,7 @@ bool process_record_quantum(keyrecord_t *record) {
shift_interrupted[1] = true;
}
#endif
if (!shift_interrupted[0]) {
if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) {
register_code(LSPO_KEY);
unregister_code(LSPO_KEY);
}
@ -302,6 +316,7 @@ bool process_record_quantum(keyrecord_t *record) {
case KC_RSPC: {
if (record->event.pressed) {
shift_interrupted[1] = false;
scs_timer = timer_read ();
register_mods(MOD_BIT(KC_RSFT));
}
else {
@ -311,7 +326,7 @@ bool process_record_quantum(keyrecord_t *record) {
shift_interrupted[1] = true;
}
#endif
if (!shift_interrupted[1]) {
if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) {
register_code(RSPC_KEY);
unregister_code(RSPC_KEY);
}
@ -796,6 +811,51 @@ void backlight_set(uint8_t level)
#endif // backlight
// Functions for spitting out values
//
void send_dword(uint32_t number) { // this might not actually work
uint16_t word = (number >> 16);
send_word(word);
send_word(number & 0xFFFFUL);
}
void send_word(uint16_t number) {
uint8_t byte = number >> 8;
send_byte(byte);
send_byte(number & 0xFF);
}
void send_byte(uint8_t number) {
uint8_t nibble = number >> 4;
send_nibble(nibble);
send_nibble(number & 0xF);
}
void send_nibble(uint8_t number) {
switch (number) {
case 0:
register_code(KC_0);
unregister_code(KC_0);
break;
case 1 ... 9:
register_code(KC_1 + (number - 1));
unregister_code(KC_1 + (number - 1));
break;
case 0xA ... 0xF:
register_code(KC_A + (number - 0xA));
unregister_code(KC_A + (number - 0xA));
break;
}
}
void api_send_unicode(uint32_t unicode) {
#ifdef API_ENABLE
uint8_t chunk[4];
dword_to_bytes(unicode, chunk);
MT_SEND_DATA(DT_UNICODE, chunk, 5);
#endif
}
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {

@ -59,6 +59,10 @@ extern uint32_t default_layer_state;
#include "process_tap_dance.h"
#ifdef PRINTING_ENABLE
#include "process_printer.h"
#endif
#define SEND_STRING(str) send_string(PSTR(str))
void send_string(const char *str);
@ -106,8 +110,15 @@ void breathing_speed_dec(uint8_t value);
#endif
#endif
void send_dword(uint32_t number);
void send_word(uint16_t number);
void send_byte(uint8_t number);
void send_nibble(uint8_t number);
void led_set_user(uint8_t usb_led);
void led_set_kb(uint8_t usb_led);
void api_send_unicode(uint32_t unicode);
#endif

@ -0,0 +1,313 @@
#ifndef QUANTUM_KEYCODES_H
#define QUANTUM_KEYCODES_H
enum quantum_keycodes {
// Ranges used in shortucuts - not to be used directly
QK_TMK = 0x0000,
QK_TMK_MAX = 0x00FF,
QK_MODS = 0x0100,
QK_LCTL = 0x0100,
QK_LSFT = 0x0200,
QK_LALT = 0x0400,
QK_LGUI = 0x0800,
QK_RMODS_MIN = 0x1000,
QK_RCTL = 0x1100,
QK_RSFT = 0x1200,
QK_RALT = 0x1400,
QK_RGUI = 0x1800,
QK_MODS_MAX = 0x1FFF,
QK_FUNCTION = 0x2000,
QK_FUNCTION_MAX = 0x2FFF,
QK_MACRO = 0x3000,
QK_MACRO_MAX = 0x3FFF,
QK_LAYER_TAP = 0x4000,
QK_LAYER_TAP_MAX = 0x4FFF,
QK_TO = 0x5000,
QK_TO_MAX = 0x50FF,
QK_MOMENTARY = 0x5100,
QK_MOMENTARY_MAX = 0x51FF,
QK_DEF_LAYER = 0x5200,
QK_DEF_LAYER_MAX = 0x52FF,
QK_TOGGLE_LAYER = 0x5300,
QK_TOGGLE_LAYER_MAX = 0x53FF,
QK_ONE_SHOT_LAYER = 0x5400,
QK_ONE_SHOT_LAYER_MAX = 0x54FF,
QK_ONE_SHOT_MOD = 0x5500,
QK_ONE_SHOT_MOD_MAX = 0x55FF,
#ifndef DISABLE_CHORDING
QK_CHORDING = 0x5600,
QK_CHORDING_MAX = 0x56FF,
#endif
QK_MOD_TAP = 0x6000,
QK_MOD_TAP_MAX = 0x6FFF,
QK_TAP_DANCE = 0x7100,
QK_TAP_DANCE_MAX = 0x71FF,
#ifdef UNICODEMAP_ENABLE
QK_UNICODE_MAP = 0x7800,
QK_UNICODE_MAP_MAX = 0x7FFF,
#endif
#ifdef UNICODE_ENABLE
QK_UNICODE = 0x8000,
QK_UNICODE_MAX = 0xFFFF,
#endif
// Loose keycodes - to be used directly
RESET = 0x7000,
DEBUG,
MAGIC_SWAP_CONTROL_CAPSLOCK,
MAGIC_CAPSLOCK_TO_CONTROL,
MAGIC_SWAP_LALT_LGUI,
MAGIC_SWAP_RALT_RGUI,
MAGIC_NO_GUI,
MAGIC_SWAP_GRAVE_ESC,
MAGIC_SWAP_BACKSLASH_BACKSPACE,
MAGIC_HOST_NKRO,
MAGIC_SWAP_ALT_GUI,
MAGIC_UNSWAP_CONTROL_CAPSLOCK,
MAGIC_UNCAPSLOCK_TO_CONTROL,
MAGIC_UNSWAP_LALT_LGUI,
MAGIC_UNSWAP_RALT_RGUI,
MAGIC_UNNO_GUI,
MAGIC_UNSWAP_GRAVE_ESC,
MAGIC_UNSWAP_BACKSLASH_BACKSPACE,
MAGIC_UNHOST_NKRO,
MAGIC_UNSWAP_ALT_GUI,
MAGIC_TOGGLE_NKRO,
// Leader key
#ifndef DISABLE_LEADER
KC_LEAD,
#endif
// Audio on/off/toggle
AU_ON,
AU_OFF,
AU_TOG,
// Music mode on/off/toggle
MU_ON,
MU_OFF,
MU_TOG,
// Music voice iterate
MUV_IN,
MUV_DE,
// Midi mode on/off
MIDI_ON,
MIDI_OFF,
// Backlight functionality
BL_0,
BL_1,
BL_2,
BL_3,
BL_4,
BL_5,
BL_6,
BL_7,
BL_8,
BL_9,
BL_10,
BL_11,
BL_12,
BL_13,
BL_14,
BL_15,
BL_DEC,
BL_INC,
BL_TOGG,
BL_STEP,
// RGB functionality
RGB_TOG,
RGB_MOD,
RGB_HUI,
RGB_HUD,
RGB_SAI,
RGB_SAD,
RGB_VAI,
RGB_VAD,
// Left shift, open paren
KC_LSPO,
// Right shift, close paren
KC_RSPC,
// Printing
PRINT_ON,
PRINT_OFF,
// always leave at the end
SAFE_RANGE
};
// Ability to use mods in layouts
#define LCTL(kc) (kc | QK_LCTL)
#define LSFT(kc) (kc | QK_LSFT)
#define LALT(kc) (kc | QK_LALT)
#define LGUI(kc) (kc | QK_LGUI)
#define RCTL(kc) (kc | QK_RCTL)
#define RSFT(kc) (kc | QK_RSFT)
#define RALT(kc) (kc | QK_RALT)
#define RGUI(kc) (kc | QK_RGUI)
#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI)
#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT)
#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI)
#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
#define MOD_HYPR 0xf
#define MOD_MEH 0x7
// Aliases for shifted symbols
// Each key has a 4-letter code, and some have longer aliases too.
// While the long aliases are descriptive, the 4-letter codes
// make for nicer grid layouts (everything lines up), and are
// the preferred style for Quantum.
#define KC_TILD LSFT(KC_GRV) // ~
#define KC_TILDE KC_TILD
#define KC_EXLM LSFT(KC_1) // !
#define KC_EXCLAIM KC_EXLM
#define KC_AT LSFT(KC_2) // @
#define KC_HASH LSFT(KC_3) // #
#define KC_DLR LSFT(KC_4) // $
#define KC_DOLLAR KC_DLR
#define KC_PERC LSFT(KC_5) // %
#define KC_PERCENT KC_PERC
#define KC_CIRC LSFT(KC_6) // ^
#define KC_CIRCUMFLEX KC_CIRC
#define KC_AMPR LSFT(KC_7) // &
#define KC_AMPERSAND KC_AMPR
#define KC_ASTR LSFT(KC_8) // *
#define KC_ASTERISK KC_ASTR
#define KC_LPRN LSFT(KC_9) // (
#define KC_LEFT_PAREN KC_LPRN
#define KC_RPRN LSFT(KC_0) // )
#define KC_RIGHT_PAREN KC_RPRN
#define KC_UNDS LSFT(KC_MINS) // _
#define KC_UNDERSCORE KC_UNDS
#define KC_PLUS LSFT(KC_EQL) // +
#define KC_LCBR LSFT(KC_LBRC) // {
#define KC_LEFT_CURLY_BRACE KC_LCBR
#define KC_RCBR LSFT(KC_RBRC) // }
#define KC_RIGHT_CURLY_BRACE KC_RCBR
#define KC_LABK LSFT(KC_COMM) // <
#define KC_LEFT_ANGLE_BRACKET KC_LABK
#define KC_RABK LSFT(KC_DOT) // >
#define KC_RIGHT_ANGLE_BRACKET KC_RABK
#define KC_COLN LSFT(KC_SCLN) // :
#define KC_COLON KC_COLN
#define KC_PIPE LSFT(KC_BSLS) // |
#define KC_LT LSFT(KC_COMM) // <
#define KC_GT LSFT(KC_DOT) // >
#define KC_QUES LSFT(KC_SLSH) // ?
#define KC_QUESTION KC_QUES
#define KC_DQT LSFT(KC_QUOT) // "
#define KC_DOUBLE_QUOTE KC_DQT
#define KC_DQUO KC_DQT
#define KC_DELT KC_DELETE // Del key (four letter code)
// Alias for function layers than expand past FN31
#define FUNC(kc) (kc | QK_FUNCTION)
// Aliases
#define S(kc) LSFT(kc)
#define F(kc) FUNC(kc)
#define M(kc) (kc | QK_MACRO)
#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
// L-ayer, T-ap - 256 keycode max, 16 layer max
#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8))
#define AG_SWAP MAGIC_SWAP_ALT_GUI
#define AG_NORM MAGIC_UNSWAP_ALT_GUI
#define BL_ON BL_9
#define BL_OFF BL_0
#define MI_ON MIDI_ON
#define MI_OFF MIDI_OFF
// GOTO layer - 16 layers max
// when:
// ON_PRESS = 1
// ON_RELEASE = 2
// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
// keycode modeled after the old version, kept below for this.
/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */
#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4))
// Momentary switch layer - 256 layer max
#define MO(layer) (layer | QK_MOMENTARY)
// Set default layer - 256 layer max
#define DF(layer) (layer | QK_DEF_LAYER)
// Toggle to layer - 256 layer max
#define TG(layer) (layer | QK_TOGGLE_LAYER)
// One-shot layer - 256 layer max
#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
// One-shot mod
#define OSM(mod) (mod | QK_ONE_SHOT_MOD)
// M-od, T-ap - 256 keycode max
#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8))
#define CTL_T(kc) MT(MOD_LCTL, kc)
#define SFT_T(kc) MT(MOD_LSFT, kc)
#define ALT_T(kc) MT(MOD_LALT, kc)
#define GUI_T(kc) MT(MOD_LGUI, kc)
#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal
#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl
#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui
#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
#define KC_HYPR HYPR(KC_NO)
#define KC_MEH MEH(KC_NO)
#ifdef UNICODE_ENABLE
// For sending unicode codes.
// You may not send codes over 7FFF -- this supports most of UTF8.
// To have a key that sends out Œ, go UC(0x0152)
#define UNICODE(n) (n | QK_UNICODE)
#define UC(n) UNICODE(n)
#endif
#ifdef UNICODEMAP_ENABLE
#define X(n) (n | QK_UNICODE_MAP)
#endif
#endif // QUANTUM_KEYCODES_H

@ -69,11 +69,12 @@ const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20};
rgblight_config_t rgblight_config;
rgblight_config_t inmem_config;
struct cRGB led[RGBLED_NUM];
uint8_t rgblight_inited = 0;
LED_TYPE led[RGBLED_NUM];
uint8_t rgblight_inited = 0;
bool rgblight_timer_enabled = false;
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
uint8_t r = 0, g = 0, b = 0, base, color;
if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
@ -124,7 +125,7 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
setrgb(r, g, b, led1);
}
void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) {
void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
(*led1).r = r;
(*led1).g = g;
(*led1).b = b;
@ -141,9 +142,9 @@ void eeconfig_update_rgblight_default(void) {
dprintf("eeconfig_update_rgblight_default\n");
rgblight_config.enable = 1;
rgblight_config.mode = 1;
rgblight_config.hue = 200;
rgblight_config.sat = 204;
rgblight_config.val = 204;
rgblight_config.hue = 0;
rgblight_config.sat = 255;
rgblight_config.val = 255;
eeconfig_update_rgblight(rgblight_config.raw);
}
void eeconfig_debug_rgblight(void) {
@ -173,7 +174,7 @@ void rgblight_init(void) {
}
eeconfig_debug_rgblight(); // display current eeprom values
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_init(); // setup the timer
#endif
@ -182,6 +183,19 @@ void rgblight_init(void) {
}
}
void rgblight_update_dword(uint32_t dword) {
rgblight_config.raw = dword;
eeconfig_update_rgblight(rgblight_config.raw);
if (rgblight_config.enable)
rgblight_mode(rgblight_config.mode);
else {
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
#endif
rgblight_set();
}
}
void rgblight_increase(void) {
uint8_t mode = 0;
if (rgblight_config.mode < RGBLIGHT_MODES) {
@ -220,7 +234,7 @@ void rgblight_mode(uint8_t mode) {
eeconfig_update_rgblight(rgblight_config.raw);
xprintf("rgblight mode: %u\n", rgblight_config.mode);
if (rgblight_config.mode == 1) {
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
#endif
} else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) {
@ -230,7 +244,7 @@ void rgblight_mode(uint8_t mode) {
// MODE 15-20, snake
// MODE 21-23, knight
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_enable();
#endif
}
@ -244,7 +258,7 @@ void rgblight_toggle(void) {
if (rgblight_config.enable) {
rgblight_mode(rgblight_config.mode);
} else {
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
#endif
_delay_ms(50);
@ -252,6 +266,13 @@ void rgblight_toggle(void) {
}
}
void rgblight_enable(void) {
rgblight_config.enable = 1;
eeconfig_update_rgblight(rgblight_config.raw);
xprintf("rgblight enable: rgblight_config.enable = %u\n", rgblight_config.enable);
rgblight_mode(rgblight_config.mode);
}
void rgblight_increase_hue(void) {
uint16_t hue;
@ -307,7 +328,7 @@ void rgblight_decrease_val(void) {
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
inmem_config.raw = rgblight_config.raw;
if (rgblight_config.enable) {
struct cRGB tmp_led;
LED_TYPE tmp_led;
sethsv(hue, sat, val, &tmp_led);
inmem_config.hue = hue;
inmem_config.sat = sat;
@ -349,68 +370,90 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
rgblight_set();
}
__attribute__ ((weak))
void rgblight_set(void) {
if (rgblight_config.enable) {
ws2812_setleds(led, RGBLED_NUM);
#ifdef RGBW
ws2812_setleds_rgbw(led, RGBLED_NUM);
#else
ws2812_setleds(led, RGBLED_NUM);
#endif
} else {
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
}
ws2812_setleds(led, RGBLED_NUM);
#ifdef RGBW
ws2812_setleds_rgbw(led, RGBLED_NUM);
#else
ws2812_setleds(led, RGBLED_NUM);
#endif
}
}
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#ifdef RGBLIGHT_ANIMATIONS
// Animation timer -- AVR Timer3
void rgblight_timer_init(void) {
static uint8_t rgblight_timer_is_init = 0;
if (rgblight_timer_is_init) {
return;
}
rgblight_timer_is_init = 1;
/* Timer 3 setup */
TCCR3B = _BV(WGM32) //CTC mode OCR3A as TOP
| _BV(CS30); //Clock selelct: clk/1
/* Set TOP value */
uint8_t sreg = SREG;
cli();
OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff;
OCR3AL = RGBLED_TIMER_TOP & 0xff;
SREG = sreg;
// static uint8_t rgblight_timer_is_init = 0;
// if (rgblight_timer_is_init) {
// return;
// }
// rgblight_timer_is_init = 1;
// /* Timer 3 setup */
// TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP
// | _BV(CS30); // Clock selelct: clk/1
// /* Set TOP value */
// uint8_t sreg = SREG;
// cli();
// OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff;
// OCR3AL = RGBLED_TIMER_TOP & 0xff;
// SREG = sreg;
rgblight_timer_enabled = true;
}
void rgblight_timer_enable(void) {
TIMSK3 |= _BV(OCIE3A);
rgblight_timer_enabled = true;
dprintf("TIMER3 enabled.\n");
}
void rgblight_timer_disable(void) {
TIMSK3 &= ~_BV(OCIE3A);
rgblight_timer_enabled = false;
dprintf("TIMER3 disabled.\n");
}
void rgblight_timer_toggle(void) {
TIMSK3 ^= _BV(OCIE3A);
rgblight_timer_enabled ^= rgblight_timer_enabled;
dprintf("TIMER3 toggled.\n");
}
ISR(TIMER3_COMPA_vect) {
// mode = 1, static light, do nothing here
if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
// mode = 2 to 5, breathing mode
rgblight_effect_breathing(rgblight_config.mode - 2);
} else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) {
// mode = 6 to 8, rainbow mood mod
rgblight_effect_rainbow_mood(rgblight_config.mode - 6);
} else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) {
// mode = 9 to 14, rainbow swirl mode
rgblight_effect_rainbow_swirl(rgblight_config.mode - 9);
} else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) {
// mode = 15 to 20, snake mode
rgblight_effect_snake(rgblight_config.mode - 15);
} else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) {
// mode = 21 to 23, knight mode
rgblight_effect_knight(rgblight_config.mode - 21);
void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
rgblight_enable();
rgblight_mode(1);
rgblight_setrgb(r, g, b);
}
void rgblight_task(void) {
if (rgblight_timer_enabled) {
// mode = 1, static light, do nothing here
if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
// mode = 2 to 5, breathing mode
rgblight_effect_breathing(rgblight_config.mode - 2);
} else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) {
// mode = 6 to 8, rainbow mood mod
rgblight_effect_rainbow_mood(rgblight_config.mode - 6);
} else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) {
// mode = 9 to 14, rainbow swirl mode
rgblight_effect_rainbow_swirl(rgblight_config.mode - 9);
} else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) {
// mode = 15 to 20, snake mode
rgblight_effect_snake(rgblight_config.mode - 15);
} else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) {
// mode = 21 to 23, knight mode
rgblight_effect_knight(rgblight_config.mode - 21);
} else {
// mode = 24, christmas mode
rgblight_effect_christmas();
}
}
}
@ -449,7 +492,7 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
last_timer = timer_read();
for (i = 0; i < RGBLED_NUM; i++) {
hue = (360 / RGBLED_NUM * i + current_hue) % 360;
sethsv(hue, rgblight_config.sat, rgblight_config.val, &led[i]);
sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
}
rgblight_set();
@ -486,7 +529,7 @@ void rgblight_effect_snake(uint8_t interval) {
k = k + RGBLED_NUM;
}
if (i == k) {
sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), &led[i]);
sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), (LED_TYPE *)&led[i]);
}
}
}
@ -506,7 +549,7 @@ void rgblight_effect_knight(uint8_t interval) {
static uint16_t last_timer = 0;
uint8_t i, j, cur;
int8_t k;
struct cRGB preled[RGBLED_NUM];
LED_TYPE preled[RGBLED_NUM];
static int8_t increment = -1;
if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
return;
@ -525,7 +568,7 @@ void rgblight_effect_knight(uint8_t interval) {
k = RGBLED_NUM - 1;
}
if (i == k) {
sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, &preled[i]);
sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&preled[i]);
}
}
}
@ -555,4 +598,22 @@ void rgblight_effect_knight(uint8_t interval) {
}
}
void rgblight_effect_christmas(void) {
static uint16_t current_offset = 0;
static uint16_t last_timer = 0;
uint16_t hue;
uint8_t i;
if (timer_elapsed(last_timer) < 1000) {
return;
}
last_timer = timer_read();
current_offset = (current_offset + 1) % 2;
for (i = 0; i < RGBLED_NUM; i++) {
hue = 0 + ((RGBLED_NUM * (i + current_offset)) % 2) * 80;
sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
}
rgblight_set();
}
#endif

@ -1,9 +1,8 @@
#ifndef RGBLIGHT_H
#define RGBLIGHT_H
#if !defined(AUDIO_ENABLE) && defined(RGBLIGHT_TIMER)
#define RGBLIGHT_MODES 23
#ifdef RGBLIGHT_ANIMATIONS
#define RGBLIGHT_MODES 24
#else
#define RGBLIGHT_MODES 1
#endif
@ -34,12 +33,15 @@
#endif
#define RGBLED_TIMER_TOP F_CPU/(256*64)
// #define RGBLED_TIMER_TOP 0xFF10
#include <stdint.h>
#include <stdbool.h>
#include "eeconfig.h"
#include "light_ws2812.h"
extern LED_TYPE led[RGBLED_NUM];
extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
@ -61,9 +63,11 @@ void rgblight_init(void);
void rgblight_increase(void);
void rgblight_decrease(void);
void rgblight_toggle(void);
void rgblight_enable(void);
void rgblight_step(void);
void rgblight_mode(uint8_t mode);
void rgblight_set(void);
void rgblight_update_dword(uint32_t dword);
void rgblight_increase_hue(void);
void rgblight_decrease_hue(void);
void rgblight_increase_sat(void);
@ -78,10 +82,15 @@ void eeconfig_update_rgblight(uint32_t val);
void eeconfig_update_rgblight_default(void);
void eeconfig_debug_rgblight(void);
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1);
void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1);
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
void rgblight_task(void);
void rgblight_timer_init(void);
void rgblight_timer_enable(void);
void rgblight_timer_disable(void);
@ -91,5 +100,6 @@ void rgblight_effect_rainbow_mood(uint8_t interval);
void rgblight_effect_rainbow_swirl(uint8_t interval);
void rgblight_effect_snake(uint8_t interval);
void rgblight_effect_knight(uint8_t interval);
void rgblight_effect_christmas(void);
#endif

@ -0,0 +1,110 @@
#include "variable_trace.h"
#include <stddef.h>
#include <string.h>
#ifdef NO_PRINT
#error "You need undef NO_PRINT to use the variable trace feature"
#endif
#ifndef CONSOLE_ENABLE
#error "The console needs to be enabled in the makefile to use the variable trace feature"
#endif
#define NUM_TRACED_VARIABLES 1
#ifndef MAX_VARIABLE_TRACE_SIZE
#define MAX_VARIABLE_TRACE_SIZE 4
#endif
typedef struct {
const char* name;
void* addr;
unsigned size;
const char* func;
int line;
uint8_t last_value[MAX_VARIABLE_TRACE_SIZE];
} traced_variable_t;
static traced_variable_t traced_variables[NUM_TRACED_VARIABLES];
void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) {
verify_traced_variables(func, line);
if (size > MAX_VARIABLE_TRACE_SIZE) {
#if defined(__AVR__)
xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size);
#else
xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size);
#endif
size = MAX_VARIABLE_TRACE_SIZE;
}
int index = -1;
for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
if (index == -1 && traced_variables[i].addr == NULL){
index = i;
}
else if (strcmp_P(name, traced_variables[i].name)==0) {
index = i;
break;
}
}
if (index == -1) {
xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES);
return;
}
traced_variable_t* t = &traced_variables[index];
t->name = name;
t->addr = addr;
t->size = size;
t->func = func;
t->line = line;
memcpy(&t->last_value[0], addr, size);
}
void remove_traced_variable(const char* name, const char* func, int line) {
verify_traced_variables(func, line);
for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
if (strcmp_P(name, traced_variables[i].name)==0) {
traced_variables[i].name = 0;
traced_variables[i].addr = NULL;
break;
}
}
}
void verify_traced_variables(const char* func, int line) {
for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
traced_variable_t* t = &traced_variables[i];
if (t->addr != NULL && t->name != NULL) {
if (memcmp(t->last_value, t->addr, t->size)!=0){
#if defined(__AVR__)
xprintf("Traced variable \"%S\" has been modified\n", t->name);
xprintf("Between %S:%d\n", t->func, t->line);
xprintf("And %S:%d\n", func, line);
#else
xprintf("Traced variable \"%s\" has been modified\n", t->name);
xprintf("Between %s:%d\n", t->func, t->line);
xprintf("And %s:%d\n", func, line);
#endif
xprintf("Previous value ");
for (int j=0; j<t->size;j++) {
print_hex8(t->last_value[j]);
}
xprintf("\nNew value ");
uint8_t* addr = (uint8_t*)(t->addr);
for (int j=0; j<t->size;j++) {
print_hex8(addr[j]);
}
xprintf("\n");
memcpy(t->last_value, addr, t->size);
}
}
t->func = func;
t->line = line;
}
}

@ -0,0 +1,34 @@
#ifndef VARIABLE_TRACE_H
#define VARIABLE_TRACE_H
// For more information about the variable tracing see the readme.
#include "print.h"
#ifdef NUM_TRACED_VARIABLES
// Start tracing a variable at the memory address addr
// The name can be anything and is used only for reporting
// The size should usually be the same size as the variable you are interested in
#define ADD_TRACED_VARIABLE(name, addr, size) \
add_traced_variable(PSTR(name), (void*)addr, size, PSTR(__FILE__), __LINE__)
// Stop tracing the variable with the given name
#define REMOVE_TRACED_VARIABLE(name) remove_traced_variable(PSTR(name), PSTR(__FILE__), __LINE__)
// Call to get messages when the variable has been changed
#define VERIFY_TRACED_VARIABLES() verify_traced_variables(PSTR(__FILE__), __LINE__)
#else
#define ADD_TRACED_VARIABLE(name, addr, size)
#define REMOVE_TRACED_VARIABLE(name)
#define VERIFY_TRACED_VARIABLES()
#endif
// Don't call directly, use the macros instead
void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line);
void remove_traced_variable(const char* name, const char* func, int line);
void verify_traced_variables(const char* func, int line);
#endif

@ -4,7 +4,7 @@
This is a keyboard firmware based on the [tmk_keyboard firmware](http://github.com/tmk/tmk_keyboard) with some useful features for Atmel AVR controllers, and more specifically, the [OLKB product line](http://olkb.com), the [ErgoDox EZ](http://www.ergodox-ez.com) keyboard, and the [Clueboard product line](http://clueboard.co/).
## Official website
## Official website (currently under construction with the move to the wiki)
For an easy-to-read version of this document and the repository, check out [http://qmk.fm](http://qmk.fm). Nicely formatted keyboard and keymap listings are also available there, along with the ability to download .hex files instead of having to setup a build environment and compile them.
@ -31,1243 +31,9 @@ The OLKB product firmwares are maintained by [Jack Humbert](https://github.com/j
This is not a tiny project. While this is the main readme, there are many other files you might want to consult. Here are some points of interest:
* [**The Wiki**](https://github.com/jackhumbert/qmk_firmware/wiki) - the entirity of the readme has been moved here
* The readme for your own keyboard: This is found under `keyboards/<your keyboards's name>/`. So for the ErgoDox EZ, it's [here](keyboards/ergodox/ez/); for the Planck, it's [here](keyboards/planck/) and so on.
* The list of possible keycodes you can use in your keymap is actually spread out in a few different places:
* [doc/keycode.txt](doc/keycode.txt) - an explanation of those same keycodes.
* [quantum/keymap.h](quantum/keymap.h) - this is where the QMK-specific aliases are all set up. Things like the Hyper and Meh key, the Leader key, and all of the other QMK innovations. These are also explained and documented below, but `keymap.h` is where they're actually defined.
* The [TMK documentation](doc/TMK_README.md). QMK is based on TMK, and this explains how it works internally.
# Getting started
Before you are able to compile, you'll need to install an environment for AVR development. You'll find the instructions for any OS below. If you find another/better way to set things up from scratch, please consider [making a pull request](https://github.com/jackhumbert/qmk_firmware/pulls) with your changes!
## Build Environment Setup
### Windows 10
It's still recommended to use the method for Vista and later below. The reason for this is that the Windows 10 Subsystem for Linux lacks [USB support](https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo/suggestions/13355724-unable-to-access-usb-devices-from-bash), so it's not possible to flash the firmware to the keyboard. Please add your vote to the link!
That said, it's still possible to use it for compilation. And recommended, if you need to compile much, since it's much faster than at least Cygwin (which is also supported, but currently lacking documentation). I haven't tried the method below, so I'm unable to tell.
Here are the steps
1. Install the Windows 10 subsystem for Linux, following [these instructions](http://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/).
2. If you have previously cloned the repository using the normal Git bash, you will need to clean up the line endings. If you have cloned it after 20th of August 2016, you are likely fine. To clean up the line endings do the following
1. Make sure that you have no changes you haven't committed by running `git status`, if you do commit them first
2. From within the Git bash run `git rm --cached -r .`
3. Followed by `git reset --hard`
3. Start the "Bash On Ubuntu On Windows" from the start menu
4. With the bash open, navigate to your Git checkout. The harddisk can be accessed from `/mnt` for example `/mnt/c` for the `c:\` drive.
5. Run `sudo util/install_dependencies.sh`.
6. After a while the installation will finish, and you are good to go
**Note** From time to time, the dependencies might change, so just run `install_dependencies.sh` again if things are not working.
**Warning:** If you edit Makefiles or shell scripts, make sure you are using an editor that saves the files with Unix line endings. Otherwise the compilation might not work.
### Windows (Vista and later)
1. If you have ever installed WinAVR, uninstall it.
2. Install [MHV AVR Tools](https://infernoembedded.com/sites/default/files/project/MHV_AVR_Tools_20131101.exe). Disable smatch, but **be sure to leave the option to add the tools to the PATH checked**.
3. If you are going to flash Infinity based keyboards you will need to install dfu-util, refer to the instructions by [Input Club](https://github.com/kiibohd/controller/wiki/Loading-DFU-Firmware).
4. Install [MinGW](https://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download). During installation, uncheck the option to install a graphical user interface. **DO NOT change the default installation folder.** The scripts depend on the default location.
5. Clone this repository. [This link will download it as a zip file, which you'll need to extract.](https://github.com/jackhumbert/qmk_firmware/archive/master.zip) Open the extracted folder in Windows Explorer.
6. Open the `\util` folder.
7. Double-click on the `1-setup-path-win` batch script to run it. You'll need to accept a User Account Control prompt. Press the spacebar to dismiss the success message in the command prompt that pops up.
8. Right-click on the `2-setup-environment-win` batch script, select "Run as administrator", and accept the User Account Control prompt. This part may take a couple of minutes, and you'll need to approve a driver installation, but once it finishes, your environment is complete!
If you have trouble and want to ask for help, it is useful to generate a *Win_Check_Output.txt* file by running `Win_Check.bat` in the `\util` folder.
### Mac
If you're using [homebrew,](http://brew.sh/) you can use the following commands:
brew tap osx-cross/avr
brew install avr-libc
brew install dfu-programmer
This is the recommended method. If you don't have homebrew, [install it!](http://brew.sh/) It's very much worth it for anyone who works in the command line.
You can also try these instructions:
1. Install Xcode from the App Store.
2. Install the Command Line Tools from `Xcode->Preferences->Downloads`.
3. Install [DFU-Programmer][dfu-prog].
If you are going to flash Infinity based keyboards you will also need dfu-util
brew install dfu-util
### Linux
To ensure you are always up to date, you can just run `sudo util/install_dependencies.sh`. That should always install all the dependencies needed.
You can also install things manually, but this documentation might not be always up to date with all requirements.
The current requirements are the following, but not all might be needed depending on what you do. Also note that some systems might not have all the dependencies available as packages, or they might be named differently.
```
build-essential
gcc
unzip
wget
zip
gcc-avr
binutils-avr
avr-libc
dfu-programmer
dfu-util
gcc-arm-none-eabi
binutils-arm-none-eabi
libnewlib-arm-none-eabi
git
```
Install the dependencies with your favorite package manager.
Debian/Ubuntu example:
sudo apt-get update
sudo apt-get install gcc unzip wget zip gcc-avr binutils-avr avr-libc dfu-programmer dfu-util gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
### Docker
If this is a bit complex for you, Docker might be the turn-key solution you need. After installing [Docker](https://www.docker.com/products/docker), run the following command at the root of the QMK folder to build a keyboard/keymap:
```bash
# You'll run this every time you want to build a keymap
# modify the keymap and keyboard assigment to compile what you want
# defaults are ergodox/default
docker run -e keymap=gwen -e keyboard=ergodox --rm -v $('pwd'):/qmk:rw edasque/qmk_firmware
# On windows docker seems to have issue with VOLUME tag in Dockerfile, and $('pwd') won't print a windows compliant path, use full path instead like this
docker run -e keymap=default -e keyboard=ergobop --rm -v D:/Users/Sacapuces/Documents/Repositories/qmk:/qmk:rw edasque/qmk_firmware
```
This will compile the targetted keyboard/keymap and leave it in your QMK directory for you to flash.
### Vagrant
If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [VAGRANT_GUIDE file](doc/VAGRANT_GUIDE.md).
## Verify Your Installation
1. If you haven't already, obtain this repository ([https://github.com/jackhumbert/qmk_firmware](https://github.com/jackhumbert/qmk_firmware)). You can either download it as a zip file and extract it, or clone it using the command line tool git or the Github Desktop application.
2. Open up a terminal or command prompt and navigate to the `qmk_firmware` folder using the `cd` command. The command prompt will typically open to your home directory. If, for example, you cloned the repository to your Documents folder, then you would type `cd Documents/qmk_firmware`. If you extracted the file from a zip, then it may be named `qmk_firmware-master` instead.
3. To confirm that you're in the correct location, you can display the contents of your current folder using the `dir` command on Windows, or the `ls` command on Linux or Mac. You should see several files, including `readme.md` and a `quantum` folder. From here, you need to navigate to the appropriate folder under `keyboards/`. For example, if you're building for a Planck, run `cd keyboards/planck`.
4. Once you're in the correct keyboard-specific folder, run the `make` command. This should output a lot of information about the build process. More information about the `make` command can be found below.
# Customizing your keymap
In every keymap folder, the following files are recommended:
* `config.h` - the options to configure your keymap
* `keymap.c` - all of your keymap code, required
* `Makefile` - the features of QMK that are enabled, required to run `make` in your keymap folder
* `readme.md` - a description of your keymap, how others might use it, and explanations of features
## The `make` command
The `make` command is how you compile the firmware into a .hex file, which can be loaded by a dfu programmer (like dfu-progammer via `make dfu`) or the [Teensy loader](https://www.pjrc.com/teensy/loader.html) (only used with Teensys).
**NOTE:** To abort a make command press `Ctrl-c`
The following instruction refers to these folders.
* The `root` (`/`) folder is the qmk_firmware folder, in which are `doc`, `keyboard`, `quantum`, etc.
* The `keyboard` folder is any keyboard project's folder, like `/keyboards/planck`.
* The `keymap` folder is any keymap's folder, like `/keyboards/planck/keymaps/default`.
* The `subproject` folder is the subproject folder of a keyboard, like `/keyboards/ergodox/ez`
### Simple instructions for building and uploading a keyboard
**Most keyboards have more specific instructions in the keyboard specific readme.md file, so please check that first**
If the `keymap` folder contains a file name `Makefile`
1. Change the directory to the `keymap` folder
2. Run `make <subproject>-<programmer>`
Otherwise, if there's no `Makefile` in the `keymap` folder
1. Enter the `keyboard` folder
2. Run `make <subproject>-<keymap>-<programmer>`
In the above commands, replace:
* `<keymap>` with the name of your keymap
* `<subproject>` with the name of the subproject (revision or sub-model of your keyboard). For example, for Ergodox it can be `ez` or `infinity`, and for Planck `rev3` or `rev4`.
* If the keyboard doesn't have a subproject, or if you are happy with the default (defined in `rules.mk` file of the `keyboard` folder), you can leave it out. But remember to also remove the dash (`-`) from the command.
* `<programmer>` The programmer to use. Most keyboards use `dfu`, but some use `teensy`. Infinity keyboards use `dfu-util`. Check the readme file in the keyboard folder to find out which programmer to use.
* If you don't add `-<programmer` to the command line, the firmware will be still be compiled into a hex file, but the upload will be skipped.
**NOTE:** Some operating systems will refuse to program unless you run the make command as root for example `sudo make dfu`
### More detailed make instruction
The full syntax of the `make` command is the following, but parts of the command can be left out if you run it from other directories than the `root` (as you might already have noticed by reading the simple instructions).
`<keyboard>-<subproject>-<keymap>-<target>`, where:
* `<keyboard>` is the name of the keyboard, for example `planck`
* Use `allkb` to compile all keyboards
* `<subproject>` is the name of the subproject (revision or sub-model of the keyboard). For example, for Ergodox it can be `ez` or `infinity`, and for Planck `rev3` or `rev4`.
* If the keyboard doesn't have any subprojects, it can be left out
* To compile the default subproject, you can leave it out, or specify `defaultsp`
* Use `allsp` to compile all subprojects
* `<keymap>` is the name of the keymap, for example `algernon`
* Use `allkm` to compile all keymaps
* `<target>` will be explained in more detail below.
**Note:** When you leave some parts of the command out, you should also remove the dash (`-`).
As mentioned above, there are some shortcuts, when you are in a:
* `keyboard` folder, the command will automatically fill the `<keyboard>` part. So you only need to type `<subproject>-<keymap>-<target>`
* `subproject` folder, it will fill in both `<keyboard>` and `<subproject>`
* `keymap` folder, then `<keyboard>` and `<keymap>` will be filled in. If you need to specify the `<subproject>` use the following syntax `<subproject>-<target>`
* Note in order to support this shortcut, the keymap needs its own Makefile (see the example [here](/doc/keymap_makefile_example.mk))
* `keymap` folder of a `subproject`, then everything except the `<target>` will be filled in
The `<target>` means the following
* If no target is given, then it's the same as `all` below
* `all` compiles the keyboard and generates a `<keyboard>_<keymap>.hex` file in whichever folder you run `make` from. These files are ignored by git, so don't worry about deleting them when committing/creating pull requests.
* `dfu`, `teensy` or `dfu-util`, compile and upload the firmware to the keyboard. If the compilation fails, then nothing will be uploaded. The programmer to use depends on the keyboard. For most keyboards it's `dfu`, but for Infinity keyboards you should use `dfu-util`, and `teensy` for standard Teensys. To find out which command you should use for your keyboard, check the keyboard specific readme. **Note** that some operating systems needs root access for these commands to work, so in that case you need to run for example `sudo make dfu`.
* `clean`, cleans the build output folders to make sure that everything is built from scratch. Run this before normal compilation if you have some unexplainable problems.
Some other targets are supported but, but not important enough to be documented here. Check the source code of the make files for more information.
You can also add extra options at the end of the make command line, after the target
* `make COLOR=false` - turns off color output
* `make SILENT=true` - turns off output besides errors/warnings
* `make VERBOSE=true` - outputs all of the gcc stuff (not interesting, unless you need to debug)
The make command itself also has some additional options, type `make --help` for more information. The most useful is probably `-jx`, which specifies that you want to compile using more than one CPU, the `x` represents the number of CPUs that you want to use. Setting that can greatly reduce the compile times, especially if you are compiling many keyboards/keymaps. I usually set it to one less than the number of CPUs that I have, so that I have some left for doing other things while it's compiling. Note that not all operating systems and make versions supports that option.
Here are some examples commands
* `make allkb-allsp-allkm` builds everything (all keyboards, all subprojects, all keymaps). Running just `make` from the `root` will also run this.
* `make` from within a `keyboard` directory, is the same as `make keyboard-allsp-allkm`, which compiles all subprojects and keymaps of the keyboard. **NOTE** that this behaviour has changed. Previously it compiled just the default keymap.
* `make ergodox-infinity-algernon-clean` will clean the build output of the Ergodox Infinity keyboard. This example uses the full syntax and can be run from any folder with a `Makefile`
* `make dfu COLOR=false` from within a keymap folder, builds and uploads the keymap, but without color output.
## The `Makefile`
There are 5 different `make` and `Makefile` locations:
* root (`/`)
* keyboard (`/keyboards/<keyboard>/`)
* keymap (`/keyboards/<keyboard>/keymaps/<keymap>/`)
* subproject (`/keyboards/<keyboard>/<subproject>`)
* subproject keymap (`/keyboards/<keyboard>/<subproject>/keymaps/<keymap>`)
The root contains the code used to automatically figure out which keymap or keymaps to compile based on your current directory and commandline arguments. It's considered stable, and shouldn't be modified. The keyboard one will contain the MCU set-up and default settings for your keyboard, and shouldn't be modified unless you are the producer of that keyboard. The keymap Makefile can be modified by users, and is optional. It is included automatically if it exists. You can see an example [here](/doc/keymap_makefile_example.mk) - the last few lines are the most important. The settings you set here will override any defaults set in the keyboard Makefile. **The file is required if you want to run `make` in the keymap folder.**
For keyboards and subprojects, the make files are split in two parts `Makefile` and `rules.mk`. All settings can be found in the `rules.mk` file, while the `Makefile` is just there for support and including the root `Makefile`. Keymaps contain just one `Makefile` for simplicity.
### Makefile options
Set the variables to `no` to disable them, and `yes` to enable them.
`BOOTMAGIC_ENABLE`
This allows you to hold a key and the salt key (space by default) and have access to a various EEPROM settings that persist over power loss. It's advised you keep this disabled, as the settings are often changed by accident, and produce confusing results that makes it difficult to debug. It's one of the more common problems encountered in help sessions.
`MOUSEKEY_ENABLE`
This gives you control over cursor movements and clicks via keycodes/custom functions.
`EXTRAKEY_ENABLE`
This allows you to use the system and audio control key codes.
`CONSOLE_ENABLE`
This allows you to print messages that can be read using [`hid_listen`](https://www.pjrc.com/teensy/hid_listen.html).
By default, all debug (*dprint*) print (*print*, *xprintf*), and user print (*uprint*) messages will be enabled. This will eat up a significant portion of the flash and may make the keyboard .hex file too big to program.
To disable debug messages (*dprint*) and reduce the .hex file size, include `#define NO_DEBUG` in your `config.h` file.
To disable print messages (*print*, *xprintf*) and user print messages (*uprint*) and reduce the .hex file size, include `#define NO_PRINT` in your `config.h` file.
To disable print messages (*print*, *xprintf*) and **KEEP** user print messages (*uprint*), include `#define USER_PRINT` in your `config.h` file.
To see the text, open `hid_listen` and enjoy looking at your printed messages.
**NOTE:** Do not include *uprint* messages in anything other than your keymap code. It must not be used within the QMK system framework. Otherwise, you will bloat other people's .hex files.
`COMMAND_ENABLE`
This enables magic commands, typically fired with the default magic key combo `LSHIFT+RSHIFT+KEY`. Magic commands include turning on debugging messages (`MAGIC+D`) or temporarily toggling NKRO (`MAGIC+N`).
`SLEEP_LED_ENABLE`
Enables your LED to breath while your computer is sleeping. Timer1 is being used here. This feature is largely unused and untested, and needs updating/abstracting.
`NKRO_ENABLE`
This allows the keyboard to tell the host OS that up to 248 keys are held down at once (default without NKRO is 6). NKRO is off by default, even if `NKRO_ENABLE` is set. NKRO can be forced by adding `#define FORCE_NKRO` to your config.h or by binding `MAGIC_TOGGLE_NKRO` to a key and then hitting the key.
`BACKLIGHT_ENABLE`
This enables your backlight on Timer1 and ports B5, B6, or B7 (for now). You can specify your port by putting this in your `config.h`:
#define BACKLIGHT_PIN B7
`MIDI_ENABLE`
This enables MIDI sending and receiving with your keyboard. To enter MIDI send mode, you can use the keycode `MI_ON`, and `MI_OFF` to turn it off. This is a largely untested feature, but more information can be found in the `quantum/quantum.c` file.
`UNICODE_ENABLE`
This allows you to send unicode symbols via `UC(<unicode>)` in your keymap. Only codes up to 0x7FFF are currently supported.
`BLUETOOTH_ENABLE`
This allows you to interface with a Bluefruit EZ-key to send keycodes wirelessly. It uses the D2 and D3 pins.
`AUDIO_ENABLE`
This allows you output audio on the C6 pin (needs abstracting). See the [audio section](#driving-a-speaker---audio-support) for more information.
### Customizing Makefile options on a per-keymap basis
If your keymap directory has a file called `Makefile` (note the filename), any Makefile options you set in that file will take precedence over other Makefile options for your particular keyboard.
So let's say your keyboard's makefile has `BACKLIGHT_ENABLE = yes` (or maybe doesn't even list the `BACKLIGHT_ENABLE` option, which would cause it to be off). You want your particular keymap to not have the debug console, so you make a file called `Makefile` and specify `BACKLIGHT_ENABLE = no`.
You can use the `doc/keymap_makefile_example.md` as a template/starting point.
## The `config.h` file
There are 2 `config.h` locations:
* keyboard (`/keyboards/<keyboard>/`)
* keymap (`/keyboards/<keyboard>/keymaps/<keymap>/`)
The keyboard `config.h` is included only if the keymap one doesn't exist. The format to use for your custom one [is here](/doc/keymap_config_h_example.h). If you want to override a setting from the parent `config.h` file, you need to do this:
```c
#undef MY_SETTING
#define MY_SETTING 4
```
For a value of `4` for this imaginary setting. So we `undef` it first, then `define` it.
You can then override any settings, rather than having to copy and paste the whole thing.
# Going beyond the keycodes
Aside from the [basic keycodes](doc/keycode.txt), your keymap can include shortcuts to common operations.
## Quick aliases to common actions
Your keymap can include shortcuts to common operations (called "function actions" in tmk).
These functions work the same way that their `ACTION_*` functions do - they're just quick aliases. To dig into all of the tmk `ACTION_*` functions, please see the [TMK documentation](https://github.com/jackhumbert/qmk_firmware/blob/master/doc/keymap.md#2-action).
Instead of using `FNx` when defining `ACTION_*` functions, you can use `F(x)` - the benefit here is being able to use more than 32 function actions (up to 4096), if you happen to need them.
### Switching and toggling layers
`MO(layer)` - momentary switch to *layer*. As soon as you let go of the key, the layer is deactivated and you pop back out to the previous layer. When you apply this to a key, that same key must be set as `KC_TRNS` on the destination layer. Otherwise, you won't make it back to the original layer when you release the key (and you'll get a keycode sent). You can only switch to layers *above* your current layer. If you're on layer 0 and you use `MO(1)`, that will switch to layer 1 just fine. But if you include `MO(3)` on layer 5, that won't do anything for you -- because layer 3 is lower than layer 5 on the stack.
`OSL(layer)` - momentary switch to *layer*, as a one-shot operation. So if you have a key that's defined as `OSL(1)`, and you tap that key, then only the very next keystroke would come from layer 1. You would drop back to layer zero immediately after that one keystroke. That's handy if you have a layer full of custom shortcuts -- for example, a dedicated key for closing a window. So you tap your one-shot layer mod, then tap that magic 'close window' key, and keep typing like a boss. Layer 1 would remain active as long as you hold that key down, too (so you can use it like a momentary toggle-layer key with extra powers).
`LT(layer, kc)` - momentary switch to *layer* when held, and *kc* when tapped. Like `MO()`, this only works upwards in the layer stack (`layer` must be higher than the current layer).
`TG(layer)` - toggles a layer on or off. As with `MO()`, you should set this key as `KC_TRNS` in the destination layer so that tapping it again actually toggles back to the original layer. Only works upwards in the layer stack.
`TO(layer)` - Goes to a layer. This code is special, because it lets you go either up or down the stack -- just goes directly to the layer you want. So while other codes only let you go _up_ the stack (from layer 0 to layer 3, for example), `TO(2)` is going to get you to layer 2, no matter where you activate it from -- even if you're currently on layer 5. This gets activated on keydown (as soon as the key is pressed).
### Fun with modifier keys
* `LSFT(kc)` - applies left Shift to *kc* (keycode) - `S(kc)` is an alias
* `RSFT(kc)` - applies right Shift to *kc*
* `LCTL(kc)` - applies left Control to *kc*
* `RCTL(kc)` - applies right Control to *kc*
* `LALT(kc)` - applies left Alt to *kc*
* `RALT(kc)` - applies right Alt to *kc*
* `LGUI(kc)` - applies left GUI (command/win) to *kc*
* `RGUI(kc)` - applies right GUI (command/win) to *kc*
* `HYPR(kc)` - applies Hyper (all modifiers) to *kc*
* `MEH(kc)` - applies Meh (all modifiers except Win/Cmd) to *kc*
* `LCAG(kc)` - applies CtrlAltGui to *kc*
You can also chain these, like this:
LALT(LCTL(KC_DEL)) -- this makes a key that sends Alt, Control, and Delete in a single keypress.
The following shortcuts automatically add `LSFT()` to keycodes to get commonly used symbols. Their long names are also available and documented in `/quantum/keymap_common.h`.
KC_TILD ~
KC_EXLM !
KC_AT @
KC_HASH #
KC_DLR $
KC_PERC %
KC_CIRC ^
KC_AMPR &
KC_ASTR *
KC_LPRN (
KC_RPRN )
KC_UNDS _
KC_PLUS +
KC_DQUO "
KC_LCBR {
KC_RCBR }
KC_LABK <
KC_RABK >
KC_PIPE |
KC_COLN :
`OSM(mod)` - this is a "one shot" modifier. So let's say you have your left Shift key defined as `OSM(MOD_LSFT)`. Tap it, let go, and Shift is "on" -- but only for the next character you'll type. So to write "The", you don't need to hold down Shift -- you tap it, tap t, and move on with life. And if you hold down the left Shift key, it just works as a left Shift key, as you would expect (so you could type THE). There's also a magical, secret way to "lock" a modifier by tapping it multiple times. If you want to learn more about that, open an issue. :)
`MT(mod, kc)` - is *mod* (modifier key - MOD_LCTL, MOD_LSFT) when held, and *kc* when tapped. In other words, you can have a key that sends Esc (or the letter O or whatever) when you tap it, but works as a Control key or a Shift key when you hold it down.
These are the values you can use for the `mod` in `MT()` and `OSM()` (right-hand modifiers are not available for `MT()`):
* MOD_LCTL
* MOD_LSFT
* MOD_LALT
* MOD_LGUI
* MOD_HYPR
* MOD_MEH
These can also be combined like `MOD_LCTL | MOD_LSFT` e.g. `MT(MOD_LCTL | MOD_LSFT, KC_ESC)` which would activate Control and Shift when held, and send Escape when tapped.
We've added shortcuts to make common modifier/tap (mod-tap) mappings more compact:
* `CTL_T(kc)` - is LCTL when held and *kc* when tapped
* `SFT_T(kc)` - is LSFT when held and *kc* when tapped
* `ALT_T(kc)` - is LALT when held and *kc* when tapped
* `GUI_T(kc)` - is LGUI when held and *kc* when tapped
* `ALL_T(kc)` - is Hyper (all mods) when held and *kc* when tapped. To read more about what you can do with a Hyper key, see [this blog post by Brett Terpstra](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)
* `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped
* `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift.
## Space Cadet Shift: The future, built in
Steve Losh [described](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) the Space Cadet Shift quite well. Essentially, you hit the left Shift on its own, and you get an opening parenthesis; hit the right Shift on its own, and you get the closing one. When hit with other keys, the Shift key keeps working as it always does. Yes, it's as cool as it sounds.
To use it, use `KC_LSPO` (Left Shift, Parens Open) for your left Shift on your keymap, and `KC_RSPC` (Right Shift, Parens Close) for your right Shift.
It's defaulted to work on US keyboards, but if your layout uses different keys for parenthesis, you can define those in your `config.h` like this:
#define LSPO_KEY KC_9
#define RSPC_KEY KC_0
You can also choose between different rollover behaviors of the shift keys by defining:
#define DISABLE_SPACE_CADET_ROLLOVER
in your `config.h`. Disabling rollover allows you to use the opposite shift key to cancel the space cadet state in the event of an erroneous press instead of emitting a pair of parentheses when the keys are released.
The only other thing you're going to want to do is create a `Makefile` in your keymap directory and set the following:
```
COMMAND_ENABLE = no # Commands for debug and configuration
```
This is just to keep the keyboard from going into command mode when you hold both Shift keys at the same time.
## The Leader key: A new kind of modifier
If you've ever used Vim, you know what a Leader key is. If not, you're about to discover a wonderful concept. :) Instead of hitting Alt+Shift+W for example (holding down three keys at the same time), what if you could hit a _sequence_ of keys instead? So you'd hit our special modifier (the Leader key), followed by W and then C (just a rapid succession of keys), and something would happen.
That's what `KC_LEAD` does. Here's an example:
1. Pick a key on your keyboard you want to use as the Leader key. Assign it the keycode `KC_LEAD`. This key would be dedicated just for this -- it's a single action key, can't be used for anything else.
2. Include the line `#define LEADER_TIMEOUT 300` somewhere in your keymap.c file, probably near the top. The 300 there is 300ms -- that's how long you have for the sequence of keys following the leader. You can tweak this value for comfort, of course.
3. Within your `matrix_scan_user` function, do something like this:
```
LEADER_EXTERNS();
void matrix_scan_user(void) {
LEADER_DICTIONARY() {
leading = false;
leader_end();
SEQ_ONE_KEY(KC_F) {
register_code(KC_S);
unregister_code(KC_S);
}
SEQ_TWO_KEYS(KC_A, KC_S) {
register_code(KC_H);
unregister_code(KC_H);
}
SEQ_THREE_KEYS(KC_A, KC_S, KC_D) {
register_code(KC_LGUI);
register_code(KC_S);
unregister_code(KC_S);
unregister_code(KC_LGUI);
}
}
}
```
As you can see, you have three function. you can use - `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS` and `SEQ_THREE_KEYS` for longer sequences. Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
## Tap Dance: A single key can do 3, 5, or 100 different things
Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a colon. Hit it three times, and your keyboard's LEDs do a wild dance. That's just one example of what Tap Dance can do. It's one of the nicest community-contributed features in the firmware, conceived and created by [algernon](https://github.com/algernon) in [#451](https://github.com/jackhumbert/qmk_firmware/pull/451). Here's how algernon describes the feature:
With this feature one can specify keys that behave differently, based on the amount of times they have been tapped, and when interrupted, they get handled before the interrupter.
To make it clear how this is different from `ACTION_FUNCTION_TAP`, lets explore a certain setup! We want one key to send `Space` on single tap, but `Enter` on double-tap.
With `ACTION_FUNCTION_TAP`, it is quite a rain-dance to set this up, and has the problem that when the sequence is interrupted, the interrupting key will be send first. Thus, `SPC a` will result in `a SPC` being sent, if they are typed within `TAPPING_TERM`. With the tap dance feature, that'll come out as `SPC a`, correctly.
The implementation hooks into two parts of the system, to achieve this: into `process_record_quantum()`, and the matrix scan. We need the latter to be able to time out a tap sequence even when a key is not being pressed, so `SPC` alone will time out and register after `TAPPING_TERM` time.
But lets start with how to use it, first!
First, you will need `TAP_DANCE_ENABLE=yes` in your `Makefile`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro, that - similar to `F()`, takes a number, which will later be used as an index into the `tap_dance_actions` array.
This array specifies what actions shall be taken when a tap-dance key is in action. Currently, there are three possible options:
* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held.
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function on when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
And that's the bulk of it!
And now, on to the explanation of how it works!
The main entry point is `process_tap_dance()`, called from `process_record_quantum()`, which is run for every keypress, and our handler gets to run early. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. If it was the same, we increment the counter and the timer.
This means that you have `TAPPING_TERM` time to tap the key again, you do not have to input all the taps within that timeframe. This allows for longer tap counts, with minimal impact on responsiveness.
Our next stop is `matrix_scan_tap_dance()`. This handles the timeout of tap-dance keys.
For the sake of flexibility, tap-dance actions can be either a pair of keycodes, or a user function. The latter allows one to handle higher tap counts, or do extra things, like blink the LEDs, fiddle with the backlighting, and so on. This is accomplished by using an union, and some clever macros.
### Examples
Here's a simple example for a single definition:
1. In your `makefile`, add `TAP_DANCE_ENABLE = yes`
2. In your `config.h` (which you can copy from `qmk_firmware/keyboards/planck/config.h` to your keymap directory), add `#define TAPPING_TERM 200`
3. In your `keymap.c` file, define the variables and definitions, then add to your keymap:
```c
//Tap Dance Declarations
enum {
TD_ESC_CAPS = 0
};
//Tap Dance Definitions
qk_tap_dance_action_t tap_dance_actions[] = {
//Tap once for Esc, twice for Caps Lock
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS)
// Other declarations would go here, separated by commas, if you have them
};
//In Layer declaration, add tap dance item in place of a key code
TD(TD_ESC_CAPS)
```
Here's a more complex example involving custom actions:
```c
enum {
CT_SE = 0,
CT_CLN,
CT_EGG,
CT_FLSH,
};
/* Have the above three on the keymap, TD(CT_SE), etc... */
void dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
register_code (KC_RSFT);
register_code (KC_SCLN);
} else {
register_code (KC_SCLN);
}
}
void dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) {
if (state->count == 1) {
unregister_code (KC_RSFT);
unregister_code (KC_SCLN);
} else {
unregister_code (KC_SCLN);
}
}
void dance_egg (qk_tap_dance_state_t *state, void *user_data) {
if (state->count >= 100) {
SEND_STRING ("Safety dance!");
reset_tap_dance (state);
}
}
// on each tap, light up one led, from right to left
// on the forth tap, turn them off from right to left
void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) {
switch (state->count) {
case 1:
ergodox_right_led_3_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_1_on();
break;
case 4:
ergodox_right_led_3_off();
_delay_ms(50);
ergodox_right_led_2_off();
_delay_ms(50);
ergodox_right_led_1_off();
}
}
// on the fourth tap, set the keyboard on flash state
void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) {
if (state->count >= 4) {
reset_keyboard();
reset_tap_dance(state);
}
}
// if the flash state didnt happen, then turn off leds, left to right
void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) {
ergodox_right_led_1_off();
_delay_ms(50);
ergodox_right_led_2_off();
_delay_ms(50);
ergodox_right_led_3_off();
}
qk_tap_dance_action_t tap_dance_actions[] = {
[CT_SE] = ACTION_TAP_DANCE_DOUBLE (KC_SPC, KC_ENT)
,[CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, dance_cln_finished, dance_cln_reset)
,[CT_EGG] = ACTION_TAP_DANCE_FN (dance_egg)
,[CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED (dance_flsh_each, dance_flsh_finished, dance_flsh_reset)
};
```
## Temporarily setting the default layer
`DF(layer)` - sets default layer to *layer*. The default layer is the one at the "bottom" of the layer stack - the ultimate fallback layer. This currently does not persist over power loss. When you plug the keyboard back in, layer 0 will always be the default. It is theoretically possible to work around that, but that's not what `DF` does.
## Prevent stuck modifiers
Consider the following scenario:
1. Layer 0 has a key defined as Shift.
2. The same key is defined on layer 1 as the letter A.
3. User presses Shift.
4. User switches to layer 1 for whatever reason.
5. User releases Shift, or rather the letter A.
6. User switches back to layer 0.
Shift was actually never released and is still considered pressed.
If such situation bothers you add this to your `config.h`:
#define PREVENT_STUCK_MODIFIERS
This option uses 5 bytes of memory per every 8 keys on the keyboard
rounded up (5 bits per key). For example on Planck (48 keys) it uses
(48/8)\*5 = 30 bytes.
## Macro shortcuts: Send a whole string when pressing just one key
Instead of using the `ACTION_MACRO` function, you can simply use `M(n)` to access macro *n* - *n* will get passed into the `action_get_macro` as the `id`, and you can use a switch statement to trigger it. This gets called on the keydown and keyup, so you'll need to use an if statement testing `record->event.pressed` (see keymap_default.c).
```c
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // this is the function signature -- just copy/paste it into your keymap file as it is.
{
switch(id) {
case 0: // this would trigger when you hit a key mapped as M(0)
if (record->event.pressed) {
return MACRO( I(255), T(H), T(E), T(L), T(L), W(255), T(O), END ); // this sends the string 'hello' when the macro executes
}
break;
}
return MACRO_NONE;
};
```
A macro can include the following commands:
* I() change interval of stroke in milliseconds.
* D() press key.
* U() release key.
* T() type key(press and release).
* W() wait (milliseconds).
* END end mark.
So above you can see the stroke interval changed to 255ms between each keystroke, then a bunch of keys being typed, waits a while, then the macro ends.
Note: Using macros to have your keyboard send passwords for you is possible, but a bad idea.
### Advanced macro functions
To get more control over the keys/actions your keyboard takes, the following functions are available to you in the `action_get_macro` function block:
* `record->event.pressed`
This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
```c
if (record->event.pressed) {
// on keydown
} else {
// on keyup
}
```
* `register_code(<kc>);`
This sends the `<kc>` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`.
* `unregister_code(<kc>);`
Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
* `layer_on(<n>);`
This will turn on the layer `<n>` - the higher layer number will always take priority. Make sure you have `KC_TRNS` for the key you're pressing on the layer you're switching to, or you'll get stick there unless you have another plan.
* `layer_off(<n>);`
This will turn off the layer `<n>`.
* `clear_keyboard();`
This will clear all mods and keys currently pressed.
* `clear_mods();`
This will clear all mods currently pressed.
* `clear_keyboard_but_mods();`
This will clear all keys besides the mods currently pressed.
* `update_tri_layer(layer_1, layer_2, layer_3);`
If the user attempts to activate layer 1 AND layer 2 at the same time (for example, by hitting their respective layer keys), layer 3 will be activated. Layers 1 and 2 will _also_ be activated, for the purposes of fallbacks (so a given key will fall back from 3 to 2, to 1 -- and only then to 0).
#### Naming your macros
If you have a bunch of macros you want to refer to from your keymap, while keeping the keymap easily readable, you can just name them like so:
```
#define AUD_OFF M(6)
#define AUD_ON M(7)
#define MUS_OFF M(8)
#define MUS_ON M(9)
#define VC_IN M(10)
#define VC_DE M(11)
#define PLOVER M(12)
#define EXT_PLV M(13)
```
As was done on the [Planck default keymap](/keyboards/planck/keymaps/default/keymap.c#L33-L40)
#### Timer functionality
It's possible to start timers and read values for time-specific events - here's an example:
```c
static uint16_t key_timer;
key_timer = timer_read();
if (timer_elapsed(key_timer) < 100) {
// do something if less than 100ms have passed
} else {
// do something if 100ms or more have passed
}
```
It's best to declare the `static uint16_t key_timer;` outside of the macro block (top of file, etc).
#### Example: Single-key copy/paste (hold to copy, tap to paste)
With QMK, it's easy to make one key do two things, as long as one of those things is being a modifier. :) So if you want a key to act as Ctrl when held and send the letter R when tapped, that's easy: `CTL_T(KC_R)`. But what do you do when you want that key to send Ctrl-V (paste) when tapped, and Ctrl-C (copy) when held?
Here's what you do:
```
static uint16_t key_timer;
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0: {
if (record->event.pressed) {
key_timer = timer_read(); // if the key is being pressed, we start the timer.
}
else { // this means the key was just released, so we can figure out how long it was pressed for (tap or "held down").
if (timer_elapsed(key_timer) > 150) { // 150 being 150ms, the threshhold we pick for counting something as a tap.
return MACRO( D(LCTL), T(C), U(LCTL), END );
}
else {
return MACRO( D(LCTL), T(V), U(LCTL), END );
}
}
break;
}
}
return MACRO_NONE;
};
```
And then, to assign this macro to a key on your keyboard layout, you just use `M(0)` on the key you want to press for copy/paste.
## Dynamic macros: record and replay macros in runtime
In addition to the static macros described above, you may enable the dynamic macros which you may record while writing. They are forgotten as soon as the keyboard is unplugged. Only two such macros may be stored at the same time, with the total length of 64 keypresses (by default).
To enable them, first add a new element to the `planck_keycodes` enum -- `DYNAMIC_MACRO_RANGE`:
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV,
DYNAMIC_MACRO_RANGE,
};
Afterwards create a new layer called `_DYN`:
#define _DYN 6 /* almost any other free number should be ok */
Below these two modifications include the `dynamic_macro.h` header:
#include "dynamic_macro.h"`
Then define the `_DYN` layer with the following keys: `DYN_REC_START1`, `DYN_MACRO_PLAY1`,`DYN_REC_START2` and `DYN_MACRO_PLAY2`. It may also contain other keys, it doesn't matter apart from the fact that you won't be able to record these keys in the dynamic macros.
[_DYN]= {
{_______, DYN_REC_START1, DYN_MACRO_PLAY1, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, DYN_REC_START2, DYN_MACRO_PLAY2, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
Add the following code to the very beginning of your `process_record_user()` function:
if (!process_record_dynamic_macro(keycode, record)) {
return false;
}
To start recording the macro, press either `DYN_REC_START1` or `DYN_REC_START2`. To finish the recording, press the `_DYN` layer button. The handler awaits specifically for the `MO(_DYN)` keycode as the "stop signal" so please don't use any fancy ways to access this layer, use the regular `MO()` modifier. To replay the macro, press either `DYN_MACRO_PLAY1` or `DYN_MACRO_PLAY2`.
If the LED-s start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by setting the `DYNAMIC_MACRO_SIZE` preprocessor macro (default value: 128; please read the comments for it in the header).
For the details about the internals of the dynamic macros, please read the comments in the `dynamic_macro.h` header.
## Additional keycode aliases for software-implemented layouts (Colemak, Dvorak, etc)
Everything is assuming you're in Qwerty (in software) by default, but there is built-in support for using a Colemak or Dvorak layout by including this at the top of your keymap:
#include <keymap_colemak.h>
If you use Dvorak, use `keymap_dvorak.h` instead of `keymap_colemak.h` for this line. After including this line, you will get access to:
* `CM_*` for all of the Colemak-equivalent characters
* `DV_*` for all of the Dvorak-equivalent characters
These implementations assume you're using Colemak or Dvorak on your OS, not on your keyboard - this is referred to as a software-implemented layout. If your computer is in Qwerty and your keymap is in Colemak or Dvorak, this is referred to as a firmware-implemented layout, and you won't need these features.
To give an example, if you're using software-implemented Colemak, and want to get an `F`, you would use `CM_F` - `KC_F` under these same circumstances would result in `T`.
## Additional language support
In `quantum/keymap_extras/`, you'll see various language files - these work the same way as the alternative layout ones do. Most are defined by their two letter country/language code followed by an underscore and a 4-letter abbreviation of its name. `FR_UGRV` which will result in a `ù` when using a software-implemented AZERTY layout. It's currently difficult to send such characters in just the firmware (but it's being worked on - see Unicode support).
## Unicode support
You can currently send 4 hex digits with your OS-specific modifier key (RALT for OSX with the "Unicode Hex Input" layout) - this is currently limited to supporting one OS at a time, and requires a recompile for switching. 8 digit hex codes are being worked on. The keycode function is `UC(n)`, where *n* is a 4 digit hexidecimal. Enable from the Makefile.
## Backlight Breathing
In order to enable backlight breathing, the following line must be added to your config.h file.
#define BACKLIGHT_BREATHING
The following function calls are used to control the breathing effect.
* ```breathing_enable()``` - Enable the free-running breathing effect.
* ```breathing_disable()``` - Disable the free-running breathing effect immediately.
* ```breathing_self_disable()``` - Disable the free-running breathing effect after the current effect ends.
* ```breathing_toggle()``` - Toggle the free-running breathing effect.
* ```breathing_defaults()``` - Reset the speed and brightness settings of the breathing effect.
The following function calls are used to control the maximum brightness of the breathing effect.
* ```breathing_intensity_set(value)``` - Set the brightness of the breathing effect when it is at its max value.
* ```breathing_intensity_default()``` - Reset the brightness of the breathing effect to the default value based on the current backlight intensity.
The following function calls are used to control the cycling speed of the breathing effect.
* ```breathing_speed_set(value)``` - Set the speed of the breathing effect - how fast it cycles.
* ```breathing_speed_inc(value)``` - Increase the speed of the breathing effect by a fixed value.
* ```breathing_speed_dec(value)``` - Decrease the speed of the breathing effect by a fixed value.
* ```breathing_speed_default()``` - Reset the speed of the breathing effect to the default value.
The following example shows how to enable the backlight breathing effect when the FUNCTION layer macro button is pressed:
case MACRO_FUNCTION:
if (record->event.pressed)
{
breathing_speed_set(3);
breathing_enable();
layer_on(LAYER_FUNCTION);
}
else
{
breathing_speed_set(1);
breathing_self_disable();
layer_off(LAYER_FUNCTION);
}
break;
The following example shows how to pulse the backlight on-off-on when the RAISED layer macro button is pressed:
case MACRO_RAISED:
if (record->event.pressed)
{
layer_on(LAYER_RAISED);
breathing_speed_set(2);
breathing_pulse();
update_tri_layer(LAYER_LOWER, LAYER_RAISED, LAYER_ADJUST);
}
else
{
layer_off(LAYER_RAISED);
update_tri_layer(LAYER_LOWER, LAYER_RAISED, LAYER_ADJUST);
}
break;
## Other firmware shortcut keycodes
* `RESET` - puts the MCU in DFU mode for flashing new firmware (with `make dfu`)
* `DEBUG` - the firmware into debug mode - you'll need hid_listen to see things
* `BL_ON` - turns the backlight on
* `BL_OFF` - turns the backlight off
* `BL_<n>` - sets the backlight to level *n*
* `BL_INC` - increments the backlight level by one
* `BL_DEC` - decrements the backlight level by one
* `BL_TOGG` - toggles the backlight
* `BL_STEP` - steps through the backlight levels
Enable the backlight from the Makefile.
# Custom Quantum functions
All of these functions are available in the `*_kb()` or `*_user()` variety. `kb` ones should only be used in the `<keyboard>/<keyboard>.c` file, and `user` ones should only be used in the `keymap.c`. The keyboard ones call the user ones - it's necessary to keep these calls to allow the keymap functions to work correctly.
## `void matrix_init_*(void)`
This function gets called when the matrix is initiated, and can contain start-up code for your keyboard/keymap.
## `void matrix_scan_*(void)`
This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot.
## `bool process_record_*(uint16_t keycode, keyrecord_t *record)`
This function gets called on every keypress/release, and is where you can define custom functionality. The return value is whether or not QMK should continue processing the keycode - returning `false` stops the execution.
The `keycode` variable is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. and can be switch-cased to execute code whenever a particular code is pressed.
The `record` variable contains infomation about the actual press:
```
keyrecord_t record {
keyevent_t event {
keypos_t key {
uint8_t col
uint8_t row
}
bool pressed
uint16_t time
}
}
```
The conditional `if (record->event.pressed)` can tell if the key is being pressed or released, and you can execute code based on that.
## `void led_set_*(uint8_t usb_led)`
This gets called whenever there is a state change on your host LEDs (eg caps lock, scroll lock, etc). The LEDs are defined as:
```
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
```
and can be tested against the `usb_led` with a conditional like `if (usb_led & (1<<USB_LED_CAPS_LOCK))` - if this is true, you can turn your LED one, otherwise turn it off.
# Modding your keyboard
## Audio output from a speaker
Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any keyboard that allows access to the C6 port, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes.
The audio code lives in [quantum/audio/audio.h](/quantum/audio/audio.h) and in the other files in the audio directory. It's enabled by default on the Planck [stock keymap](/keyboards/planck/keymaps/default/keymap.c). Here are the important bits:
```
#include "audio.h"
```
Then, lower down the file:
```
float tone_startup[][2] = {
ED_NOTE(_E7 ),
E__NOTE(_CS7),
E__NOTE(_E6 ),
E__NOTE(_A6 ),
M__NOTE(_CS7, 20)
};
```
This is how you write a song. Each of these lines is a note, so we have a little ditty composed of five notes here.
Then, we have this chunk:
```
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 goodbye[][2] = SONG(GOODBYE_SOUND);
```
Wherein we bind predefined songs (from [quantum/audio/song_list.h](/quantum/audio/song_list.h)) into named variables. This is one optimization that helps save on memory: These songs only take up memory when you reference them in your keymap, because they're essentially all preprocessor directives.
So now you have something called `tone_plover` for example. How do you make it play the Plover tune, then? If you look further down the keymap, you'll see this:
```
PLAY_NOTE_ARRAY(tone_plover, false, 0); // Signature is: Song name, repeat, rest style
```
This is inside one of the macros. So when that macro executes, your keyboard plays that particular chime.
"Rest style" in the method signature above (the last parameter) specifies if there's a rest (a moment of silence) between the notes.
## Recording And Playing back Music
* ```Music On``` - Turn music mode on. The default mapping is ```Lower+Upper+C```
* ```LCTL``` - start a recording
* play some tones
* ```LALT``` - stop recording, stop playing
* ```LGUI``` - play recording
* ```LALT``` - stop playing
* ```Music Off``` - Turn music mode off. The default mapping is ```Lower+Upper+V```
## MIDI functionalty
This is still a WIP, but check out `quantum/keymap_midi.c` to see what's happening. Enable from the Makefile.
## Bluetooth functionality
This requires [some hardware changes](https://www.reddit.com/r/MechanicalKeyboards/comments/3psx0q/the_planck_keyboard_with_bluetooth_guide_and/?ref=search_posts), but can be enabled via the Makefile. The firmware will still output characters via USB, so be aware of this when charging via a computer. It would make sense to have a switch on the Bluefruit to turn it off at will.
## International Characters on Windows
[AutoHotkey](https://autohotkey.com) allows Windows users to create custom hotkeys among others.
The method does not require Unicode support in the keyboard itself but depends instead of AutoHotkey running in the background.
First you need to select a modifier combination that is not in use by any of your programs.
CtrlAltWin is not used very widely and should therefore be perfect for this.
There is a macro defined for a mod-tab combo `LCAG_T`.
Add this mod-tab combo to a key on your keyboard, e.g.: `LCAG_T(KC_TAB)`.
This makes the key behave like a tab key if pressed and released immediately but changes it to the modifier if used with another key.
In the default script of AutoHotkey you can define custom hotkeys.
<^<!<#a::Send, ä
<^<!<#<+a::Send, Ä
The hotkeys above are for the combination CtrlAltGui and CtrlAltGuiShift plus the letter a.
AutoHotkey inserts the Text right of `Send, ` when this combination is pressed.
## RGB Under Glow Mod
![Planck with RGB Underglow](https://raw.githubusercontent.com/jackhumbert/qmk_firmware/master/keyboards/planck/keymaps/yang/planck-with-rgb-underglow.jpg)
Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY).
For this mod, you need an unused pin wiring to DI of WS2812 strip. After wiring the VCC, GND, and DI, you can enable the underglow in your Makefile.
RGBLIGHT_ENABLE = yes
In order to use the underglow timer functions, you need to have `#define RGBLIGHT_TIMER` in your `config.h`, and have audio disabled (`AUDIO_ENABLE = no` in your Makefile).
Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the `F4` pin by default:
#define RGB_DI_PIN F4 // The pin your RGB strip is wired to
#define RGBLIGHT_TIMER // Require for fancier stuff (not compatible with audio)
#define RGBLED_NUM 14 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
You'll need to edit `RGB_DI_PIN` to the pin you have your `DI` on your RGB strip wired to.
The firmware supports 5 different light effects, and the color (hue, saturation, brightness) can be customized in most effects. To control the underglow, you need to modify your keymap file to assign those functions to some keys/key combinations. For details, please check this keymap. `keyboards/planck/keymaps/yang/keymap.c`
### WS2812 Wiring
![WS2812 Wiring](https://raw.githubusercontent.com/jackhumbert/qmk_firmware/master/keyboards/planck/keymaps/yang/WS2812-wiring.jpg)
Please note the USB port can only supply a limited amount of power to the keyboard (500mA by standard, however, modern computer and most usb hubs can provide 700+mA.). According to the data of NeoPixel from Adafruit, 30 WS2812 LEDs require a 5V 1A power supply, LEDs used in this mod should not more than 20.
## Safety Considerations
You probably don't want to "brick" your keyboard, making it impossible
to rewrite firmware onto it. Here are some of the parameters to show
what things are (and likely aren't) too risky.
- If a keyboard map does not include RESET, then, to get into DFU
mode, you will need to press the reset button on the PCB, which
requires unscrewing some bits.
- Messing with tmk_core / common files might make the keyboard
inoperable
- Too large a .hex file is trouble; `make dfu` will erase the block,
test the size (oops, wrong order!), which errors out, failing to
flash the keyboard
- DFU tools do /not/ allow you to write into the bootloader (unless
you throw in extra fruitsalad of options), so there is little risk
there.
- EEPROM has around a 100000 write cycle. You shouldn't rewrite the
firmware repeatedly and continually; that'll burn the EEPROM
eventually.
# Porting your keyboard to QMK
If your keyboard is running an Atmega chip (atmega32u4 and others), it's pretty easy to get things setup for compiling your own firmware to flash onto your board. There is a `/util/new_project.sh <keyboard>` script to help get you started - you can simply pass your keyboard's name into the script, and all of the necessary files will be created. The components of each are described below.
## `/keyboards/<keyboard>/config.h`
The `USB Device descriptor parameter` block contains parameters are used to uniquely identify your keyboard, but they don't really matter to the machine.
Your `MATRIX_ROWS` and `MATRIX_COLS` are the numbers of rows and cols in your keyboard matrix - this may be different than the number of actual rows and columns on your keyboard. There are some tricks you can pull to increase the number of keys in a given matrix, but most keyboards are pretty straight-forward.
The `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` are the pins your MCU uses on each row/column. Your schematic (if you have one) will have this information on it, and the values will vary depending on your setup. This is one of the most important things to double-check in getting your keyboard setup correctly.
For the `DIODE_DIRECTION`, most hand-wiring guides will instruct you to wire the diodes in the `COL2ROW` position, but it's possible that they are in the other - people coming from EasyAVR often use `ROW2COL`. Nothing will function if this is incorrect.
`BACKLIGHT_PIN` is the pin that your PWM-controlled backlight (if one exists) is hooked-up to. Currently only B5, B6, and B7 are supported.
`BACKLIGHT_BREATHING` is a fancier backlight feature that adds breathing/pulsing/fading effects to the backlight. It uses the same timer as the normal backlight. These breathing effects must be called by code in your keymap.
`BACKLIGHT_LEVELS` is how many levels exist for your backlight - max is 15, and they are computed automatically from this number.
## `/keyboards/<keyboard>/Makefile`
The values at the top likely won't need to be changed, since most boards use the `atmega32u4` chip. The `BOOTLOADER_SIZE` will need to be adjusted based on your MCU type. It's defaulted to the Teensy, since that's the most common controller. Below is quoted from the `Makefile`.
```
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
```
At the bottom of the file, you'll find lots of features to turn on and off - all of these options should be set with `?=` to allow for the keymap overrides. `?=` only assigns if the variable was previously undefined. For the full documenation of these features, see the [Makefile options](#makefile-options).
## `/keyboards/<keyboard>/readme.md`
This is where you'll describe your keyboard - please write as much as you can about it! Talking about default functionality/features is useful here. Feel free to link to external pages/sites if necessary. Images can be included here as well. This file will be rendered into a webpage at qmk.fm/keyboards/<keyboard>/.
## `/keyboards/<keyboard>/<keyboard>.c`
This is where all of the custom logic for your keyboard goes - you may not need to put anything in this file, since a lot of things are configured automatically. All of the `*_kb()` functions are defined here. If you modify them, remember to keep the calls to `*_user()`, or things in the keymaps might not work. You can read more about the functions [here](#custom-quantum-functions-for-keyboards-and-keymaps)
## `/keyboards/<keyboard>/<keyboard>.h`
Here is where you can (optionally) define your `KEYMAP` function to remap your matrix into a more readable format. With ortholinear boards, this isn't always necessary, but it can help to accomodate the dead spots on your matrix, where there are keys that take up more than one space (2u, staggering, 6.25u, etc). The example shows the difference between the physical keys, and the matrix design:
```
#define KEYMAP( \
k00, k01, k02, \
k10, k11 \
) \
{ \
{ k00, k01, k02 }, \
{ k10, KC_NO, k11 }, \
}
```
Each of the `kxx` variables needs to be unique, and usually follows the format `k<row><col>`. You can place `KC_NO` where your dead keys are in your matrix.
# Unit Testing
If you are new to unit testing, then you can find many good resources on internet. However most of it is scattered around in small pieces here and there, and there's also many different opinions, so I won't give any recommendations.
Instead I recommend these two books, explaining two different styles of Unit Testing in detail.
* "Test Driven Development: By Example: Kent Beck"
* "Growing Object-Oriented Software, Guided By Tests: Steve Freeman, Nat Pryce"
If you prefer videos there are Uncle Bob's [Clean Coders Videos](https://cleancoders.com/), which unfortunately cost quite a bit, especially if you want to watch many of them. But James Shore has a free [Let's Play](http://www.jamesshore.com/Blog/Lets-Play) video series.
## Google Test and Google Mock
It's possible to Unit Test your code using [Google Test](https://github.com/google/googletest). The Google Test framework also includes another component for writing testing mocks and stubs, called "Google Mock". For information how to write the actual tests, please refer to the documentation on that site.
## Use of C++
Note that Google Test and therefore any test has to be written in C++, even if the rest of the QMK codebases is written in C. This should hopefully not be a problem even if you don't know any C++, since there's quite clear documentation and examples of the required C++ features, and you can write the rest of the test code almost as you would write normal C. Note that some compiler errors which you might get can look quite scary, but just read carefully what it says, and you should be ok.
One thing to remember, is that you have to append `extern "C"` around all of your C file includes.
## Adding tests for new or existing features
If you want to unit test some feature, then take a look at the existing serial_link tests, in the `quantum/serial_link/tests folder`, and follow the steps below to create a similar structure.
1. If it doesn't already exist, add a test subfolder to the folder containing the feature.
2. Create a `testlist.mk` and a `rules.mk` file in that folder.
3. Include those files from the root folder `testlist.mk`and `build_test.mk` respectively.
4. Add a new name for your testgroup to the `testlist.mk` file. Each group defined there will be a separate executable. And that's how you can support mocking out different parts. Note that it's worth adding some common prefix, just like it's done for the serial_link tests. The reason for that is that the make command allows substring filtering, so this way you can easily run a subset of the tests.
5. Define the source files and required options in the `rules.mk` file.
* `_SRC` for source files
* `_DEFS` for additional defines
* `_INC` for additional include folders
6. Write the tests in a new cpp file inside the test folder you created. That file has to be one of the files included from the `rules.mk` file.
Note how there's several different tests, each mocking out a separate part. Also note that each of them only compiles the very minimum that's needed for the tests. It's recommend that you try to do the same. For a relevant video check out [Matt Hargett "Advanced Unit Testing in C & C++](https://www.youtube.com/watch?v=Wmy6g-aVgZI)
## Running the tests
To run all the tests in the codebase, type `make test`. You can also run test matching a substring by typing `make test-matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer.
## Debugging the tests
If there are problems with the tests, you can find the executable in the `./build/test` folder. You should be able to run those with GDB or a similar debugger.
## Full Integration tests
It's not yet possible to do a full integration test, where you would compile the whole firmware and define a keymap that you are going to test. However there are plans for doing that, because writing tests that way would probably be easier, at least for people that are not used to unit testing.
In that model you would emulate the input, and expect a certain output from the emulated keyboard.

@ -26,7 +26,7 @@ CFLAGS += -fno-inline-small-functions
CFLAGS += -fno-strict-aliasing
CPPFLAGS += $(COMPILEFLAGS)
CPPFLAGS += -fno-exceptions
CPPFLAGS += -fno-exceptions -std=c++11
LDFLAGS +=-Wl,--gc-sections

@ -50,6 +50,10 @@ ifeq ($(strip $(EXTRAKEY_ENABLE)), yes)
TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE
endif
ifeq ($(strip $(RAW_ENABLE)), yes)
TMK_COMMON_DEFS += -DRAW_ENABLE
endif
ifeq ($(strip $(CONSOLE_ENABLE)), yes)
TMK_COMMON_DEFS += -DCONSOLE_ENABLE
else
@ -81,6 +85,10 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
TMK_COMMON_DEFS += -DBACKLIGHT_ENABLE
endif
ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
TMK_COMMON_DEFS += -DADAFRUIT_BLE_ENABLE
endif
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
endif
@ -110,4 +118,4 @@ endif
VPATH += $(TMK_PATH)/$(COMMON_DIR)
ifeq ($(PLATFORM),CHIBIOS)
VPATH += $(TMK_PATH)/$(COMMON_DIR)/chibios
endif
endif

@ -47,6 +47,7 @@ void suspend_idle(uint8_t time)
sleep_disable();
}
#ifndef NO_SUSPEND_POWER_DOWN
/* Power down MCU with watchdog timer
* wdto: watchdog timer timeout defined in <avr/wdt.h>
* WDTO_15MS
@ -61,6 +62,7 @@ void suspend_idle(uint8_t time)
* WDTO_8S
*/
static uint8_t wdt_timeout = 0;
static void power_down(uint8_t wdto)
{
#ifdef PROTOCOL_LUFA
@ -98,19 +100,19 @@ static void power_down(uint8_t wdto)
// Disable watchdog after sleep
wdt_disable();
}
#endif
void suspend_power_down(void)
{
#ifndef NO_SUSPEND_POWER_DOWN
power_down(WDTO_15MS);
#endif
}
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void)
{
#ifdef BACKLIGHT_ENABLE
backlight_set(0);
#endif
matrix_power_up();
matrix_scan();
matrix_power_down();
@ -126,10 +128,9 @@ void suspend_wakeup_init(void)
// clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_set(0);
backlight_init();
#endif
led_set(host_keyboard_leds());
led_set(host_keyboard_leds());
}
#ifndef NO_SUSPEND_POWER_DOWN

@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
#include <stdint.h>
#include "timer_avr.h"
#include "timer.h"
@ -24,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// counter resolution 1ms
// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
volatile uint32_t timer_count = 0;
volatile uint32_t timer_count;
void timer_init(void)
{
@ -52,10 +53,9 @@ void timer_init(void)
inline
void timer_clear(void)
{
uint8_t sreg = SREG;
cli();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
timer_count = 0;
SREG = sreg;
}
}
inline
@ -63,10 +63,9 @@ uint16_t timer_read(void)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
return (t & 0xFFFF);
}
@ -76,10 +75,9 @@ uint32_t timer_read32(void)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
return t;
}
@ -89,10 +87,9 @@ uint16_t timer_elapsed(uint16_t last)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
return TIMER_DIFF_16((t & 0xFFFF), last);
}
@ -102,10 +99,9 @@ uint32_t timer_elapsed32(uint32_t last)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
return TIMER_DIFF_32(t, last);
}

@ -36,9 +36,9 @@ void backlight_increase(void)
if(backlight_config.level < BACKLIGHT_LEVELS)
{
backlight_config.level++;
backlight_config.enable = 1;
eeconfig_update_backlight(backlight_config.raw);
}
backlight_config.enable = 1;
eeconfig_update_backlight(backlight_config.raw);
dprintf("backlight increase: %u\n", backlight_config.level);
backlight_set(backlight_config.level);
}

@ -379,11 +379,11 @@ static bool command_common(uint8_t code)
debug_enable = !debug_enable;
if (debug_enable) {
print("\ndebug: on\n");
debug_matrix = true;
debug_keyboard = true;
debug_mouse = true;
} else {
print("\ndebug: off\n");
debug_matrix = false;
debug_keyboard = false;
debug_mouse = false;
}
break;

@ -20,7 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "report.h"
#ifdef MIDI_ENABLE
#include "midi.h"
#endif
typedef struct {
uint8_t (*keyboard_leds)(void);
@ -28,6 +30,11 @@ typedef struct {
void (*send_mouse)(report_mouse_t *);
void (*send_system)(uint16_t);
void (*send_consumer)(uint16_t);
#ifdef MIDI_ENABLE
void (*usb_send_func)(MidiDevice *, uint16_t, uint8_t, uint8_t, uint8_t);
void (*usb_get_midi)(MidiDevice *);
void (*midi_usb_init)(MidiDevice *);
#endif
} host_driver_t;
#endif

@ -85,7 +85,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_LCAP KC_LOCKING_CAPS
#define KC_LNUM KC_LOCKING_NUM
#define KC_LSCR KC_LOCKING_SCROLL
#define KC_ERAS KC_ALT_ERASE,
#define KC_ERAS KC_ALT_ERASE
#define KC_CLR KC_CLEAR
/* Japanese specific */
#define KC_ZKHK KC_GRAVE

@ -0,0 +1,8 @@
#ifndef _RAW_HID_H_
#define _RAW_HID_H_
void raw_hid_receive( uint8_t *data, uint8_t length );
void raw_hid_send( uint8_t *data, uint8_t length );
#endif

@ -21,6 +21,10 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)
include $(TMK_PATH)/protocol/midi.mk
endif
ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
endif
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
$(TMK_DIR)/protocol/serial_uart.c

@ -0,0 +1,805 @@
#include "adafruit_ble.h"
#include <stdio.h>
#include <stdlib.h>
#include <alloca.h>
#include <util/delay.h>
#include <util/atomic.h>
#include "debug.h"
#include "pincontrol.h"
#include "timer.h"
#include "action_util.h"
#include "ringbuffer.hpp"
#include <string.h>
// These are the pin assignments for the 32u4 boards.
// You may define them to something else in your config.h
// if yours is wired up differently.
#ifndef AdafruitBleResetPin
#define AdafruitBleResetPin D4
#endif
#ifndef AdafruitBleCSPin
#define AdafruitBleCSPin B4
#endif
#ifndef AdafruitBleIRQPin
#define AdafruitBleIRQPin E6
#endif
#define SAMPLE_BATTERY
#define ConnectionUpdateInterval 1000 /* milliseconds */
static struct {
bool is_connected;
bool initialized;
bool configured;
#define ProbedEvents 1
#define UsingEvents 2
bool event_flags;
#ifdef SAMPLE_BATTERY
uint16_t last_battery_update;
uint32_t vbat;
#endif
uint16_t last_connection_update;
} state;
// Commands are encoded using SDEP and sent via SPI
// https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/blob/master/SDEP.md
#define SdepMaxPayload 16
struct sdep_msg {
uint8_t type;
uint8_t cmd_low;
uint8_t cmd_high;
struct __attribute__((packed)) {
uint8_t len:7;
uint8_t more:1;
};
uint8_t payload[SdepMaxPayload];
} __attribute__((packed));
// The recv latency is relatively high, so when we're hammering keys quickly,
// we want to avoid waiting for the responses in the matrix loop. We maintain
// a short queue for that. Since there is quite a lot of space overhead for
// the AT command representation wrapped up in SDEP, we queue the minimal
// information here.
enum queue_type {
QTKeyReport, // 1-byte modifier + 6-byte key report
QTConsumer, // 16-bit key code
#ifdef MOUSE_ENABLE
QTMouseMove, // 4-byte mouse report
#endif
};
struct queue_item {
enum queue_type queue_type;
uint16_t added;
union __attribute__((packed)) {
struct __attribute__((packed)) {
uint8_t modifier;
uint8_t keys[6];
} key;
uint16_t consumer;
struct __attribute__((packed)) {
int8_t x, y, scroll, pan;
} mousemove;
};
};
// Items that we wish to send
static RingBuffer<queue_item, 40> send_buf;
// Pending response; while pending, we can't send any more requests.
// This records the time at which we sent the command for which we
// are expecting a response.
static RingBuffer<uint16_t, 2> resp_buf;
static bool process_queue_item(struct queue_item *item, uint16_t timeout);
enum sdep_type {
SdepCommand = 0x10,
SdepResponse = 0x20,
SdepAlert = 0x40,
SdepError = 0x80,
SdepSlaveNotReady = 0xfe, // Try again later
SdepSlaveOverflow = 0xff, // You read more data than is available
};
enum ble_cmd {
BleInitialize = 0xbeef,
BleAtWrapper = 0x0a00,
BleUartTx = 0x0a01,
BleUartRx = 0x0a02,
};
enum ble_system_event_bits {
BleSystemConnected = 0,
BleSystemDisconnected = 1,
BleSystemUartRx = 8,
BleSystemMidiRx = 10,
};
// The SDEP.md file says 2MHz but the web page and the sample driver
// both use 4MHz
#define SpiBusSpeed 4000000
#define SdepTimeout 150 /* milliseconds */
#define SdepShortTimeout 10 /* milliseconds */
#define SdepBackOff 25 /* microseconds */
#define BatteryUpdateInterval 10000 /* milliseconds */
static bool at_command(const char *cmd, char *resp, uint16_t resplen,
bool verbose, uint16_t timeout = SdepTimeout);
static bool at_command_P(const char *cmd, char *resp, uint16_t resplen,
bool verbose = false);
struct SPI_Settings {
uint8_t spcr, spsr;
};
static struct SPI_Settings spi;
// Initialize 4Mhz MSBFIRST MODE0
void SPI_init(struct SPI_Settings *spi) {
spi->spcr = _BV(SPE) | _BV(MSTR);
spi->spsr = _BV(SPI2X);
static_assert(SpiBusSpeed == F_CPU / 2, "hard coded at 4Mhz");
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
// Ensure that SS is OUTPUT High
digitalWrite(B0, PinLevelHigh);
pinMode(B0, PinDirectionOutput);
SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);
pinMode(B1 /* SCK */, PinDirectionOutput);
pinMode(B2 /* MOSI */, PinDirectionOutput);
}
}
static inline void SPI_begin(struct SPI_Settings*spi) {
SPCR = spi->spcr;
SPSR = spi->spsr;
}
static inline uint8_t SPI_TransferByte(uint8_t data) {
SPDR = data;
asm volatile("nop");
while (!(SPSR & _BV(SPIF))) {
; // wait
}
return SPDR;
}
static inline void spi_send_bytes(const uint8_t *buf, uint8_t len) {
if (len == 0) return;
const uint8_t *end = buf + len;
while (buf < end) {
SPDR = *buf;
while (!(SPSR & _BV(SPIF))) {
; // wait
}
++buf;
}
}
static inline uint16_t spi_read_byte(void) {
return SPI_TransferByte(0x00 /* dummy */);
}
static inline void spi_recv_bytes(uint8_t *buf, uint8_t len) {
const uint8_t *end = buf + len;
if (len == 0) return;
while (buf < end) {
SPDR = 0; // write a dummy to initiate read
while (!(SPSR & _BV(SPIF))) {
; // wait
}
*buf = SPDR;
++buf;
}
}
#if 0
static void dump_pkt(const struct sdep_msg *msg) {
print("pkt: type=");
print_hex8(msg->type);
print(" cmd=");
print_hex8(msg->cmd_high);
print_hex8(msg->cmd_low);
print(" len=");
print_hex8(msg->len);
print(" more=");
print_hex8(msg->more);
print("\n");
}
#endif
// Send a single SDEP packet
static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
SPI_begin(&spi);
digitalWrite(AdafruitBleCSPin, PinLevelLow);
uint16_t timerStart = timer_read();
bool success = false;
bool ready = false;
do {
ready = SPI_TransferByte(msg->type) != SdepSlaveNotReady;
if (ready) {
break;
}
// Release it and let it initialize
digitalWrite(AdafruitBleCSPin, PinLevelHigh);
_delay_us(SdepBackOff);
digitalWrite(AdafruitBleCSPin, PinLevelLow);
} while (timer_elapsed(timerStart) < timeout);
if (ready) {
// Slave is ready; send the rest of the packet
spi_send_bytes(&msg->cmd_low,
sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len);
success = true;
}
digitalWrite(AdafruitBleCSPin, PinLevelHigh);
return success;
}
static inline void sdep_build_pkt(struct sdep_msg *msg, uint16_t command,
const uint8_t *payload, uint8_t len,
bool moredata) {
msg->type = SdepCommand;
msg->cmd_low = command & 0xff;
msg->cmd_high = command >> 8;
msg->len = len;
msg->more = (moredata && len == SdepMaxPayload) ? 1 : 0;
static_assert(sizeof(*msg) == 20, "msg is correctly packed");
memcpy(msg->payload, payload, len);
}
// Read a single SDEP packet
static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
bool success = false;
uint16_t timerStart = timer_read();
bool ready = false;
do {
ready = digitalRead(AdafruitBleIRQPin);
if (ready) {
break;
}
_delay_us(1);
} while (timer_elapsed(timerStart) < timeout);
if (ready) {
SPI_begin(&spi);
digitalWrite(AdafruitBleCSPin, PinLevelLow);
do {
// Read the command type, waiting for the data to be ready
msg->type = spi_read_byte();
if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) {
// Release it and let it initialize
digitalWrite(AdafruitBleCSPin, PinLevelHigh);
_delay_us(SdepBackOff);
digitalWrite(AdafruitBleCSPin, PinLevelLow);
continue;
}
// Read the rest of the header
spi_recv_bytes(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)));
// and get the payload if there is any
if (msg->len <= SdepMaxPayload) {
spi_recv_bytes(msg->payload, msg->len);
}
success = true;
break;
} while (timer_elapsed(timerStart) < timeout);
digitalWrite(AdafruitBleCSPin, PinLevelHigh);
}
return success;
}
static void resp_buf_read_one(bool greedy) {
uint16_t last_send;
if (!resp_buf.peek(last_send)) {
return;
}
if (digitalRead(AdafruitBleIRQPin)) {
struct sdep_msg msg;
again:
if (sdep_recv_pkt(&msg, SdepTimeout)) {
if (!msg.more) {
// We got it; consume this entry
resp_buf.get(last_send);
dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send));
}
if (greedy && resp_buf.peek(last_send) && digitalRead(AdafruitBleIRQPin)) {
goto again;
}
}
} else if (timer_elapsed(last_send) > SdepTimeout * 2) {
dprintf("waiting_for_result: timeout, resp_buf size %d\n",
(int)resp_buf.size());
// Timed out: consume this entry
resp_buf.get(last_send);
}
}
static void send_buf_send_one(uint16_t timeout = SdepTimeout) {
struct queue_item item;
// Don't send anything more until we get an ACK
if (!resp_buf.empty()) {
return;
}
if (!send_buf.peek(item)) {
return;
}
if (process_queue_item(&item, timeout)) {
// commit that peek
send_buf.get(item);
dprintf("send_buf_send_one: have %d remaining\n", (int)send_buf.size());
} else {
dprint("failed to send, will retry\n");
_delay_ms(SdepTimeout);
resp_buf_read_one(true);
}
}
static void resp_buf_wait(const char *cmd) {
bool didPrint = false;
while (!resp_buf.empty()) {
if (!didPrint) {
dprintf("wait on buf for %s\n", cmd);
didPrint = true;
}
resp_buf_read_one(true);
}
}
static bool ble_init(void) {
state.initialized = false;
state.configured = false;
state.is_connected = false;
pinMode(AdafruitBleIRQPin, PinDirectionInput);
pinMode(AdafruitBleCSPin, PinDirectionOutput);
digitalWrite(AdafruitBleCSPin, PinLevelHigh);
SPI_init(&spi);
// Perform a hardware reset
pinMode(AdafruitBleResetPin, PinDirectionOutput);
digitalWrite(AdafruitBleResetPin, PinLevelHigh);
digitalWrite(AdafruitBleResetPin, PinLevelLow);
_delay_ms(10);
digitalWrite(AdafruitBleResetPin, PinLevelHigh);
_delay_ms(1000); // Give it a second to initialize
state.initialized = true;
return state.initialized;
}
static inline uint8_t min(uint8_t a, uint8_t b) {
return a < b ? a : b;
}
static bool read_response(char *resp, uint16_t resplen, bool verbose) {
char *dest = resp;
char *end = dest + resplen;
while (true) {
struct sdep_msg msg;
if (!sdep_recv_pkt(&msg, 2 * SdepTimeout)) {
dprint("sdep_recv_pkt failed\n");
return false;
}
if (msg.type != SdepResponse) {
*resp = 0;
return false;
}
uint8_t len = min(msg.len, end - dest);
if (len > 0) {
memcpy(dest, msg.payload, len);
dest += len;
}
if (!msg.more) {
// No more data is expected!
break;
}
}
// Ensure the response is NUL terminated
*dest = 0;
// "Parse" the result text; we want to snip off the trailing OK or ERROR line
// Rewind past the possible trailing CRLF so that we can strip it
--dest;
while (dest > resp && (dest[0] == '\n' || dest[0] == '\r')) {
*dest = 0;
--dest;
}
// Look back for start of preceeding line
char *last_line = strrchr(resp, '\n');
if (last_line) {
++last_line;
} else {
last_line = resp;
}
bool success = false;
static const char kOK[] PROGMEM = "OK";
success = !strcmp_P(last_line, kOK );
if (verbose || !success) {
dprintf("result: %s\n", resp);
}
return success;
}
static bool at_command(const char *cmd, char *resp, uint16_t resplen,
bool verbose, uint16_t timeout) {
const char *end = cmd + strlen(cmd);
struct sdep_msg msg;
if (verbose) {
dprintf("ble send: %s\n", cmd);
}
if (resp) {
// They want to decode the response, so we need to flush and wait
// for all pending I/O to finish before we start this one, so
// that we don't confuse the results
resp_buf_wait(cmd);
*resp = 0;
}
// Fragment the command into a series of SDEP packets
while (end - cmd > SdepMaxPayload) {
sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, SdepMaxPayload, true);
if (!sdep_send_pkt(&msg, timeout)) {
return false;
}
cmd += SdepMaxPayload;
}
sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, end - cmd, false);
if (!sdep_send_pkt(&msg, timeout)) {
return false;
}
if (resp == NULL) {
auto now = timer_read();
while (!resp_buf.enqueue(now)) {
resp_buf_read_one(false);
}
auto later = timer_read();
if (TIMER_DIFF_16(later, now) > 0) {
dprintf("waited %dms for resp_buf\n", TIMER_DIFF_16(later, now));
}
return true;
}
return read_response(resp, resplen, verbose);
}
bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose) {
auto cmdbuf = (char *)alloca(strlen_P(cmd) + 1);
strcpy_P(cmdbuf, cmd);
return at_command(cmdbuf, resp, resplen, verbose);
}
bool adafruit_ble_is_connected(void) {
return state.is_connected;
}
bool adafruit_ble_enable_keyboard(void) {
char resbuf[128];
if (!state.initialized && !ble_init()) {
return false;
}
state.configured = false;
// Disable command echo
static const char kEcho[] PROGMEM = "ATE=0";
// Make the advertised name match the keyboard
static const char kGapDevName[] PROGMEM =
"AT+GAPDEVNAME=" STR(PRODUCT) " " STR(DESCRIPTION);
// Turn on keyboard support
static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1";
// Adjust intervals to improve latency. This causes the "central"
// system (computer/tablet) to poll us every 10-30 ms. We can't
// set a smaller value than 10ms, and 30ms seems to be the natural
// processing time on my macbook. Keeping it constrained to that
// feels reasonable to type to.
static const char kGapIntervals[] PROGMEM = "AT+GAPINTERVALS=10,30,,";
// Reset the device so that it picks up the above changes
static const char kATZ[] PROGMEM = "ATZ";
// Turn down the power level a bit
static const char kPower[] PROGMEM = "AT+BLEPOWERLEVEL=-12";
static PGM_P const configure_commands[] PROGMEM = {
kEcho,
kGapIntervals,
kGapDevName,
kHidEnOn,
kPower,
kATZ,
};
uint8_t i;
for (i = 0; i < sizeof(configure_commands) / sizeof(configure_commands[0]);
++i) {
PGM_P cmd;
memcpy_P(&cmd, configure_commands + i, sizeof(cmd));
if (!at_command_P(cmd, resbuf, sizeof(resbuf))) {
dprintf("failed BLE command: %S: %s\n", cmd, resbuf);
goto fail;
}
}
state.configured = true;
// Check connection status in a little while; allow the ATZ time
// to kick in.
state.last_connection_update = timer_read();
fail:
return state.configured;
}
static void set_connected(bool connected) {
if (connected != state.is_connected) {
if (connected) {
print("****** BLE CONNECT!!!!\n");
} else {
print("****** BLE DISCONNECT!!!!\n");
}
state.is_connected = connected;
// TODO: if modifiers are down on the USB interface and
// we cut over to BLE or vice versa, they will remain stuck.
// This feels like a good point to do something like clearing
// the keyboard and/or generating a fake all keys up message.
// However, I've noticed that it takes a couple of seconds
// for macOS to to start recognizing key presses after BLE
// is in the connected state, so I worry that doing that
// here may not be good enough.
}
}
void adafruit_ble_task(void) {
char resbuf[48];
if (!state.configured && !adafruit_ble_enable_keyboard()) {
return;
}
resp_buf_read_one(true);
send_buf_send_one(SdepShortTimeout);
if (resp_buf.empty() && (state.event_flags & UsingEvents) &&
digitalRead(AdafruitBleIRQPin)) {
// Must be an event update
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
uint32_t mask = strtoul(resbuf, NULL, 16);
if (mask & BleSystemConnected) {
set_connected(true);
} else if (mask & BleSystemDisconnected) {
set_connected(false);
}
}
}
if (timer_elapsed(state.last_connection_update) > ConnectionUpdateInterval) {
bool shouldPoll = true;
if (!(state.event_flags & ProbedEvents)) {
// Request notifications about connection status changes.
// This only works in SPIFRIEND firmware > 0.6.7, which is why
// we check for this conditionally here.
// Note that at the time of writing, HID reports only work correctly
// with Apple products on firmware version 0.6.7!
// https://forums.adafruit.com/viewtopic.php?f=8&t=104052
if (at_command_P(PSTR("AT+EVENTENABLE=0x1"), resbuf, sizeof(resbuf))) {
at_command_P(PSTR("AT+EVENTENABLE=0x2"), resbuf, sizeof(resbuf));
state.event_flags |= UsingEvents;
}
state.event_flags |= ProbedEvents;
// leave shouldPoll == true so that we check at least once
// before relying solely on events
} else {
shouldPoll = false;
}
static const char kGetConn[] PROGMEM = "AT+GAPGETCONN";
state.last_connection_update = timer_read();
if (at_command_P(kGetConn, resbuf, sizeof(resbuf))) {
set_connected(atoi(resbuf));
}
}
#ifdef SAMPLE_BATTERY
// I don't know if this really does anything useful yet; the reported
// voltage level always seems to be around 3200mV. We may want to just rip
// this code out.
if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval &&
resp_buf.empty()) {
state.last_battery_update = timer_read();
if (at_command_P(PSTR("AT+HWVBAT"), resbuf, sizeof(resbuf))) {
state.vbat = atoi(resbuf);
}
}
#endif
}
static bool process_queue_item(struct queue_item *item, uint16_t timeout) {
char cmdbuf[48];
char fmtbuf[64];
// Arrange to re-check connection after keys have settled
state.last_connection_update = timer_read();
#if 1
if (TIMER_DIFF_16(state.last_connection_update, item->added) > 0) {
dprintf("send latency %dms\n",
TIMER_DIFF_16(state.last_connection_update, item->added));
}
#endif
switch (item->queue_type) {
case QTKeyReport:
strcpy_P(fmtbuf,
PSTR("AT+BLEKEYBOARDCODE=%02x-00-%02x-%02x-%02x-%02x-%02x-%02x"));
snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier,
item->key.keys[0], item->key.keys[1], item->key.keys[2],
item->key.keys[3], item->key.keys[4], item->key.keys[5]);
return at_command(cmdbuf, NULL, 0, true, timeout);
case QTConsumer:
strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x"));
snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer);
return at_command(cmdbuf, NULL, 0, true, timeout);
#ifdef MOUSE_ENABLE
case QTMouseMove:
strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d"));
snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->mousemove.x,
item->mousemove.y, item->mousemove.scroll, item->mousemove.pan);
return at_command(cmdbuf, NULL, 0, true, timeout);
#endif
default:
return true;
}
}
bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys,
uint8_t nkeys) {
struct queue_item item;
bool didWait = false;
item.queue_type = QTKeyReport;
item.key.modifier = hid_modifier_mask;
item.added = timer_read();
while (nkeys >= 0) {
item.key.keys[0] = keys[0];
item.key.keys[1] = nkeys >= 1 ? keys[1] : 0;
item.key.keys[2] = nkeys >= 2 ? keys[2] : 0;
item.key.keys[3] = nkeys >= 3 ? keys[3] : 0;
item.key.keys[4] = nkeys >= 4 ? keys[4] : 0;
item.key.keys[5] = nkeys >= 5 ? keys[5] : 0;
if (!send_buf.enqueue(item)) {
if (!didWait) {
dprint("wait for buf space\n");
didWait = true;
}
send_buf_send_one();
continue;
}
if (nkeys <= 6) {
return true;
}
nkeys -= 6;
keys += 6;
}
return true;
}
bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) {
struct queue_item item;
item.queue_type = QTConsumer;
item.consumer = keycode;
while (!send_buf.enqueue(item)) {
send_buf_send_one();
}
return true;
}
#ifdef MOUSE_ENABLE
bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll,
int8_t pan) {
struct queue_item item;
item.queue_type = QTMouseMove;
item.mousemove.x = x;
item.mousemove.y = y;
item.mousemove.scroll = scroll;
item.mousemove.pan = pan;
while (!send_buf.enqueue(item)) {
send_buf_send_one();
}
return true;
}
#endif
uint32_t adafruit_ble_read_battery_voltage(void) {
return state.vbat;
}
bool adafruit_ble_set_mode_leds(bool on) {
if (!state.configured) {
return false;
}
// The "mode" led is the red blinky one
at_command_P(on ? PSTR("AT+HWMODELED=1") : PSTR("AT+HWMODELED=0"), NULL, 0);
// Pin 19 is the blue "connected" LED; turn that off too.
// When turning LEDs back on, don't turn that LED on if we're
// not connected, as that would be confusing.
at_command_P(on && state.is_connected ? PSTR("AT+HWGPIO=19,1")
: PSTR("AT+HWGPIO=19,0"),
NULL, 0);
return true;
}
// https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-generic#at-plus-blepowerlevel
bool adafruit_ble_set_power_level(int8_t level) {
char cmd[46];
if (!state.configured) {
return false;
}
snprintf(cmd, sizeof(cmd), "AT+BLEPOWERLEVEL=%d", level);
return at_command(cmd, NULL, 0, false);
}

@ -0,0 +1,60 @@
/* Bluetooth Low Energy Protocol for QMK.
* Author: Wez Furlong, 2016
* Supports the Adafruit BLE board built around the nRF51822 chip.
*/
#pragma once
#ifdef ADAFRUIT_BLE_ENABLE
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Instruct the module to enable HID keyboard support and reset */
extern bool adafruit_ble_enable_keyboard(void);
/* Query to see if the BLE module is connected */
extern bool adafruit_ble_query_is_connected(void);
/* Returns true if we believe that the BLE module is connected.
* This uses our cached understanding that is maintained by
* calling ble_task() periodically. */
extern bool adafruit_ble_is_connected(void);
/* Call this periodically to process BLE-originated things */
extern void adafruit_ble_task(void);
/* Generates keypress events for a set of keys.
* The hid modifier mask specifies the state of the modifier keys for
* this set of keys.
* Also sends a key release indicator, so that the keys do not remain
* held down. */
extern bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys,
uint8_t nkeys);
/* Send a consumer keycode, holding it down for the specified duration
* (milliseconds) */
extern bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration);
#ifdef MOUSE_ENABLE
/* Send a mouse/wheel movement report.
* The parameters are signed and indicate positive of negative direction
* change. */
extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll,
int8_t pan);
#endif
/* Compute battery voltage by reading an analog pin.
* Returns the integer number of millivolts */
extern uint32_t adafruit_ble_read_battery_voltage(void);
extern bool adafruit_ble_set_mode_leds(bool on);
extern bool adafruit_ble_set_power_level(int8_t level);
#ifdef __cplusplus
}
#endif
#endif // ADAFRUIT_BLE_ENABLE

@ -40,6 +40,9 @@
#include "report.h"
#include "descriptor.h"
#ifndef USB_MAX_POWER_CONSUMPTION
#define USB_MAX_POWER_CONSUMPTION 500
#endif
/*******************************************************************************
* HID Report Descriptors
@ -140,10 +143,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
HID_RI_USAGE(8, 0x80), /* System Control */
HID_RI_COLLECTION(8, 0x01), /* Application */
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
HID_RI_LOGICAL_MINIMUM(16, 0x0081),
HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
HID_RI_LOGICAL_MINIMUM(16, 0x0001),
HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */
HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */
HID_RI_USAGE_MAXIMUM(16, 0x0083), /* System Wake Up */
HID_RI_REPORT_SIZE(8, 16),
HID_RI_REPORT_COUNT(8, 1),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
@ -164,6 +167,28 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
};
#endif
#ifdef RAW_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] =
{
HID_RI_USAGE_PAGE(16, 0xFF60), /* Vendor Page 0xFF60 */
HID_RI_USAGE(8, 0x61), /* Vendor Usage 0x61 */
HID_RI_COLLECTION(8, 0x01), /* Application */
HID_RI_USAGE(8, 0x62), /* Vendor Usage 0x62 */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_RI_USAGE(8, 0x63), /* Vendor Usage 0x63 */
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(16, 0x00FF),
HID_RI_REPORT_COUNT(8, RAW_EPSIZE),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
HID_RI_END_COLLECTION(0),
};
#endif
#ifdef CONSOLE_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
{
@ -272,7 +297,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
.MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
.MaxPowerConsumption = USB_CONFIG_POWER_MA(USB_MAX_POWER_CONSUMPTION)
},
/*
@ -399,6 +424,58 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
},
#endif
/*
* Raw
*/
#ifdef RAW_ENABLE
.Raw_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = RAW_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 2,
.Class = HID_CSCP_HIDClass,
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.Raw_HID =
{
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
.HIDSpec = VERSION_BCD(1,1,1),
.CountryCode = 0x00,
.TotalReportDescriptors = 1,
.HIDReportType = HID_DTYPE_Report,
.HIDReportLength = sizeof(RawReport)
},
.Raw_INEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_IN | RAW_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = RAW_EPSIZE,
.PollingIntervalMS = 0x01
},
.Raw_OUTEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_OUT | RAW_OUT_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = RAW_EPSIZE,
.PollingIntervalMS = 0x01
},
#endif
/*
* Console
*/
@ -754,7 +831,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.PollingIntervalMS = 0x05
},
#endif
};
@ -846,6 +922,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
#ifdef RAW_ENABLE
case RAW_INTERFACE:
Address = &ConfigurationDescriptor.Raw_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
#ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE:
Address = &ConfigurationDescriptor.Console_HID;
@ -878,6 +960,12 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Size = sizeof(ExtrakeyReport);
break;
#endif
#ifdef RAW_ENABLE
case RAW_INTERFACE:
Address = &RawReport;
Size = sizeof(RawReport);
break;
#endif
#ifdef CONSOLE_ENABLE
case CONSOLE_INTERFACE:
Address = &ConsoleReport;

@ -71,6 +71,14 @@ typedef struct
USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
#endif
#ifdef RAW_ENABLE
// Raw HID Interface
USB_Descriptor_Interface_t Raw_Interface;
USB_HID_Descriptor_HID_t Raw_HID;
USB_Descriptor_Endpoint_t Raw_INEndpoint;
USB_Descriptor_Endpoint_t Raw_OUTEndpoint;
#endif
#ifdef CONSOLE_ENABLE
// Console HID Interface
USB_Descriptor_Interface_t Console_Interface;
@ -137,10 +145,16 @@ typedef struct
# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
#endif
#ifdef RAW_ENABLE
# define RAW_INTERFACE (EXTRAKEY_INTERFACE + 1)
#else
# define RAW_INTERFACE EXTRAKEY_INTERFACE
#endif
#ifdef CONSOLE_ENABLE
# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
# define CONSOLE_INTERFACE (RAW_INTERFACE + 1)
#else
# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
# define CONSOLE_INTERFACE RAW_INTERFACE
#endif
#ifdef NKRO_ENABLE
@ -182,12 +196,19 @@ typedef struct
# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM
#endif
#ifdef RAW_ENABLE
# define RAW_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
# define RAW_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
#else
# define RAW_OUT_EPNUM EXTRAKEY_IN_EPNUM
#endif
#ifdef CONSOLE_ENABLE
# define CONSOLE_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
# define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 1)
//# define CONSOLE_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1)
//# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2)
# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1)
#else
# define CONSOLE_OUT_EPNUM EXTRAKEY_IN_EPNUM
# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM
#endif
#ifdef NKRO_ENABLE
@ -217,7 +238,6 @@ typedef struct
# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM
#endif
#if defined(__AVR_ATmega32U2__) && CDC_OUT_EPNUM > 4
# error "Endpoints are not available enough to support all functions. Remove some in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL)"
#endif
@ -225,6 +245,7 @@ typedef struct
#define KEYBOARD_EPSIZE 8
#define MOUSE_EPSIZE 8
#define EXTRAKEY_EPSIZE 8
#define RAW_EPSIZE 32
#define CONSOLE_EPSIZE 32
#define NKRO_EPSIZE 32
#define MIDI_STREAM_EPSIZE 64

@ -51,6 +51,8 @@
#include "descriptor.h"
#include "lufa.h"
#include "quantum.h"
#include <util/atomic.h>
#ifdef NKRO_ENABLE
#include "keycode_config.h"
@ -66,11 +68,26 @@
#ifdef BLUETOOTH_ENABLE
#include "bluetooth.h"
#endif
#ifdef ADAFRUIT_BLE_ENABLE
#include "adafruit_ble.h"
#endif
#ifdef VIRTSER_ENABLE
#include "virtser.h"
#endif
#if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE)
#include "rgblight.h"
#endif
#ifdef MIDI_ENABLE
#include "sysex_tools.h"
#endif
#ifdef RAW_ENABLE
#include "raw_hid.h"
#endif
uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1;
@ -79,9 +96,9 @@ static uint8_t keyboard_led_stats = 0;
static report_keyboard_t keyboard_report_sent;
#ifdef MIDI_ENABLE
void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
void usb_get_midi(MidiDevice * device);
void midi_usb_init(MidiDevice * device);
static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
static void usb_get_midi(MidiDevice * device);
static void midi_usb_init(MidiDevice * device);
#endif
/* Host driver */
@ -166,6 +183,80 @@ USB_ClassInfo_CDC_Device_t cdc_device =
};
#endif
#ifdef RAW_ENABLE
void raw_hid_send( uint8_t *data, uint8_t length )
{
// TODO: implement variable size packet
if ( length != RAW_EPSIZE )
{
return;
}
if (USB_DeviceState != DEVICE_STATE_Configured)
{
return;
}
// TODO: decide if we allow calls to raw_hid_send() in the middle
// of other endpoint usage.
uint8_t ep = Endpoint_GetCurrentEndpoint();
Endpoint_SelectEndpoint(RAW_IN_EPNUM);
// Check to see if the host is ready to accept another packet
if (Endpoint_IsINReady())
{
// Write data
Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
// Finalize the stream transfer to send the last packet
Endpoint_ClearIN();
}
Endpoint_SelectEndpoint(ep);
}
__attribute__ ((weak))
void raw_hid_receive( uint8_t *data, uint8_t length )
{
// Users should #include "raw_hid.h" in their own code
// and implement this function there. Leave this as weak linkage
// so users can opt to not handle data coming in.
}
static void raw_hid_task(void)
{
// Create a temporary buffer to hold the read in data from the host
uint8_t data[RAW_EPSIZE];
bool data_read = false;
// Device must be connected and configured for the task to run
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
// Check to see if a packet has been sent from the host
if (Endpoint_IsOUTReceived())
{
// Check to see if the packet contains data
if (Endpoint_IsReadWriteAllowed())
{
/* Read data */
Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
data_read = true;
}
// Finalize the stream transfer to receive the last packet
Endpoint_ClearOUT();
if ( data_read )
{
raw_hid_receive( data, sizeof(data) );
}
}
}
#endif
/*******************************************************************************
* Console
@ -285,10 +376,14 @@ void EVENT_USB_Device_WakeUp()
#endif
}
#ifdef CONSOLE_ENABLE
static bool console_flush = false;
#define CONSOLE_FLUSH_SET(b) do { \
uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\
console_flush = b; \
} \
} while (0)
// called every 1ms
@ -302,6 +397,7 @@ void EVENT_USB_Device_StartOfFrame(void)
Console_Task();
console_flush = false;
}
#endif
/** Event handler for the USB_ConfigurationChanged event.
@ -330,6 +426,14 @@ void EVENT_USB_Device_ConfigurationChanged(void)
EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef RAW_ENABLE
/* Setup Raw HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
RAW_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef CONSOLE_ENABLE
/* Setup Console HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
@ -492,9 +596,35 @@ static uint8_t keyboard_leds(void)
return keyboard_led_stats;
}
#define SendToUSB 1
#define SendToBT 2
#define SendToBLE 4
static inline uint8_t where_to_send(void) {
#ifdef ADAFRUIT_BLE_ENABLE
#if 0
if (adafruit_ble_is_connected()) {
// For testing, send to BLE as a priority
return SendToBLE;
}
#endif
// This is the real policy
if (USB_DeviceState != DEVICE_STATE_Configured) {
if (adafruit_ble_is_connected()) {
return SendToBLE;
}
}
#endif
return ((USB_DeviceState == DEVICE_STATE_Configured) ? SendToUSB : 0)
#ifdef BLUETOOTH_ENABLE
|| SendToBT
#endif
;
}
static void send_keyboard(report_keyboard_t *report)
{
#ifdef BLUETOOTH_ENABLE
bluefruit_serial_send(0xFD);
for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
@ -503,9 +633,17 @@ static void send_keyboard(report_keyboard_t *report)
#endif
uint8_t timeout = 255;
uint8_t where = where_to_send();
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
#ifdef ADAFRUIT_BLE_ENABLE
if (where & SendToBLE) {
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
}
#endif
if (!(where & SendToUSB)) {
return;
}
/* Select the Keyboard Report Endpoint */
#ifdef NKRO_ENABLE
@ -558,8 +696,17 @@ static void send_mouse(report_mouse_t *report)
uint8_t timeout = 255;
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
uint8_t where = where_to_send();
#ifdef ADAFRUIT_BLE_ENABLE
if (where & SendToBLE) {
// FIXME: mouse buttons
adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
}
#endif
if (!(where & SendToUSB)) {
return;
}
/* Select the Mouse Report Endpoint */
Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
@ -585,7 +732,7 @@ static void send_system(uint16_t data)
report_extra_t r = {
.report_id = REPORT_ID_SYSTEM,
.usage = data
.usage = data - SYSTEM_POWER_DOWN + 1
};
Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
@ -617,9 +764,16 @@ static void send_consumer(uint16_t data)
#endif
uint8_t timeout = 255;
uint8_t where = where_to_send();
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
#ifdef ADAFRUIT_BLE_ENABLE
if (where & SendToBLE) {
adafruit_ble_send_consumer_key(data, 0);
}
#endif
if (!(where & SendToUSB)) {
return;
}
report_extra_t r = {
.report_id = REPORT_ID_CONSUMER,
@ -709,7 +863,7 @@ int8_t sendchar(uint8_t c)
******************************************************************************/
#ifdef MIDI_ENABLE
void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
MIDI_EventPacket_t event;
event.Data1 = byte0;
event.Data2 = byte1;
@ -769,7 +923,7 @@ void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byt
USB_USBTask();
}
void usb_get_midi(MidiDevice * device) {
static void usb_get_midi(MidiDevice * device) {
MIDI_EventPacket_t event;
while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
@ -799,12 +953,12 @@ void usb_get_midi(MidiDevice * device) {
USB_USBTask();
}
void midi_usb_init(MidiDevice * device){
static void midi_usb_init(MidiDevice * device){
midi_device_init(device);
midi_device_set_send_func(device, usb_send_func);
midi_device_set_pre_input_process_func(device, usb_get_midi);
SetupHardware();
// SetupHardware();
sei();
}
@ -1029,7 +1183,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
#ifndef BLUETOOTH_ENABLE
#if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE)
while (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
suspend_power_down();
@ -1039,20 +1193,34 @@ int main(void)
}
#endif
keyboard_task();
#ifdef MIDI_ENABLE
midi_device_process(&midi_device);
// MIDI_Task();
#endif
keyboard_task();
#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
rgblight_task();
#endif
#ifdef ADAFRUIT_BLE_ENABLE
adafruit_ble_task();
#endif
#ifdef VIRTSER_ENABLE
virtser_task();
CDC_Device_USBTask(&cdc_device);
#endif
#ifdef RAW_ENABLE
raw_hid_task();
#endif
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
USB_USBTask();
#endif
}
}
@ -1077,15 +1245,50 @@ void fallthrough_callback(MidiDevice * device,
#endif
}
void cc_callback(MidiDevice * device,
uint8_t chan, uint8_t num, uint8_t val) {
//sending it back on the next channel
midi_send_cc(device, (chan + 1) % 16, num, val);
// midi_send_cc(device, (chan + 1) % 16, num, val);
}
void sysex_callback(MidiDevice * device,
uint16_t start, uint8_t length, uint8_t * data) {
for (int i = 0; i < length; i++)
midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
#ifdef API_SYSEX_ENABLE
uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
#endif
void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
#ifdef API_SYSEX_ENABLE
// SEND_STRING("\n");
// send_word(start);
// SEND_STRING(": ");
// Don't store the header
int16_t pos = start - 4;
for (uint8_t place = 0; place < length; place++) {
// send_byte(*data);
if (pos >= 0) {
if (*data == 0xF7) {
// SEND_STRING("\nRD: ");
// for (uint8_t i = 0; i < start + place + 1; i++){
// send_byte(midi_buffer[i]);
// SEND_STRING(" ");
// }
const unsigned decoded_length = sysex_decoded_length(pos);
uint8_t decoded[API_SYSEX_MAX_SIZE];
sysex_decode(decoded, midi_buffer, pos);
process_api(decoded_length, decoded);
return;
}
else if (pos >= MIDI_SYSEX_BUFFER) {
return;
}
midi_buffer[pos] = *data;
}
// SEND_STRING(" ");
data++;
pos++;
}
#endif
}
#endif

@ -68,8 +68,19 @@ typedef struct {
} __attribute__ ((packed)) report_extra_t;
#ifdef MIDI_ENABLE
void MIDI_Task(void);
MidiDevice midi_device;
void MIDI_Task(void);
MidiDevice midi_device;
#endif
#ifdef API_ENABLE
#include "api.h"
#endif
#ifdef API_SYSEX_ENABLE
#include "api_sysex.h"
// Allocate space for encoding overhead.
//The header and terminator are not stored to save a few bytes of precious ram
#define MIDI_SYSEX_BUFFER (API_SYSEX_MAX_SIZE + API_SYSEX_MAX_SIZE / 7 + (API_SYSEX_MAX_SIZE % 7 ? 1 : 0))
#endif
// #if LUFA_VERSION_INTEGER < 0x120730

@ -0,0 +1,66 @@
#pragma once
// A simple ringbuffer holding Size elements of type T
template <typename T, uint8_t Size>
class RingBuffer {
protected:
T buf_[Size];
uint8_t head_{0}, tail_{0};
public:
inline uint8_t nextPosition(uint8_t position) {
return (position + 1) % Size;
}
inline uint8_t prevPosition(uint8_t position) {
if (position == 0) {
return Size - 1;
}
return position - 1;
}
inline bool enqueue(const T &item) {
static_assert(Size > 1, "RingBuffer size must be > 1");
uint8_t next = nextPosition(head_);
if (next == tail_) {
// Full
return false;
}
buf_[head_] = item;
head_ = next;
return true;
}
inline bool get(T &dest, bool commit = true) {
auto tail = tail_;
if (tail == head_) {
// No more data
return false;
}
dest = buf_[tail];
tail = nextPosition(tail);
if (commit) {
tail_ = tail;
}
return true;
}
inline bool empty() const { return head_ == tail_; }
inline uint8_t size() const {
int diff = head_ - tail_;
if (diff >= 0) {
return diff;
}
return Size + diff;
}
inline T& front() {
return buf_[tail_];
}
inline bool peek(T &item) {
return get(item, false);
}
};

@ -4,6 +4,7 @@ SRC += midi.c \
midi_device.c \
bytequeue/bytequeue.c \
bytequeue/interrupt_setting.c \
sysex_tools.c \
$(LUFA_SRC_USBCLASS)
VPATH += $(TMK_PATH)/$(MIDI_DIR)

@ -18,60 +18,59 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#include<avr/io.h>
#include<util/delay.h>
#include "ps2.h"
#include "ps2_mouse.h"
#include "report.h"
#include "host.h"
#include "timer.h"
#include "print.h"
#include "report.h"
#include "debug.h"
#include "ps2.h"
/* ============================= MACROS ============================ */
static report_mouse_t mouse_report = {};
static inline void ps2_mouse_print_report(report_mouse_t *mouse_report);
static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report);
static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report);
static inline void ps2_mouse_enable_scrolling(void);
static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report);
static void print_usb_data(void);
/* ============================= IMPLEMENTATION ============================ */
/* supports only 3 button mouse at this time */
uint8_t ps2_mouse_init(void) {
uint8_t rcv;
void ps2_mouse_init(void) {
ps2_host_init();
_delay_ms(1000); // wait for powering up
_delay_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up
// send Reset
rcv = ps2_host_send(0xFF);
print("ps2_mouse_init: send Reset: ");
phex(rcv); phex(ps2_error); print("\n");
PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset");
// read completion code of BAT
rcv = ps2_host_recv_response();
print("ps2_mouse_init: read BAT: ");
phex(rcv); phex(ps2_error); print("\n");
PS2_MOUSE_RECEIVE("ps2_mouse_init: read BAT");
PS2_MOUSE_RECEIVE("ps2_mouse_init: read DevID");
// read Device ID
rcv = ps2_host_recv_response();
print("ps2_mouse_init: read DevID: ");
phex(rcv); phex(ps2_error); print("\n");
#ifdef PS2_MOUSE_USE_REMOTE_MODE
ps2_mouse_set_remote_mode();
#else
ps2_mouse_enable_data_reporting();
#endif
#ifdef PS2_MOUSE_ENABLE_SCROLLING
ps2_mouse_enable_scrolling();
#endif
// send Set Remote mode
rcv = ps2_host_send(0xF0);
print("ps2_mouse_init: send 0xF0: ");
phex(rcv); phex(ps2_error); print("\n");
#ifdef PS2_MOUSE_USE_2_1_SCALING
ps2_mouse_set_scaling_2_1();
#endif
return 0;
ps2_mouse_init_user();
}
#define X_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_X_SIGN))
#define Y_IS_NEG (mouse_report.buttons & (1<<PS2_MOUSE_Y_SIGN))
#define X_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_X_OVFLW))
#define Y_IS_OVF (mouse_report.buttons & (1<<PS2_MOUSE_Y_OVFLW))
void ps2_mouse_task(void)
{
enum { SCROLL_NONE, SCROLL_BTN, SCROLL_SENT };
static uint8_t scroll_state = SCROLL_NONE;
__attribute__((weak))
void ps2_mouse_init_user(void) {
}
void ps2_mouse_task(void) {
static uint8_t buttons_prev = 0;
/* receives packet from mouse */
@ -79,142 +78,169 @@ void ps2_mouse_task(void)
rcv = ps2_host_send(PS2_MOUSE_READ_DATA);
if (rcv == PS2_ACK) {
mouse_report.buttons = ps2_host_recv_response();
mouse_report.x = ps2_host_recv_response();
mouse_report.y = ps2_host_recv_response();
mouse_report.x = ps2_host_recv_response() * PS2_MOUSE_X_MULTIPLIER;
mouse_report.y = ps2_host_recv_response() * PS2_MOUSE_Y_MULTIPLIER;
#ifdef PS2_MOUSE_ENABLE_SCROLLING
mouse_report.v = -(ps2_host_recv_response() & PS2_MOUSE_SCROLL_MASK) * PS2_MOUSE_V_MULTIPLIER;
#endif
} else {
if (debug_mouse) print("ps2_mouse: fail to get mouse packet\n");
return;
}
xprintf("%ud ", timer_read());
print("ps2_mouse raw: [");
phex(mouse_report.buttons); print("|");
print_hex8((uint8_t)mouse_report.x); print(" ");
print_hex8((uint8_t)mouse_report.y); print("]\n");
/* if mouse moves or buttons state changes */
if (mouse_report.x || mouse_report.y ||
if (mouse_report.x || mouse_report.y || mouse_report.v ||
((mouse_report.buttons ^ buttons_prev) & PS2_MOUSE_BTN_MASK)) {
#ifdef PS2_MOUSE_DEBUG
print("ps2_mouse raw: [");
phex(mouse_report.buttons); print("|");
print_hex8((uint8_t)mouse_report.x); print(" ");
print_hex8((uint8_t)mouse_report.y); print("]\n");
#ifdef PS2_MOUSE_DEBUG_RAW
// Used to debug raw ps2 bytes from mouse
ps2_mouse_print_report(&mouse_report);
#endif
buttons_prev = mouse_report.buttons;
ps2_mouse_convert_report_to_hid(&mouse_report);
#if PS2_MOUSE_SCROLL_BTN_MASK
ps2_mouse_scroll_button_task(&mouse_report);
#endif
#ifdef PS2_MOUSE_DEBUG_HID
// Used to debug the bytes sent to the host
ps2_mouse_print_report(&mouse_report);
#endif
host_mouse_send(&mouse_report);
}
ps2_mouse_clear_report(&mouse_report);
}
// PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value.
// bit: 8 7 ... 0
// sign \8-bit/
//
// Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used.
//
// This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit.
mouse_report.x = X_IS_NEG ?
((!X_IS_OVF && -127 <= mouse_report.x && mouse_report.x <= -1) ? mouse_report.x : -127) :
((!X_IS_OVF && 0 <= mouse_report.x && mouse_report.x <= 127) ? mouse_report.x : 127);
mouse_report.y = Y_IS_NEG ?
((!Y_IS_OVF && -127 <= mouse_report.y && mouse_report.y <= -1) ? mouse_report.y : -127) :
((!Y_IS_OVF && 0 <= mouse_report.y && mouse_report.y <= 127) ? mouse_report.y : 127);
void ps2_mouse_disable_data_reporting(void) {
PS2_MOUSE_SEND(PS2_MOUSE_DISABLE_DATA_REPORTING, "ps2 mouse disable data reporting");
}
// remove sign and overflow flags
mouse_report.buttons &= PS2_MOUSE_BTN_MASK;
void ps2_mouse_enable_data_reporting(void) {
PS2_MOUSE_SEND(PS2_MOUSE_ENABLE_DATA_REPORTING, "ps2 mouse enable data reporting");
}
// invert coordinate of y to conform to USB HID mouse
mouse_report.y = -mouse_report.y;
void ps2_mouse_set_remote_mode(void) {
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_REMOTE_MODE, "ps2 mouse set remote mode");
ps2_mouse_mode = PS2_MOUSE_REMOTE_MODE;
}
void ps2_mouse_set_stream_mode(void) {
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_STREAM_MODE, "ps2 mouse set stream mode");
ps2_mouse_mode = PS2_MOUSE_STREAM_MODE;
}
#if PS2_MOUSE_SCROLL_BTN_MASK
static uint16_t scroll_button_time = 0;
if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == (PS2_MOUSE_SCROLL_BTN_MASK)) {
if (scroll_state == SCROLL_NONE) {
scroll_button_time = timer_read();
scroll_state = SCROLL_BTN;
}
// doesn't send Scroll Button
//mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
if (mouse_report.x || mouse_report.y) {
scroll_state = SCROLL_SENT;
mouse_report.v = -mouse_report.y/(PS2_MOUSE_SCROLL_DIVISOR_V);
mouse_report.h = mouse_report.x/(PS2_MOUSE_SCROLL_DIVISOR_H);
mouse_report.x = 0;
mouse_report.y = 0;
//host_mouse_send(&mouse_report);
}
void ps2_mouse_set_scaling_2_1(void) {
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_2_1, "ps2 mouse set scaling 2:1");
}
void ps2_mouse_set_scaling_1_1(void) {
PS2_MOUSE_SEND_SAFE(PS2_MOUSE_SET_SCALING_1_1, "ps2 mouse set scaling 1:1");
}
void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution) {
PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_RESOLUTION, resolution, "ps2 mouse set resolution");
}
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate) {
PS2_MOUSE_SET_SAFE(PS2_MOUSE_SET_SAMPLE_RATE, sample_rate, "ps2 mouse set sample rate");
}
/* ============================= HELPERS ============================ */
#define X_IS_NEG (mouse_report->buttons & (1<<PS2_MOUSE_X_SIGN))
#define Y_IS_NEG (mouse_report->buttons & (1<<PS2_MOUSE_Y_SIGN))
#define X_IS_OVF (mouse_report->buttons & (1<<PS2_MOUSE_X_OVFLW))
#define Y_IS_OVF (mouse_report->buttons & (1<<PS2_MOUSE_Y_OVFLW))
static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report) {
// PS/2 mouse data is '9-bit integer'(-256 to 255) which is comprised of sign-bit and 8-bit value.
// bit: 8 7 ... 0
// sign \8-bit/
//
// Meanwhile USB HID mouse indicates 8bit data(-127 to 127), note that -128 is not used.
//
// This converts PS/2 data into HID value. Use only -127-127 out of PS/2 9-bit.
mouse_report->x = X_IS_NEG ?
((!X_IS_OVF && -127 <= mouse_report->x && mouse_report->x <= -1) ? mouse_report->x : -127) :
((!X_IS_OVF && 0 <= mouse_report->x && mouse_report->x <= 127) ? mouse_report->x : 127);
mouse_report->y = Y_IS_NEG ?
((!Y_IS_OVF && -127 <= mouse_report->y && mouse_report->y <= -1) ? mouse_report->y : -127) :
((!Y_IS_OVF && 0 <= mouse_report->y && mouse_report->y <= 127) ? mouse_report->y : 127);
// remove sign and overflow flags
mouse_report->buttons &= PS2_MOUSE_BTN_MASK;
// invert coordinate of y to conform to USB HID mouse
mouse_report->y = -mouse_report->y;
}
static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
mouse_report->x = 0;
mouse_report->y = 0;
mouse_report->v = 0;
mouse_report->h = 0;
mouse_report->buttons = 0;
}
static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {
if (!debug_mouse) return;
print("ps2_mouse: [");
phex(mouse_report->buttons); print("|");
print_hex8((uint8_t)mouse_report->x); print(" ");
print_hex8((uint8_t)mouse_report->y); print(" ");
print_hex8((uint8_t)mouse_report->v); print(" ");
print_hex8((uint8_t)mouse_report->h); print("]\n");
}
static inline void ps2_mouse_enable_scrolling(void) {
PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Initiaing scroll wheel enable: Set sample rate");
PS2_MOUSE_SEND(200, "200");
PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate");
PS2_MOUSE_SEND(100, "100");
PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate");
PS2_MOUSE_SEND(80, "80");
PS2_MOUSE_SEND(PS2_MOUSE_GET_DEVICE_ID, "Finished enabling scroll wheel");
_delay_ms(20);
}
#define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK)
#define RELEASE_SCROLL_BUTTONS mouse_report->buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK)
static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) {
static enum {
SCROLL_NONE,
SCROLL_BTN,
SCROLL_SENT,
} scroll_state = SCROLL_NONE;
static uint16_t scroll_button_time = 0;
if (PS2_MOUSE_SCROLL_BTN_MASK == (mouse_report->buttons & (PS2_MOUSE_SCROLL_BTN_MASK))) {
// All scroll buttons are pressed
if (scroll_state == SCROLL_NONE) {
scroll_button_time = timer_read();
scroll_state = SCROLL_BTN;
}
else if ((mouse_report.buttons & (PS2_MOUSE_SCROLL_BTN_MASK)) == 0) {
// If the mouse has moved, update the report to scroll instead of move the mouse
if (mouse_report->x || mouse_report->y) {
scroll_state = SCROLL_SENT;
mouse_report->v = -mouse_report->y/(PS2_MOUSE_SCROLL_DIVISOR_V);
mouse_report->h = mouse_report->x/(PS2_MOUSE_SCROLL_DIVISOR_H);
mouse_report->x = 0;
mouse_report->y = 0;
}
} else if (0 == (PS2_MOUSE_SCROLL_BTN_MASK & mouse_report->buttons)) {
// None of the scroll buttons are pressed
#if PS2_MOUSE_SCROLL_BTN_SEND
if (scroll_state == SCROLL_BTN &&
TIMER_DIFF_16(timer_read(), scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
// send Scroll Button(down and up at once) when not scrolled
mouse_report.buttons |= (PS2_MOUSE_SCROLL_BTN_MASK);
host_mouse_send(&mouse_report);
_delay_ms(100);
mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
}
#endif
scroll_state = SCROLL_NONE;
if (scroll_state == SCROLL_BTN
&& timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) {
PRESS_SCROLL_BUTTONS;
host_mouse_send(mouse_report);
_delay_ms(100);
RELEASE_SCROLL_BUTTONS;
}
// doesn't send Scroll Button
mouse_report.buttons &= ~(PS2_MOUSE_SCROLL_BTN_MASK);
#endif
host_mouse_send(&mouse_report);
print_usb_data();
scroll_state = SCROLL_NONE;
}
// clear report
mouse_report.x = 0;
mouse_report.y = 0;
mouse_report.v = 0;
mouse_report.h = 0;
mouse_report.buttons = 0;
}
static void print_usb_data(void)
{
if (!debug_mouse) return;
print("ps2_mouse usb: [");
phex(mouse_report.buttons); print("|");
print_hex8((uint8_t)mouse_report.x); print(" ");
print_hex8((uint8_t)mouse_report.y); print(" ");
print_hex8((uint8_t)mouse_report.v); print(" ");
print_hex8((uint8_t)mouse_report.h); print("]\n");
}
/* PS/2 Mouse Synopsis
* http://www.computer-engineering.org/ps2mouse/
*
* Command:
* 0xFF: Reset
* 0xF6: Set Defaults Sampling; rate=100, resolution=4cnt/mm, scaling=1:1, reporting=disabled
* 0xF5: Disable Data Reporting
* 0xF4: Enable Data Reporting
* 0xF3: Set Sample Rate
* 0xF2: Get Device ID
* 0xF0: Set Remote Mode
* 0xEB: Read Data
* 0xEA: Set Stream Mode
* 0xE9: Status Request
* 0xE8: Set Resolution
* 0xE7: Set Scaling 2:1
* 0xE6: Set Scaling 1:1
*
* Mode:
* Stream Mode: devices sends the data when it changs its state
* Remote Mode: host polls the data periodically
*
* This code uses Remote Mode and polls the data with Read Data(0xEB).
*
* Data format:
* byte|7 6 5 4 3 2 1 0
* ----+--------------------------------------------------------------
* 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
* 1| X movement
* 2| Y movement
*/
RELEASE_SCROLL_BUTTONS;
}

@ -19,16 +19,61 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_MOUSE_H
#include <stdbool.h>
#include "debug.h"
#define PS2_MOUSE_READ_DATA 0xEB
#define PS2_MOUSE_SEND(command, message) \
do { \
uint8_t rcv = ps2_host_send(command); \
if (debug_mouse) { \
print((message)); \
xprintf(" command: %X, result: %X, error: %X \n", command, rcv, ps2_error); \
} \
} while(0)
#define PS2_MOUSE_SEND_SAFE(command, message) \
do { \
if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \
ps2_mouse_disable_data_reporting(); \
} \
PS2_MOUSE_SEND(command, message); \
if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \
ps2_mouse_enable_data_reporting(); \
} \
} while(0)
#define PS2_MOUSE_SET_SAFE(command, value, message) \
do { \
if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \
ps2_mouse_disable_data_reporting(); \
} \
PS2_MOUSE_SEND(command, message); \
PS2_MOUSE_SEND(value, "Sending value"); \
if (PS2_MOUSE_STREAM_MODE == ps2_mouse_mode) { \
ps2_mouse_enable_data_reporting(); \
} \
} while(0)
#define PS2_MOUSE_RECEIVE(message) \
do { \
uint8_t rcv = ps2_host_recv_response(); \
if (debug_mouse) { \
print((message)); \
xprintf(" result: %X, error: %X \n", rcv, ps2_error); \
} \
} while(0)
static enum ps2_mouse_mode_e {
PS2_MOUSE_STREAM_MODE,
PS2_MOUSE_REMOTE_MODE,
} ps2_mouse_mode = PS2_MOUSE_STREAM_MODE;
/*
* Data format:
* byte|7 6 5 4 3 2 1 0
* ----+--------------------------------------------------------------
* 0|Yovflw Xovflw Ysign Xsign 1 Middle Right Left
* 1| X movement(0-255)
* 2| Y movement(0-255)
* ----+----------------------------------------------------------------
* 0|[Yovflw][Xovflw][Ysign ][Xsign ][ 1 ][Middle][Right ][Left ]
* 1|[ X movement(0-255) ]
* 2|[ Y movement(0-255) ]
*/
#define PS2_MOUSE_BTN_MASK 0x07
#define PS2_MOUSE_BTN_LEFT 0
@ -39,10 +84,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_MOUSE_X_OVFLW 6
#define PS2_MOUSE_Y_OVFLW 7
/*
* Scroll by mouse move with pressing button
*/
/* mouse button to start scrolling; set 0 to disable scroll */
#ifndef PS2_MOUSE_SCROLL_BTN_MASK
#define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BTN_MIDDLE)
@ -58,9 +99,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef PS2_MOUSE_SCROLL_DIVISOR_H
#define PS2_MOUSE_SCROLL_DIVISOR_H 2
#endif
/* multiply reported mouse values by these */
#ifndef PS2_MOUSE_X_MULTIPLIER
#define PS2_MOUSE_X_MULTIPLIER 1
#endif
#ifndef PS2_MOUSE_Y_MULTIPLIER
#define PS2_MOUSE_Y_MULTIPLIER 1
#endif
#ifndef PS2_MOUSE_V_MULTIPLIER
#define PS2_MOUSE_V_MULTIPLIER 1
#endif
/* For some mice this will need to be 0x0F */
#ifndef PS2_MOUSE_SCROLL_MASK
#define PS2_MOUSE_SCROLL_MASK 0xFF
#endif
#ifndef PS2_MOUSE_INIT_DELAY
#define PS2_MOUSE_INIT_DELAY 1000
#endif
enum ps2_mouse_command_e {
PS2_MOUSE_RESET = 0xFF,
PS2_MOUSE_RESEND = 0xFE,
PS2_MOSUE_SET_DEFAULTS = 0xF6,
PS2_MOUSE_DISABLE_DATA_REPORTING = 0xF5,
PS2_MOUSE_ENABLE_DATA_REPORTING = 0xF4,
PS2_MOUSE_SET_SAMPLE_RATE = 0xF3,
PS2_MOUSE_GET_DEVICE_ID = 0xF2,
PS2_MOUSE_SET_REMOTE_MODE = 0xF0,
PS2_MOUSE_SET_WRAP_MODE = 0xEC,
PS2_MOUSE_READ_DATA = 0xEB,
PS2_MOUSE_SET_STREAM_MODE = 0xEA,
PS2_MOUSE_STATUS_REQUEST = 0xE9,
PS2_MOUSE_SET_RESOLUTION = 0xE8,
PS2_MOUSE_SET_SCALING_2_1 = 0xE7,
PS2_MOUSE_SET_SCALING_1_1 = 0xE6,
};
typedef enum ps2_mouse_resolution_e {
PS2_MOUSE_1_COUNT_MM,
PS2_MOUSE_2_COUNT_MM,
PS2_MOUSE_4_COUNT_MM,
PS2_MOUSE_8_COUNT_MM,
} ps2_mouse_resolution_t;
typedef enum ps2_mouse_sample_rate_e {
PS2_MOUSE_10_SAMPLES_SEC = 10,
PS2_MOUSE_20_SAMPLES_SEC = 20,
PS2_MOUSE_40_SAMPLES_SEC = 40,
PS2_MOUSE_60_SAMPLES_SEC = 60,
PS2_MOUSE_80_SAMPLES_SEC = 80,
PS2_MOUSE_100_SAMPLES_SEC = 100,
PS2_MOUSE_200_SAMPLES_SEC = 200,
} ps2_mouse_sample_rate_t;
void ps2_mouse_init(void);
void ps2_mouse_init_user(void);
uint8_t ps2_mouse_init(void);
void ps2_mouse_task(void);
void ps2_mouse_disable_data_reporting(void);
void ps2_mouse_enable_data_reporting(void);
void ps2_mouse_set_remote_mode(void);
void ps2_mouse_set_stream_mode(void);
void ps2_mouse_set_scaling_2_1(void);
void ps2_mouse_set_scaling_1_1(void);
void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution);
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
#endif

@ -4,13 +4,13 @@
* Ring buffer to store scan codes from keyboard
*------------------------------------------------------------------*/
#define RBUF_SIZE 32
#include <util/atomic.h>
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;
static inline void rbuf_enqueue(uint8_t data)
{
uint8_t sreg = SREG;
cli();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
if (next != rbuf_tail) {
rbuf[rbuf_head] = data;
@ -18,36 +18,34 @@ static inline void rbuf_enqueue(uint8_t data)
} else {
print("rbuf: full\n");
}
SREG = sreg;
}
}
static inline uint8_t rbuf_dequeue(void)
{
uint8_t val = 0;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
uint8_t sreg = SREG;
cli();
if (rbuf_head != rbuf_tail) {
val = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
}
SREG = sreg;
}
return val;
}
static inline bool rbuf_has_data(void)
{
uint8_t sreg = SREG;
cli();
bool has_data = (rbuf_head != rbuf_tail);
SREG = sreg;
return has_data;
bool has_data;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
has_data = (rbuf_head != rbuf_tail);
}
return has_data;
}
static inline void rbuf_clear(void)
{
uint8_t sreg = SREG;
cli();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
rbuf_head = rbuf_tail = 0;
SREG = sreg;
}
}
#endif /* RING_BUFFER_H */

Loading…
Cancel
Save