aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang_complete24
-rw-r--r--.gitignore2
-rw-r--r--.vscode/settings.json20
-rw-r--r--autocomplete.sh1
-rwxr-xr-xbin/qmk59
-rw-r--r--build_json.mk5
-rw-r--r--docs/_summary.md5
-rw-r--r--docs/cli.md4
-rw-r--r--docs/cli_commands.md127
-rw-r--r--docs/cli_development.md18
-rw-r--r--docs/coding_conventions_python.md4
-rw-r--r--docs/config_options.md10
-rw-r--r--docs/de/_summary.md1
-rw-r--r--docs/es/_summary.md1
-rw-r--r--docs/faq_debug.md7
-rw-r--r--docs/feature_advanced_keycodes.md6
-rw-r--r--docs/feature_debounce_type.md1
-rw-r--r--docs/feature_macros.md4
-rw-r--r--docs/feature_ps2_mouse.md19
-rw-r--r--docs/flashing.md1
-rw-r--r--docs/fr-fr/_summary.md3
-rw-r--r--docs/fr-fr/faq_debug.md8
-rw-r--r--docs/fr-fr/flashing.md1
-rw-r--r--docs/getting_started_vagrant.md1
-rw-r--r--docs/he-il/_summary.md1
-rw-r--r--docs/ja/_summary.md1
-rw-r--r--docs/ja/faq_debug.md7
-rw-r--r--docs/ja/feature_advanced_keycodes.md4
-rw-r--r--docs/ja/feature_combo.md108
-rw-r--r--docs/ja/feature_dip_switch.md95
-rw-r--r--docs/ja/flashing.md1
-rw-r--r--docs/ja/getting_started_vagrant.md1
-rw-r--r--docs/keycodes.md12
-rw-r--r--docs/keycodes_basic.md4
-rw-r--r--docs/mod_tap.md4
-rw-r--r--docs/newbs_getting_started.md2
-rw-r--r--docs/platformdev_chibios_earlyinit.md53
-rw-r--r--docs/proton_c_conversion.md69
-rw-r--r--docs/pt-br/_summary.md1
-rw-r--r--docs/ref_functions.md4
-rw-r--r--docs/reference_glossary.md3
-rw-r--r--docs/ru-ru/_summary.md1
-rw-r--r--docs/spi_driver.md121
-rw-r--r--docs/zh-cn/_summary.md1
-rw-r--r--docs/zh-cn/faq_debug.md7
-rw-r--r--docs/zh-cn/reference_glossary.md3
-rw-r--r--drivers/avr/spi_master.c176
-rw-r--r--drivers/avr/spi_master.h57
-rw-r--r--keyboards/2_milk/2_milk.c2
-rw-r--r--keyboards/2_milk/2_milk.h2
-rw-r--r--keyboards/2_milk/config.h2
-rw-r--r--keyboards/2_milk/info.json3
-rw-r--r--keyboards/2_milk/keymaps/copypasta/keymap.c1
-rw-r--r--keyboards/2_milk/readme.md2
-rw-r--r--keyboards/aplx6/README.md41
-rw-r--r--keyboards/aplx6/aplx6.c19
-rw-r--r--keyboards/aplx6/aplx6.h12
-rw-r--r--keyboards/aplx6/config.h49
-rw-r--r--keyboards/aplx6/keymaps/default/keymap.c38
-rw-r--r--keyboards/aplx6/rules.mk33
-rw-r--r--keyboards/bat43/info.json71
-rw-r--r--keyboards/bm16a/config.h4
-rw-r--r--keyboards/bm16a/keymaps/via/keymap.c51
-rw-r--r--keyboards/bm16a/keymaps/via/readme.md1
-rw-r--r--keyboards/bm16a/keymaps/via/rules.mk2
-rw-r--r--keyboards/botanicalkeyboards/fm2u/config.h55
-rw-r--r--keyboards/botanicalkeyboards/fm2u/fm2u.c17
-rw-r--r--keyboards/botanicalkeyboards/fm2u/fm2u.h46
-rw-r--r--keyboards/botanicalkeyboards/fm2u/info.json56
-rw-r--r--keyboards/botanicalkeyboards/fm2u/keymaps/default/keymap.c25
-rw-r--r--keyboards/botanicalkeyboards/fm2u/keymaps/via/keymap.c37
-rw-r--r--keyboards/botanicalkeyboards/fm2u/keymaps/via/rules.mk4
-rw-r--r--keyboards/botanicalkeyboards/fm2u/readme.md13
-rw-r--r--keyboards/botanicalkeyboards/fm2u/rules.mk32
-rw-r--r--keyboards/butterstick/keymaps/dennytom/README.md11
-rw-r--r--keyboards/butterstick/keymaps/dennytom/keymap.c1418
-rw-r--r--keyboards/butterstick/keymaps/dennytom/keymap_def.json309
-rw-r--r--keyboards/butterstick/keymaps/dennytom/rules.mk8
-rw-r--r--keyboards/cannonkeys/atlas/atlas.c1
-rw-r--r--keyboards/cannonkeys/atlas/atlas.h48
-rw-r--r--keyboards/cannonkeys/atlas/chconf.h714
-rw-r--r--keyboards/cannonkeys/atlas/config.h71
-rw-r--r--keyboards/cannonkeys/atlas/halconf.h525
-rw-r--r--keyboards/cannonkeys/atlas/info.json198
-rw-r--r--keyboards/cannonkeys/atlas/keymaps/default/keymap.c93
-rw-r--r--keyboards/cannonkeys/atlas/keymaps/via/keymap.c102
-rw-r--r--keyboards/cannonkeys/atlas/keymaps/via/rules.mk1
-rw-r--r--keyboards/cannonkeys/atlas/mcuconf.h176
-rw-r--r--keyboards/cannonkeys/atlas/readme.md10
-rw-r--r--keyboards/cannonkeys/atlas/rules.mk16
-rw-r--r--keyboards/cannonkeys/db60/chconf.h714
-rw-r--r--keyboards/cannonkeys/db60/config.h78
-rw-r--r--keyboards/cannonkeys/db60/db60.c1
-rw-r--r--keyboards/cannonkeys/db60/db60.h61
-rw-r--r--keyboards/cannonkeys/db60/halconf.h525
-rw-r--r--keyboards/cannonkeys/db60/info.json19
-rw-r--r--keyboards/cannonkeys/db60/keymaps/default/keymap.c45
-rw-r--r--keyboards/cannonkeys/db60/keymaps/iso/keymap.c45
-rw-r--r--keyboards/cannonkeys/db60/keymaps/tsangan/keymap.c46
-rw-r--r--keyboards/cannonkeys/db60/keymaps/via/keymap.c63
-rw-r--r--keyboards/cannonkeys/db60/keymaps/via/rules.mk1
-rw-r--r--keyboards/cannonkeys/db60/mcuconf.h176
-rw-r--r--keyboards/cannonkeys/db60/readme.md12
-rw-r--r--keyboards/cannonkeys/db60/rules.mk21
-rw-r--r--keyboards/cannonkeys/devastatingtkl/chconf.h714
-rw-r--r--keyboards/cannonkeys/devastatingtkl/config.h77
-rw-r--r--keyboards/cannonkeys/devastatingtkl/devastatingtkl.c1
-rw-r--r--keyboards/cannonkeys/devastatingtkl/devastatingtkl.h19
-rw-r--r--keyboards/cannonkeys/devastatingtkl/halconf.h525
-rw-r--r--keyboards/cannonkeys/devastatingtkl/info.json13
-rw-r--r--keyboards/cannonkeys/devastatingtkl/keymaps/default/keymap.c41
-rw-r--r--keyboards/cannonkeys/devastatingtkl/keymaps/via/keymap.c59
-rw-r--r--keyboards/cannonkeys/devastatingtkl/keymaps/via/rules.mk1
-rw-r--r--keyboards/cannonkeys/devastatingtkl/mcuconf.h176
-rw-r--r--keyboards/cannonkeys/devastatingtkl/readme.md12
-rw-r--r--keyboards/cannonkeys/devastatingtkl/rules.mk20
-rw-r--r--keyboards/cannonkeys/rekt1800/chconf.h714
-rw-r--r--keyboards/cannonkeys/rekt1800/config.h74
-rw-r--r--keyboards/cannonkeys/rekt1800/halconf.h525
-rw-r--r--keyboards/cannonkeys/rekt1800/info.json12
-rw-r--r--keyboards/cannonkeys/rekt1800/keymaps/default/keymap.c48
-rw-r--r--keyboards/cannonkeys/rekt1800/keymaps/via/keymap.c58
-rw-r--r--keyboards/cannonkeys/rekt1800/keymaps/via/rules.mk1
-rw-r--r--keyboards/cannonkeys/rekt1800/mcuconf.h176
-rw-r--r--keyboards/cannonkeys/rekt1800/readme.md10
-rw-r--r--keyboards/cannonkeys/rekt1800/rekt1800.c1
-rw-r--r--keyboards/cannonkeys/rekt1800/rekt1800.h20
-rw-r--r--keyboards/cannonkeys/rekt1800/rules.mk19
-rw-r--r--keyboards/doro67/multi/keymaps/konstantin/rules.mk1
-rw-r--r--keyboards/dp60/config.h6
-rw-r--r--keyboards/dp60/keymaps/via/keymap.c14
-rw-r--r--keyboards/dp60/keymaps/via/rules.mk3
-rw-r--r--keyboards/ergodox_ez/keymaps/pvinis/keymap.c411
-rw-r--r--keyboards/georgi/keymaps/dennytom/README.md11
-rw-r--r--keyboards/georgi/keymaps/dennytom/keymap.c1208
-rw-r--r--keyboards/georgi/keymaps/dennytom/keymap_def.json153
-rw-r--r--keyboards/georgi/keymaps/dennytom/rules.mk8
-rw-r--r--keyboards/gergo/keymaps/gotham/config.h3
-rw-r--r--keyboards/gergo/keymaps/gotham/keymap.c155
-rw-r--r--keyboards/gergo/keymaps/gotham/readme.md8
-rw-r--r--keyboards/gergo/keymaps/gotham/rules.mk37
-rw-r--r--keyboards/gray_studio/space65/keymaps/keithlo/keymap.c63
-rw-r--r--keyboards/gray_studio/space65/keymaps/keithlo/readme.md107
-rw-r--r--keyboards/handwired/bdn9_ble/bdn9_ble.c1
-rw-r--r--keyboards/handwired/bdn9_ble/bdn9_ble.h37
-rw-r--r--keyboards/handwired/bdn9_ble/config.h52
-rw-r--r--keyboards/handwired/bdn9_ble/info.json22
-rw-r--r--keyboards/handwired/bdn9_ble/keymaps/default/keymap.c49
-rw-r--r--keyboards/handwired/bdn9_ble/readme.md14
-rw-r--r--keyboards/handwired/bdn9_ble/rules.mk37
-rw-r--r--keyboards/handwired/fc200rt_qmk/config.h136
-rw-r--r--keyboards/handwired/fc200rt_qmk/fc200rt_qmk.c17
-rw-r--r--keyboards/handwired/fc200rt_qmk/fc200rt_qmk.h46
-rw-r--r--keyboards/handwired/fc200rt_qmk/info.json12
-rw-r--r--keyboards/handwired/fc200rt_qmk/keymaps/default/keymap.c28
-rw-r--r--keyboards/handwired/fc200rt_qmk/readme.md35
-rw-r--r--keyboards/handwired/fc200rt_qmk/rules.mk32
-rw-r--r--keyboards/handwired/jotpad16/config.h9
-rw-r--r--keyboards/handwired/jotpad16/jotpad16.c7
-rw-r--r--keyboards/handwired/jotpad16/readme.md24
-rw-r--r--keyboards/handwired/jotpad16/rules.mk2
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/config.h74
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/info.json36
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/keymaps/default/keymap.c435
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/keymaps/default/readme.md1
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/keymaps/default/rules.mk1
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/readme.md14
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/rules.mk34
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/spaget.c16
-rw-r--r--keyboards/handwired/obuwunkunubi/spaget/spaget.h47
-rw-r--r--keyboards/handwired/slash/rules.mk7
-rw-r--r--keyboards/helix/rev2/keymaps/default/keymap.c4
-rw-r--r--keyboards/helix/rev2/keymaps/five_rows/keymap.c4
-rw-r--r--keyboards/hineybush/physix/info.json288
-rw-r--r--keyboards/id80/config.h88
-rw-r--r--keyboards/id80/id80.c36
-rw-r--r--keyboards/id80/id80.h42
-rw-r--r--keyboards/id80/info.json13
-rw-r--r--keyboards/id80/keymaps/default/keymap.c35
-rw-r--r--keyboards/id80/keymaps/default/readme.md1
-rw-r--r--keyboards/id80/readme.md15
-rw-r--r--keyboards/id80/rules.mk36
-rw-r--r--keyboards/jisplit89/info.json2
-rw-r--r--keyboards/kbdfans/kbd67/mkiirgb/v2/config.h4
-rw-r--r--keyboards/kbdfans/kbd67/rev1/keymaps/default/keymap.c8
-rw-r--r--keyboards/kbdfans/kbd67/rev2/config.h6
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/default/keymap.c8
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/keymap.c58
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/readme.md4
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/via/config.h1
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/via/keymap.c45
-rw-r--r--keyboards/kbdfans/kbd67/rev2/keymaps/via/rules.mk2
-rw-r--r--keyboards/kbdfans/kbd6x/config.h6
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/konstantin/keymap.c18
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/konstantin/rules.mk1
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/via/keymap.c50
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/via/readme.md7
-rw-r--r--keyboards/kbdfans/kbd6x/keymaps/via/rules.mk2
-rw-r--r--keyboards/kbdfans/kbd8x_mk2/readme.md2
-rw-r--r--keyboards/kc60/config.h138
-rw-r--r--keyboards/kc60/info.json224
-rw-r--r--keyboards/kc60/kc60.h167
-rw-r--r--keyboards/kc60/keymaps/default/keymap.c22
-rw-r--r--keyboards/kc60/keymaps/default/readme.md5
-rw-r--r--keyboards/kc60/keymaps/ws2812/config.h11
-rw-r--r--keyboards/kc60/keymaps/ws2812/keymap.c106
-rw-r--r--keyboards/kc60/keymaps/ws2812/readme.md21
-rw-r--r--keyboards/kc60/keymaps/ws2812/rules.mk24
-rw-r--r--keyboards/kc60/mod_rgb_underglow.md31
-rw-r--r--keyboards/kc60/readme.md38
-rw-r--r--keyboards/kc60/rules.mk8
-rw-r--r--keyboards/keebio/bdn9/keymaps/via/keymap.c52
-rw-r--r--keyboards/keebio/bdn9/keymaps/via/rules.mk5
-rw-r--r--keyboards/keebio/choconum/chconf.h714
-rw-r--r--keyboards/keebio/choconum/choconum.c1
-rw-r--r--keyboards/keebio/choconum/choconum.h49
-rw-r--r--keyboards/keebio/choconum/config.h207
-rw-r--r--keyboards/keebio/choconum/halconf.h525
-rw-r--r--keyboards/keebio/choconum/info.json64
-rw-r--r--keyboards/keebio/choconum/keymaps/default/keymap.c40
-rw-r--r--keyboards/keebio/choconum/keymaps/via/keymap.c48
-rw-r--r--keyboards/keebio/choconum/keymaps/via/readme.md1
-rw-r--r--keyboards/keebio/choconum/keymaps/via/rules.mk1
-rw-r--r--keyboards/keebio/choconum/mcuconf.h176
-rw-r--r--keyboards/keebio/choconum/readme.md18
-rw-r--r--keyboards/keebio/choconum/rules.mk27
-rw-r--r--keyboards/keebio/iris/keymaps/pvinis/config.h36
-rw-r--r--keyboards/keebio/iris/keymaps/pvinis/keymap.c267
-rw-r--r--keyboards/keebio/iris/keymaps/pvinis/rules.mk11
-rw-r--r--keyboards/keebio/nyquist/keymaps/georgepetri3/config.h25
-rw-r--r--keyboards/keebio/nyquist/keymaps/georgepetri3/keymap.c106
-rw-r--r--keyboards/keebio/nyquist/keymaps/georgepetri3/readme.md52
-rw-r--r--keyboards/keebio/nyquist/keymaps/georgepetri3/rules.mk5
-rw-r--r--keyboards/keebio/quefrency/rev1/config.h3
-rw-r--r--keyboards/keebio/quefrency/rev1/rules.mk1
-rw-r--r--keyboards/keebio/quefrency/rev2/config.h5
-rw-r--r--keyboards/keebio/quefrency/rev2/rev2.c31
-rw-r--r--keyboards/keebio/quefrency/rev2/rules.mk1
-rw-r--r--keyboards/keebio/quefrency/rules.mk20
-rw-r--r--keyboards/keebwerk/nano_slider/keymaps/default/keymap.c15
-rw-r--r--keyboards/kira80/config.h2
-rw-r--r--keyboards/kira80/keymaps/via/keymap.c52
-rw-r--r--keyboards/kira80/keymaps/via/readme.md1
-rw-r--r--keyboards/kira80/keymaps/via/rules.mk3
-rw-r--r--keyboards/kudox/kudox.h3
-rw-r--r--keyboards/kudox/readme.md10
-rw-r--r--keyboards/kudox/rev3/config.h91
-rw-r--r--keyboards/kudox/rev3/info.json77
-rw-r--r--keyboards/kudox/rev3/keymaps/default/keymap.c70
-rw-r--r--keyboards/kudox/rev3/keymaps/default/readme.md1
-rw-r--r--keyboards/kudox/rev3/keymaps/jis/keymap.c70
-rw-r--r--keyboards/kudox/rev3/keymaps/jis/readme.md1
-rw-r--r--keyboards/kudox/rev3/rev3.c0
-rw-r--r--keyboards/kudox/rev3/rev3.h23
-rw-r--r--keyboards/kudox/rev3/rules.mk0
-rw-r--r--keyboards/kudox/rules.mk2
-rw-r--r--keyboards/launchpad/keymaps/via/keymap.c24
-rw-r--r--keyboards/launchpad/keymaps/via/rules.mk2
-rw-r--r--keyboards/launchpad/rev1/config.h7
-rw-r--r--keyboards/maartenwut/wasdat/config.h8
-rw-r--r--keyboards/maartenwut/wasdat/keymaps/konstantin/rules.mk1
-rw-r--r--keyboards/maartenwut/wasdat/keymaps/via/keymap.c96
-rw-r--r--keyboards/maartenwut/wasdat/keymaps/via/rules.mk2
-rw-r--r--keyboards/maartenwut/wasdat/rules.mk2
-rw-r--r--keyboards/maartenwut/wasdat/wasdat.h19
-rw-r--r--keyboards/massdrop/ctrl/keymaps/default/keymap.c6
-rw-r--r--keyboards/melody96/keymaps/konstantin/rules.mk1
-rw-r--r--keyboards/mint60/config.h1
-rw-r--r--keyboards/niu_mini/config.h4
-rw-r--r--keyboards/niu_mini/keymaps/via/keymap.c79
-rw-r--r--keyboards/niu_mini/keymaps/via/rules.mk2
-rw-r--r--keyboards/pancake/config.h4
-rw-r--r--keyboards/pancake/feather/config.h2
-rw-r--r--keyboards/pancake/info.json2
-rw-r--r--keyboards/pancake/pancake.c2
-rw-r--r--keyboards/pancake/pancake.h2
-rw-r--r--keyboards/pancake/promicro/config.h2
-rw-r--r--keyboards/pancake/readme.md2
-rw-r--r--keyboards/planck/keymaps/oeywil/.gitignore1
-rw-r--r--keyboards/planck/keymaps/oeywil/config.h37
-rw-r--r--keyboards/planck/keymaps/oeywil/keymap.c392
-rw-r--r--keyboards/planck/keymaps/oeywil/no_keycodes.h28
-rw-r--r--keyboards/planck/keymaps/oeywil/readme.md4
-rw-r--r--keyboards/planck/keymaps/oeywil/rules.mk11
-rw-r--r--keyboards/projectkb/alice/alice.c12
-rw-r--r--keyboards/projectkb/alice/keymaps/keithlo/keymap.c43
-rw-r--r--keyboards/projectkb/alice/readme.md2
-rw-r--r--keyboards/projectkb/alice/rev1/config.h (renamed from keyboards/projectkb/alice/config.h)3
-rw-r--r--keyboards/projectkb/alice/rev1/rules.mk27
-rw-r--r--keyboards/projectkb/alice/rev2/config.h85
-rw-r--r--keyboards/projectkb/alice/rev2/rules.mk27
-rw-r--r--keyboards/projectkb/alice/rules.mk23
-rw-r--r--keyboards/splitish/config.h43
-rw-r--r--keyboards/splitish/keymaps/default/keymap.c57
-rw-r--r--keyboards/splitish/keymaps/default/readme.md4
-rw-r--r--keyboards/splitish/readme.md18
-rw-r--r--keyboards/splitish/rules.mk23
-rw-r--r--keyboards/splitish/splitish.c1
-rw-r--r--keyboards/splitish/splitish.h14
-rw-r--r--keyboards/tgr/jane/config.h4
-rw-r--r--keyboards/tgr/jane/info.json8
-rw-r--r--keyboards/tgr/jane/jane.h36
-rw-r--r--keyboards/tgr/jane/keymaps/via/config.h1
-rw-r--r--keyboards/tgr/jane/keymaps/via/keymap.c43
-rw-r--r--keyboards/tgr/jane/keymaps/via/rules.mk5
-rw-r--r--keyboards/tkc1800/keymaps/yanfali/rules.mk1
-rw-r--r--keyboards/walletburner/neuron/info.json4
-rw-r--r--keyboards/wheatfield/split75/README.md28
-rw-r--r--keyboards/wheatfield/split75/config.h18
-rw-r--r--keyboards/wheatfield/split75/info.json12
-rw-r--r--keyboards/wheatfield/split75/keymaps/art/keymap.c189
-rw-r--r--keyboards/wheatfield/split75/keymaps/default/keymap.c30
-rw-r--r--keyboards/wheatfield/split75/matrix.c155
-rw-r--r--keyboards/wheatfield/split75/rules.mk31
-rw-r--r--keyboards/wheatfield/split75/split75.c25
-rw-r--r--keyboards/wheatfield/split75/split75.h33
-rw-r--r--keyboards/whitefox/keymaps/konstantin/rules.mk1
-rw-r--r--keyboards/winkeyless/bface/config.h2
-rw-r--r--keyboards/winkeyless/bface/keymaps/via/config.h1
-rw-r--r--keyboards/winkeyless/bface/keymaps/via/keymap.c43
-rw-r--r--keyboards/winkeyless/bface/keymaps/via/rules.mk5
-rw-r--r--keyboards/winkeyless/bmini/bmini.h24
-rw-r--r--keyboards/winkeyless/bmini/config.h2
-rw-r--r--keyboards/winkeyless/bmini/keymaps/via/config.h1
-rw-r--r--keyboards/winkeyless/bmini/keymaps/via/keymap.c46
-rw-r--r--keyboards/winkeyless/bmini/keymaps/via/rules.mk5
-rw-r--r--keyboards/winkeyless/bminiex/bminiex.h20
-rw-r--r--keyboards/winkeyless/bminiex/config.h2
-rw-r--r--keyboards/winkeyless/bminiex/keymaps/via/config.h1
-rw-r--r--keyboards/winkeyless/bminiex/keymaps/via/keymap.c47
-rw-r--r--keyboards/winkeyless/bminiex/keymaps/via/rules.mk5
-rw-r--r--keyboards/winkeyless/readme.md2
-rw-r--r--keyboards/wsk/gothic50/rules.mk3
-rw-r--r--keyboards/wsk/gothic70/rules.mk3
-rw-r--r--keyboards/yd60mq/12led/config.h5
-rw-r--r--keyboards/yd60mq/12led/readme.md3
-rw-r--r--keyboards/yd60mq/12led/rules.mk0
-rw-r--r--keyboards/yd60mq/16led/config.h5
-rw-r--r--keyboards/yd60mq/16led/readme.md3
-rw-r--r--keyboards/yd60mq/16led/rules.mk0
-rw-r--r--keyboards/yd60mq/config.h5
-rw-r--r--keyboards/yd60mq/readme.md16
-rw-r--r--keyboards/yd60mq/rules.mk2
-rw-r--r--keyboards/yd60mq/yd60mq.c2
-rw-r--r--keyboards/yushakobo/quick7/config.h252
-rw-r--r--keyboards/yushakobo/quick7/info.json16
-rw-r--r--keyboards/yushakobo/quick7/keymaps/default/keymap.c72
-rw-r--r--keyboards/yushakobo/quick7/keymaps/default/readme.md25
-rw-r--r--keyboards/yushakobo/quick7/quick7.c17
-rw-r--r--keyboards/yushakobo/quick7/quick7.h38
-rw-r--r--keyboards/yushakobo/quick7/readme.md15
-rw-r--r--keyboards/yushakobo/quick7/rules.mk34
-rw-r--r--layouts/community/60_tsangan_hhkb/yanfali_wkl/keymap.c25
-rw-r--r--layouts/community/75_ansi/spidey3/keymap.c31
-rw-r--r--layouts/community/75_ansi/spidey3/rules.mk3
-rw-r--r--lib/python/milc.py88
-rw-r--r--lib/python/qmk/cli/__init__.py7
-rw-r--r--lib/python/qmk/cli/cformat.py7
-rw-r--r--lib/python/qmk/cli/docs.py2
-rwxr-xr-xlib/python/qmk/cli/doctor.py13
-rwxr-xr-xlib/python/qmk/cli/hello.py2
-rwxr-xr-xlib/python/qmk/cli/json2c.py8
-rwxr-xr-xlib/python/qmk/cli/kle2json.py10
-rwxr-xr-xlib/python/qmk/cli/new/keymap.py2
-rwxr-xr-xlib/python/qmk/cli/pyformat.py2
-rw-r--r--lib/python/qmk/cli/pytest.py2
-rw-r--r--lib/python/qmk/commands.py4
-rw-r--r--lib/python/qmk/keymap.py19
-rw-r--r--quantum/debounce/eager_pk.c20
-rw-r--r--quantum/debounce/eager_pr.c12
-rw-r--r--quantum/debounce/sym_pk.c111
-rw-r--r--quantum/dip_switch.c4
-rw-r--r--quantum/keymap_extras/keymap_fr_ch.h303
-rw-r--r--quantum/keymap_extras/keymap_french_osx.h306
-rw-r--r--quantum/keymap_extras/keymap_german_ch.h245
-rw-r--r--quantum/keymap_extras/keymap_german_osx.h385
-rw-r--r--quantum/keymap_extras/keymap_italian_osx_ansi.h333
-rw-r--r--quantum/keymap_extras/keymap_italian_osx_iso.h334
-rw-r--r--quantum/keymap_extras/keymap_workman_zxcvm.h125
-rw-r--r--quantum/keymap_extras/sendstring_fr_ch.h100
-rw-r--r--quantum/keymap_extras/sendstring_french.h2
-rw-r--r--quantum/keymap_extras/sendstring_french_osx.h100
-rw-r--r--quantum/keymap_extras/sendstring_german_ch.h100
-rw-r--r--quantum/keymap_extras/sendstring_german_osx.h100
-rw-r--r--quantum/keymap_extras/sendstring_italian_osx_ansi.h100
-rw-r--r--quantum/keymap_extras/sendstring_italian_osx_iso.h100
-rw-r--r--quantum/keymap_extras/sendstring_workman_zxcvm.h59
-rw-r--r--quantum/quantum.c13
-rw-r--r--quantum/quantum.h4
-rw-r--r--quantum/quantum_keycodes.h9
-rw-r--r--quantum/send_string_keycodes.h2
-rw-r--r--quantum/template/avr/config.h7
-rw-r--r--quantum/template/ps2avrgb/config.h6
-rw-r--r--requirements-dev.txt8
-rw-r--r--requirements.txt3
-rw-r--r--tmk_core/avr.mk14
-rw-r--r--tmk_core/common.mk2
-rw-r--r--tmk_core/common/action.c2
-rw-r--r--tmk_core/common/action.h10
-rw-r--r--tmk_core/common/action_tapping.c8
-rw-r--r--tmk_core/common/action_tapping.h2
-rw-r--r--tmk_core/common/keycode.h2
-rw-r--r--tmk_core/common/timer.h2
-rw-r--r--tmk_core/protocol/chibios/init_hooks.h5
-rw-r--r--tmk_core/protocol/chibios/main.c38
-rw-r--r--tmk_core/protocol/lufa.mk1
-rw-r--r--tmk_core/protocol/lufa/adafruit_ble.cpp162
-rw-r--r--tmk_core/protocol/ps2_mouse.c15
-rw-r--r--tmk_core/rules.mk18
-rw-r--r--users/dennytom/chording_engine/README.md376
-rw-r--r--users/dennytom/chording_engine/chord.py466
-rw-r--r--users/dennytom/chording_engine/engine.part.1163
-rw-r--r--users/dennytom/chording_engine/engine.part.2323
-rw-r--r--users/dennytom/chording_engine/engine.part.3404
-rw-r--r--users/dennytom/chording_engine/keymap_def.schema.json337
-rw-r--r--users/dennytom/chording_engine/parser.py231
-rw-r--r--users/dennytom/chording_engine/state_machine.dot49
-rw-r--r--users/dennytom/chording_engine/state_machine.svg235
-rw-r--r--users/dennytom/chording_engine/tests/minunit.h288
-rw-r--r--users/dennytom/chording_engine/tests/test.c1259
-rw-r--r--users/dennytom/chording_engine/tests/test_full.sh11
-rw-r--r--users/dennytom/chording_engine/tests/test_keymap_def.json145
-rw-r--r--users/dennytom/chording_engine/tests/test_quick.sh6
-rw-r--r--users/konstantin/config.h12
-rw-r--r--users/konstantin/konstantin.c11
-rw-r--r--users/konstantin/konstantin.h1
-rw-r--r--users/konstantin/rgb.h2
-rw-r--r--users/konstantin/rules.mk2
-rw-r--r--users/pvinis/config.h9
-rw-r--r--users/pvinis/pvinis.c127
-rw-r--r--users/pvinis/pvinis.h228
-rw-r--r--users/pvinis/rules.mk34
-rw-r--r--users/spidey3/init.c15
-rw-r--r--users/spidey3/layer_rgb.c76
-rw-r--r--users/spidey3/spidey3.c18
-rw-r--r--users/spidey3/spidey3.h5
-rw-r--r--users/stanrc85/config.h1
-rw-r--r--users/stanrc85/rgblight_layers.c47
-rw-r--r--users/stanrc85/rules.mk10
-rw-r--r--users/yanfali/rules.mk4
l---------users/yanfali_wkl1
-rw-r--r--util/1-setup-path-win.bat66
-rw-r--r--util/2-setup-environment-win.bat72
-rw-r--r--util/ELEVATE_LICENSE.md25
-rw-r--r--util/Win_Check.bat208
-rwxr-xr-xutil/activate_msys2.sh1
-rwxr-xr-xutil/activate_wsl.sh1
-rw-r--r--util/add-paths.bat30
-rw-r--r--util/elevate.exebin79360 -> 0 bytes
-rwxr-xr-xutil/linux_install.sh11
-rwxr-xr-xutil/msys2_install.sh14
-rwxr-xr-xutil/win_shared_install.sh4
-rwxr-xr-xutil/wsl_install.sh15
453 files changed, 26618 insertions, 3009 deletions
diff --git a/.clang_complete b/.clang_complete
deleted file mode 100644
index 21434586c..000000000
--- a/.clang_complete
+++ /dev/null
@@ -1,24 +0,0 @@
-
--I.
--I./drivers
--I./drivers/avr
--I./keyboards/ergodox_ez
--I./keyboards/ergodox_ez/keymaps/vim
--I./lib
--I./lib/lufa
--I./quantum
--I./quantum/api
--I./quantum/audio
--I./quantum/keymap_extras
--I./quantum/process_keycode
--I./quantum/serial_link
--I./quantum/template
--I./quantum/tools
--I./quantum/visualizer
--I./tmk_core
--I./tmk_core/common
--I./tmk_core/common/debug.h
--I./tmk_core/protocol
--I./tmk_core/protocol/lufa
--I./util
--DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\"
diff --git a/.gitignore b/.gitignore
index 0e80cdb6c..20437224f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ quantum/version.h
.idea/
CMakeLists.txt
cmake-build-debug
+.clang_complete
doxygen/
.DS_Store
/util/wsl_downloaded
@@ -47,7 +48,6 @@ doxygen/
*.iml
.browse.VC.db*
*.stackdump
-util/Win_Check_Output.txt
# Let these ones be user specific, since we have so many different configurations
.vscode/c_cpp_properties.json
.vscode/launch.json
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f17b9e23e..9aa546a78 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -9,13 +9,17 @@
"**/*.bin": true
},
"files.associations": {
- "*.h": "c",
- "*.c": "c",
- "*.inc": "c",
- "*.cpp": "cpp",
- "*.hpp": "cpp",
- "xstddef": "c",
- "type_traits": "c",
- "utility": "c"
+ "*.h": "c",
+ "*.c": "c",
+ "*.inc": "c",
+ "*.cpp": "cpp",
+ "*.hpp": "cpp",
+ "xstddef": "c",
+ "type_traits": "c",
+ "utility": "c"
+ },
+ "[markdown]": {
+ "editor.trimAutoWhitespace": false,
+ "files.trimTrailingWhitespace": false
}
}
diff --git a/autocomplete.sh b/autocomplete.sh
deleted file mode 100644
index dffb260c4..000000000
--- a/autocomplete.sh
+++ /dev/null
@@ -1 +0,0 @@
-complete -W " 9key-default alps64-default amj40-default amj40-fabian amj60-default_60_ansi amj60-iso_split_rshift amj60-maximized amjpad-default amjpad-max amjpad-ortho_left amjpad-ortho_right atomic-default atomic-default_ortho_5x15 atomic-pvc atreus-alphadox atreus-classic atreus-default atreus-erlandsona atreus-gerb atreus-jeremy atreus-replicaJunction atreus-xyverz atreus62-atreus52 atreus62-default atreus62-mneme atreus62-xyverz bananasplit-0010 bananasplit-coloneljesus bananasplit-default bananasplit-hhkbanana bananasplit-nic bananasplit-rask bantam44-default chibios_test-default clueboard-bloodlvst clueboard-caps_fn clueboard-colemak clueboard-default clueboard-jokrik clueboard-mac_optimized clueboard-magicmonty clueboard-maximised clueboard-mouse_keys clueboard-serubin clueboard-shift_fn clueboard-skully clueboard-smt clueboard-tetris clueboard-unix_optimized clueboard-win_optimized clueboard-xyverz cluecard-default cluecard-rgb_effects cluepad-default deltasplit75-default deltasplit75-itsaferbie deltasplit75-protosplit dk60-default eco-default eco-that_canadian ergodone-333fred ergodone-ab ergodone-absenth ergodone-adam ergodone-adnw_k_o_y ergodone-albert ergodone-alexjj ergodone-algernon ergodone-alphadox ergodone-andrew_osx ergodone-belak ergodone-bepo ergodone-bepo_csa ergodone-bryan ergodone-coderkun_neo2 ergodone-colemak ergodone-colemak_osx_pc_no ergodone-colemak_programmer ergodone-common_nighthawk ergodone-csharp_dev ergodone-dave ergodone-deadcyclo ergodone-default ergodone-default_ergodox ergodone-dragon788 ergodone-dvorak ergodone-dvorak_emacs ergodone-dvorak_emacs_software ergodone-dvorak_intl_squisher ergodone-dvorak_plover ergodone-dvorak_programmer ergodone-dvorak_programmer_swe ergodone-dvorak_spanish ergodone-emacs_osx_dk ergodone-erez_experimental ergodone-familiar ergodone-french_hacker ergodone-galson ergodone-german ergodone-german-kinergo ergodone-german-lukas ergodone-german-manuneo ergodone-guni ergodone-ishigoya-jp ergodone-italian ergodone-j3rn ergodone-jack ergodone-jacobono ergodone-jafo ergodone-jgarr ergodone-josh ergodone-kastyle ergodone-kines-ish ergodone-kristian ergodone-maz ergodone-mclennon_osx ergodone-mpiechotka ergodone-msc ergodone-naps62 ergodone-neo2_on_qwertz_hardware ergodone-norwegian_programmer_osx_pc ergodone-norwegian_programmer_osx_pc_colemak ergodone-ordinary ergodone-osx_de ergodone-osx_de_adnw_koy ergodone-osx_de_experimental ergodone-osx_fr ergodone-osx_kinesis_pnut ergodone-osx_whiskey_tango_foxtrot_capslock ergodone-phoenix ergodone-plover ergodone-plums ergodone-pvinis ergodone-replicaJunction ergodone-reset_eeprom ergodone-robot_test_layout ergodone-romanzolotarev-norman-osx ergodone-romanzolotarev-norman-plover-osx ergodone-romanzolotarev-norman-plover-osx-hjkl ergodone-romanzolotarev-norman-qwerty-osx ergodone-sethbc ergodone-siroken3 ergodone-sneako ergodone-software_neo2 ergodone-supercoder ergodone-swedish ergodone-swedish-lindhe ergodone-swissgerman ergodone-techtomas ergodone-teckinesis ergodone-tkuichooseyou ergodone-tm2030 ergodone-tonyabra_osx ergodone-townk_osx ergodone-twentylives_dvorak_with_hebrew ergodone-twey ergodone-videck ergodone-win10_writers-block ergodone-workman_osx_mdw ergodone-xyverz ergodone-yoruian ergodone-zweihander-osx ergodox_ez-333fred ergodox_ez-ab ergodox_ez-absenth ergodox_ez-adam ergodox_ez-adnw_k_o_y ergodox_ez-albert ergodox_ez-alexjj ergodox_ez-algernon ergodox_ez-alphadox ergodox_ez-andrew_osx ergodox_ez-belak ergodox_ez-bepo ergodox_ez-bepo_csa ergodox_ez-blakedietz ergodox_ez-bryan ergodox_ez-coderkun_neo2 ergodox_ez-colemak ergodox_ez-colemak_osx_pc_no ergodox_ez-colemak_programmer ergodox_ez-common_nighthawk ergodox_ez-csharp_dev ergodox_ez-dave ergodox_ez-deadcyclo ergodox_ez-default ergodox_ez-default_ergodox ergodox_ez-default_osx ergodox_ez-dragon788 ergodox_ez-drashna ergodox_ez-drashna-custom ergodox_ez-dvorak ergodox_ez-dvorak_emacs ergodox_ez-dvorak_emacs_software ergodox_ez-dvorak_intl_squisher ergodox_ez-dvorak_plover ergodox_ez-dvorak_programmer ergodox_ez-dvorak_programmer_swe ergodox_ez-dvorak_spanish ergodox_ez-emacs_osx_dk ergodox_ez-erez_experimental ergodox_ez-familiar ergodox_ez-french_hacker ergodox_ez-galson ergodox_ez-german ergodox_ez-german-kinergo ergodox_ez-german-lukas ergodox_ez-german-manuneo ergodox_ez-guni ergodox_ez-ishigoya-jp ergodox_ez-italian ergodox_ez-j3rn ergodox_ez-jack ergodox_ez-jacobono ergodox_ez-jafo ergodox_ez-jgarr ergodox_ez-josh ergodox_ez-kastyle ergodox_ez-kines-ish ergodox_ez-kristian ergodox_ez-maz ergodox_ez-mclennon_osx ergodox_ez-mpiechotka ergodox_ez-msc ergodox_ez-naps62 ergodox_ez-neo2_on_qwertz_hardware ergodox_ez-norwegian_programmer_osx_pc ergodox_ez-norwegian_programmer_osx_pc_colemak ergodox_ez-ordinary ergodox_ez-osx_de ergodox_ez-osx_de_adnw_koy ergodox_ez-osx_de_experimental ergodox_ez-osx_fr ergodox_ez-osx_kinesis_pnut ergodox_ez-osx_whiskey_tango_foxtrot_capslock ergodox_ez-phoenix ergodox_ez-plover ergodox_ez-plums ergodox_ez-profet_80 ergodox_ez-pvinis ergodox_ez-replicaJunction ergodox_ez-reset_eeprom ergodox_ez-robot_test_layout ergodox_ez-romanzolotarev-norman-osx ergodox_ez-romanzolotarev-norman-plover-osx ergodox_ez-romanzolotarev-norman-plover-osx-hjkl ergodox_ez-romanzolotarev-norman-qwerty-osx ergodox_ez-sethbc ergodox_ez-siroken3 ergodox_ez-sneako ergodox_ez-software_neo2 ergodox_ez-steno ergodox_ez-supercoder ergodox_ez-swedish ergodox_ez-swedish-lindhe ergodox_ez-swissgerman ergodox_ez-techtomas ergodox_ez-teckinesis ergodox_ez-tkuichooseyou ergodox_ez-tm2030 ergodox_ez-tonyabra_osx ergodox_ez-townk_osx ergodox_ez-twentylives_dvorak_with_hebrew ergodox_ez-twey ergodox_ez-videck ergodox_ez-win10_writers-block ergodox_ez-workman_osx_mdw ergodox_ez-xyverz ergodox_ez-yoruian ergodox_ez-zweihander-osx ergodox_infinity-333fred ergodox_infinity-ab ergodox_infinity-absenth ergodox_infinity-adam ergodox_infinity-adnw_k_o_y ergodox_infinity-albert ergodox_infinity-alexjj ergodox_infinity-algernon ergodox_infinity-alphadox ergodox_infinity-andrew_osx ergodox_infinity-belak ergodox_infinity-bepo ergodox_infinity-bepo_csa ergodox_infinity-bryan ergodox_infinity-coderkun_neo2 ergodox_infinity-colemak ergodox_infinity-colemak_osx_pc_no ergodox_infinity-colemak_programmer ergodox_infinity-common_nighthawk ergodox_infinity-csharp_dev ergodox_infinity-dave ergodox_infinity-deadcyclo ergodox_infinity-default_ergodox ergodox_infinity-dragon788 ergodox_infinity-dvorak ergodox_infinity-dvorak_emacs ergodox_infinity-dvorak_emacs_software ergodox_infinity-dvorak_intl_squisher ergodox_infinity-dvorak_plover ergodox_infinity-dvorak_programmer ergodox_infinity-dvorak_programmer_swe ergodox_infinity-dvorak_spanish ergodox_infinity-emacs_osx_dk ergodox_infinity-erez_experimental ergodox_infinity-familiar ergodox_infinity-french_hacker ergodox_infinity-galson ergodox_infinity-german ergodox_infinity-german-kinergo ergodox_infinity-german-lukas ergodox_infinity-german-manuneo ergodox_infinity-guni ergodox_infinity-ishigoya-jp ergodox_infinity-italian ergodox_infinity-j3rn ergodox_infinity-jack ergodox_infinity-jacobono ergodox_infinity-jafo ergodox_infinity-jgarr ergodox_infinity-josh ergodox_infinity-kastyle ergodox_infinity-kines-ish ergodox_infinity-kristian ergodox_infinity-maz ergodox_infinity-mclennon_osx ergodox_infinity-mpiechotka ergodox_infinity-msc ergodox_infinity-naps62 ergodox_infinity-neo2_on_qwertz_hardware ergodox_infinity-norwegian_programmer_osx_pc ergodox_infinity-norwegian_programmer_osx_pc_colemak ergodox_infinity-ordinary ergodox_infinity-osx_de ergodox_infinity-osx_de_adnw_koy ergodox_infinity-osx_de_experimental ergodox_infinity-osx_fr ergodox_infinity-osx_kinesis_pnut ergodox_infinity-osx_whiskey_tango_foxtrot_capslock ergodox_infinity-phoenix ergodox_infinity-plover ergodox_infinity-plums ergodox_infinity-pvinis ergodox_infinity-replicaJunction ergodox_infinity-reset_eeprom ergodox_infinity-robot_test_layout ergodox_infinity-romanzolotarev-norman-osx ergodox_infinity-romanzolotarev-norman-plover-osx ergodox_infinity-romanzolotarev-norman-plover-osx-hjkl ergodox_infinity-romanzolotarev-norman-qwerty-osx ergodox_infinity-sethbc ergodox_infinity-siroken3 ergodox_infinity-sneako ergodox_infinity-software_neo2 ergodox_infinity-supercoder ergodox_infinity-swedish ergodox_infinity-swedish-lindhe ergodox_infinity-swissgerman ergodox_infinity-techtomas ergodox_infinity-teckinesis ergodox_infinity-tkuichooseyou ergodox_infinity-tm2030 ergodox_infinity-tonyabra_osx ergodox_infinity-townk_osx ergodox_infinity-twentylives_dvorak_with_hebrew ergodox_infinity-twey ergodox_infinity-videck ergodox_infinity-win10_writers-block ergodox_infinity-workman_osx_mdw ergodox_infinity-xyverz ergodox_infinity-yoruian ergodox_infinity-zweihander-osx four_banger-default frosty_flake-default frosty_flake-nikchi frosty_flake-tkl gh60-dbroqua gh60-dbroqua_7U gh60-default gh60-default_60_ansi gh60-default_60_ansi_split_bs_rshift gh60-default_60_iso gh60-robotmaxtron gh60-sethbc gh60-talljoe gh60-unxmaal gh60-xyverz gherkin-default gherkin-mjt gherkin-steno gherkin-talljoe gonnerd-default gonnerd-mauin gonnerd-tkl hadron-default hadron-side_numpad hhkb-blakedietz hhkb-cinaeco hhkb-dbroqua hhkb-default hhkb-jp hhkb-jp_mac hhkb-lxol hhkb-mjt hhkb-rdg_jp hhkb-sh_jp hhkb-shela hhkb-smt infinity60-default infinity60-default_60_ansi_split_bs_rshift infinity60-depariel infinity60-hasu infinity60-jpetermans infinity60-talljoe jc65-default jc65-jetpacktuxedo jd40-default jd40-vanagon jd45-blakedietz jd45-default jd45-jeebak jd45-justin jd45-mjt jd45-mjt6u kbd75-default kc60-dbroqua kc60-dbroqua_hhkb kc60-default kc60-default_60_ansi kc60-mechmerlin kc60-sgoodwin kc60-stanleylai kc60-wigguno kc60-workman-dead kc60-ws2812 kinesis-default kinesis-dvorak kinesis-milestogo kinesis-xyverz kitten_paw-default kitten_paw-ickerwx kmac-default kmac-winkeyless lets_split-OLED_sample lets_split-adam lets_split-dale lets_split-default lets_split-default_ortho_4x12 lets_split-ergodoxish lets_split-fabian lets_split-henxing lets_split-hexwire lets_split-khord lets_split-mbsurfer lets_split-mjt lets_split-piemod lets_split-smt lets_split-xk lets_split-xyverz m10a-default maxipad-default mechmini-default minidox-default minidox-that_canadian mitosis-carvac_dv mitosis-default mitosis-mjt miuni32-adam-lee miuni32-default miuni32-ht_156 nyquist-333fred nyquist-default nyquist-default_ortho_5x12 nyquist-hexwire org60-boardy org60-default orthodox-default pegasushoof-blowrak pegasushoof-default phantom-default phantom-rgbmod phantom-xyverz planck-ab planck-alexey planck-angerthosenear planck-austin planck-basic planck-bone2planck planck-brandon planck-callum planck-cbbrowne planck-chance planck-charlie planck-circuit planck-coloneljesus planck-dale planck-daniel planck-david planck-dbroqua planck-default planck-default_ortho_4x12 planck-dshields planck-dzobert planck-ergodoxish planck-espynn planck-experimental planck-gabriel planck-handwired_binaryplease planck-impossible planck-jacob planck-jeebak planck-jeremy-dev planck-jhenahan planck-joe planck-johannes planck-khord planck-kyle planck-lae3 planck-leo planck-lucas planck-lukas planck-luke planck-max planck-mitch planck-mjt planck-mjtnumsym planck-mollat planck-nico planck-originerd planck-pete planck-piemod planck-premek planck-priyadi planck-pvc planck-rai-suta planck-sgoodwin planck-smt planck-steno planck-tak3over planck-thermal_printer planck-tong92 planck-unicode planck-vifon planck-xyverz planck-yale planck-yang planck-zach preonic-0xdec preonic-CMD-Preonic preonic-dale preonic-default preonic-default_ortho_5x12 preonic-jacwib preonic-kinesis preonic-nikchi preonic-smt preonic-xyverz preonic-zach ps2avrGB-default roadkit-default roadkit-default_ortho_4x4 roadkit-flipphone roadkit-mjt roadkit-singles roadkit-singlesBrent s60_x-ansi_qwertz s60_x-bluebear s60_x-custom s60_x-dbroqua s60_x-default s60_x-hasu s60_x-hhkb s60_x-iso s60_x-jpec s60_x-plain s60_x-poker s60_x-poker_bit s60_x-poker_set s60_x-spacefn s65_x-default s65_x-iso s65_x-nall s65_x-smt satan-admiralStrokers satan-ben_iso satan-colemak satan-dbroqua satan-default satan-default_60_ansi satan-default_60_ansi_split_bs_rshift satan-default_60_iso satan-denolfe satan-iso_split_rshift satan-mark1 satan-midi satan-poker satan-rask63 satan-sethbc satan-smt satan-stanleylai satan-talljoe satan-unxmaal sixkeyboard-default subatomic-default sweet16-default tada68-default tada68-maartenwut tada68-rgb tiger_lily-default tv44-belak tv44-core tv44-default tv44-jeebak tv44-jetpacktuxedo tv44-mjt tv44-smt tv44-tong92 tv44-xyverz uk78-default vision_division-default whitefox-default whitefox-jetpacktuxedo whitefox-matt3o xd60-cheese xd60-default xd60-stanleylai xd75-default xd75-default_ortho_5x15 xd75-fabian" make
diff --git a/bin/qmk b/bin/qmk
index 7592eefd9..801852d4e 100755
--- a/bin/qmk
+++ b/bin/qmk
@@ -4,38 +4,59 @@
import os
import sys
from importlib.util import find_spec
+from pathlib import Path
# Add the QMK python libs to our path
-script_dir = os.path.dirname(os.path.realpath(__file__))
-qmk_dir = os.path.abspath(os.path.join(script_dir, '..'))
-python_lib_dir = os.path.abspath(os.path.join(qmk_dir, 'lib', 'python'))
-sys.path.append(python_lib_dir)
+script_dir = Path(os.path.realpath(__file__)).parent
+qmk_dir = script_dir.parent
+python_lib_dir = Path(qmk_dir / 'lib' / 'python').resolve()
+sys.path.append(str(python_lib_dir))
-# Make sure our modules have been setup
-with open(os.path.join(qmk_dir, 'requirements.txt'), 'r') as fd:
- for line in fd.readlines():
- line = line.strip().replace('<', '=').replace('>', '=')
- if line[0] == '#':
- continue
+def _check_modules(requirements):
+ """ Check if the modules in the given requirements.txt are available.
+ """
+ with Path(qmk_dir / requirements).open() as fd:
+ for line in fd.readlines():
+ line = line.strip().replace('<', '=').replace('>', '=')
+
+ if len(line) == 0 or line[0] == '#' or line.startswith('-r'):
+ continue
- if '#' in line:
- line = line.split('#')[0]
+ if '#' in line:
+ line = line.split('#')[0]
- module = line.split('=')[0] if '=' in line else line
+ module = dict()
+ module['name'] = module['import'] = line.split('=')[0] if '=' in line else line
- if module in ['pep8-naming']:
# Not every module is importable by its own name.
- continue
+ if module['name'] == "pep8-naming":
+ module['import'] = "pep8ext_naming"
- if not find_spec(module):
- print('Could not find module %s!' % module)
- print('Please run `pip3 install -r requirements.txt` to install the python dependencies.')
- exit(255)
+ if not find_spec(module['import']):
+ print('Could not find module %s!' % module['name'])
+ print('Please run `python3 -m pip install -r %s` to install required python dependencies.' % (qmk_dir / requirements,))
+ if developer:
+ print('You can also turn off developer mode: qmk config user.developer=None')
+ print()
+ exit(255)
+
+
+developer = False
+# Make sure our modules have been setup
+_check_modules('requirements.txt')
# Setup the CLI
import milc # noqa
+# For developers additional modules are needed
+if milc.cli.config.user.developer:
+ # Do not run the check for 'config',
+ # so users can turn off developer mode
+ if len(sys.argv) == 1 or (len(sys.argv) > 1 and 'config' != sys.argv[1]):
+ developer = True
+ _check_modules('requirements-dev.txt')
+
milc.EMOJI_LOGLEVELS['INFO'] = '{fg_blue}Ψ{style_reset_all}'
diff --git a/build_json.mk b/build_json.mk
index 087944cc4..6e2f9c4c8 100644
--- a/build_json.mk
+++ b/build_json.mk
@@ -21,6 +21,11 @@ else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
endif
+# Load the keymap-level rules.mk if exists
+ifneq ("$(wildcard $(KEYMAP_PATH))", "")
+ -include $(KEYMAP_PATH)/rules.mk
+endif
+
# Generate the keymap.c
$(KEYBOARD_OUTPUT)/src/keymap.c: $(KEYMAP_JSON)
bin/qmk json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON)
diff --git a/docs/_summary.md b/docs/_summary.md
index 4a6e6996e..d47b252c0 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -121,6 +121,7 @@
* [Drivers](hardware_drivers.md)
* [ADC Driver](adc_driver.md)
* [I2C Driver](i2c_driver.md)
+ * [SPI Driver](spi_driver.md)
* [WS2812 Driver](ws2812_driver.md)
* [EEPROM Driver](eeprom_driver.md)
* [GPIO Controls](internals_gpio_control.md)
@@ -135,6 +136,10 @@
* [Development Environment](api_development_environment.md)
* [Architecture Overview](api_development_overview.md)
+ * Hardware Platform Development
+ * Arm/ChibiOS
+ * [Early initialization](platformdev_chibios_earlyinit.md)
+
* QMK Reference
* [Contributing to QMK](contributing.md)
* [Translating the QMK Docs](translating.md)
diff --git a/docs/cli.md b/docs/cli.md
index 760fe1cdb..01641bd8b 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -6,7 +6,7 @@ The QMK CLI makes building and working with QMK keyboards easier. We have provid
### Requirements :id=requirements
-The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
+QMK requires Python 3.6 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
@@ -21,7 +21,7 @@ qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build
### Install Using easy_install or pip :id=install-using-easy_install-or-pip
-If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command:
+If your system is not listed above you can install QMK manually. First ensure that you have python 3.6 (or later) installed and have installed pip. Then install QMK with this command:
```
pip3 install qmk
diff --git a/docs/cli_commands.md b/docs/cli_commands.md
index eb5362bd2..eff5321bd 100644
--- a/docs/cli_commands.md
+++ b/docs/cli_commands.md
@@ -1,38 +1,6 @@
# QMK CLI Commands
-# CLI Commands
-
-## `qmk cformat`
-
-This command formats C code using clang-format.
-
-Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b <branch_name>`
-
-Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files.
-
-**Usage for specified files**:
-
-```
-qmk cformat [file1] [file2] [...] [fileN]
-```
-
-**Usage for all core files**:
-
-```
-qmk cformat -a
-```
-
-**Usage for only changed files against origin/master**:
-
-```
-qmk cformat
-```
-
-**Usage for only changed files against branch_name**:
-
-```
-qmk cformat -b branch_name
-```
+# User Commands
## `qmk compile`
@@ -136,16 +104,6 @@ This command lets you configure the behavior of QMK. For the full `qmk config` d
qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
```
-## `qmk docs`
-
-This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
-
-**Usage**:
-
-```
-qmk docs [-p PORT]
-```
-
## `qmk doctor`
This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to.
@@ -180,56 +138,102 @@ Creates a keymap.c from a QMK Configurator export.
qmk json2c [-o OUTPUT] filename
```
-## `qmk kle2json`
+## `qmk list-keyboards`
-This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
+This command lists all the keyboards currently defined in `qmk_firmware`
**Usage**:
```
-qmk kle2json [-f] <filename>
+qmk list-keyboards
```
-**Examples**:
+## `qmk list-keymaps`
+
+This command lists all the keymaps for a specified keyboard (and revision).
+
+**Usage**:
```
-$ qmk kle2json kle.txt
-☒ File info.json already exists, use -f or --force to overwrite.
+qmk list-keymaps -kb planck/ez
```
+## `qmk new-keymap`
+
+This command creates a new keymap based on a keyboard's existing default keymap.
+
+**Usage**:
+
```
-$ qmk kle2json -f kle.txt -f
-Ψ Wrote out to info.json
+qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
```
-## `qmk list-keyboards`
+---
-This command lists all the keyboards currently defined in `qmk_firmware`
+# Developer Commands
-**Usage**:
+## `qmk cformat`
+
+This command formats C code using clang-format.
+
+Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b <branch_name>`
+
+Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files.
+
+**Usage for specified files**:
```
-qmk list-keyboards
+qmk cformat [file1] [file2] [...] [fileN]
```
-## `qmk list-keymaps`
+**Usage for all core files**:
-This command lists all the keymaps for a specified keyboard (and revision).
+```
+qmk cformat -a
+```
+
+**Usage for only changed files against origin/master**:
+
+```
+qmk cformat
+```
+
+**Usage for only changed files against branch_name**:
+
+```
+qmk cformat -b branch_name
+```
+
+## `qmk docs`
+
+This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
**Usage**:
```
-qmk list-keymaps -kb planck/ez
+qmk docs [-p PORT]
```
-## `qmk new-keymap`
+## `qmk kle2json`
-This command creates a new keymap based on a keyboard's existing default keymap.
+This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
**Usage**:
```
-qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
+qmk kle2json [-f] <filename>
+```
+
+**Examples**:
+
+```
+$ qmk kle2json kle.txt
+☒ File info.json already exists, use -f or --force to overwrite.
+```
+
+```
+$ qmk kle2json -f kle.txt -f
+Ψ Wrote out to info.json
```
## `qmk pyformat`
@@ -251,3 +255,4 @@ This command runs the python test suite. If you make changes to python code you
```
qmk pytest
```
+
diff --git a/docs/cli_development.md b/docs/cli_development.md
index cc8c59d06..af86686c0 100644
--- a/docs/cli_development.md
+++ b/docs/cli_development.md
@@ -6,6 +6,18 @@ This document has useful information for developers wishing to write new `qmk` s
The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None.
+## Developer mode:
+
+If you intend to maintain keyboards and/or contribute to QMK, you can enable the CLI's "Developer" mode:
+
+`qmk config user.developer=True`
+
+This will allow you to see all available subcommands.
+**Note:** You will have to install additional requirements:
+```bash
+python3 -m pip install -r requirements-dev.txt
+```
+
# Subcommands
[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code.
@@ -32,7 +44,7 @@ def hello(cli):
First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function.
-Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.5/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
+Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator.
# User Interaction
@@ -44,13 +56,13 @@ There are two main methods for outputting text in a subcommand- `cli.log` and `c
You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below.
-Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.5/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
+Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example.
You should never use the format operator (`%`) directly, always pass values as arguments.
### Logging (`cli.log`)
-The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.5/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
+The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong.
The default log level is `INFO`. If the user runs `qmk -v <subcommand>` the default log level will be set to `DEBUG`.
diff --git a/docs/coding_conventions_python.md b/docs/coding_conventions_python.md
index 1aefc044e..47dff7f8e 100644
--- a/docs/coding_conventions_python.md
+++ b/docs/coding_conventions_python.md
@@ -2,7 +2,7 @@
Most of our style follows PEP8 with some local modifications to make things less nit-picky.
-* We target Python 3.5 for compatability with all supported platforms.
+* We target Python 3.6 for compatability with all supported platforms.
* We indent using four (4) spaces (soft tabs)
* We encourage liberal use of comments
* Think of them as a story describing the feature
@@ -317,7 +317,7 @@ At the time of this writing our tests are not very comprehensive. Looking at the
## Integration Tests
-Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.5/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened.
+Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened.
## Unit Tests
diff --git a/docs/config_options.md b/docs/config_options.md
index 661cfccce..16fea83a3 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -115,9 +115,9 @@ If you define these options you will disable the associated feature, which can s
* `#define NO_ACTION_ONESHOT`
* disable one-shot modifiers
* `#define NO_ACTION_MACRO`
- * disable old style macro handling: MACRO() & action_get_macro
+ * disable old-style macro handling using `MACRO()`, `action_get_macro()` _(deprecated)_
* `#define NO_ACTION_FUNCTION`
- * disable calling of action_function() from the fn_actions array (deprecated)
+ * disable old-style function handling using `fn_actions`, `action_function()` _(deprecated)_
## Features That Can Be Enabled
@@ -317,10 +317,10 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
* `LAYOUTS`
* A list of [layouts](feature_layouts.md) this keyboard supports.
* `LINK_TIME_OPTIMIZATION_ENABLE`
- * Enables Link Time Optimization (`LTO`) when compiling the keyboard. This makes the process take longer, but can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). However, this will automatically disable the old Macros and Functions features automatically, as these break when `LTO` is enabled.
- It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`
+ * Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable).
+However, this will automatically disable the legacy TMK Macros and Functions features, as these break when LTO is enabled. It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`. (Note: This does not affect QMK [Macros](feature_macros.md) and [Layers](feature_layers.md).)
* `LTO_ENABLE`
- * It has the same meaning as LINK_TIME_OPTIMIZATION_ENABLE. You can use `LTO_ENABLE` instead of `LINK_TIME_OPTIMIZATION_ENABLE`.
+ * Has the same meaning as `LINK_TIME_OPTIMIZATION_ENABLE`. You can use `LTO_ENABLE` instead of `LINK_TIME_OPTIMIZATION_ENABLE`.
## AVR MCU Options
* `MCU = atmega32u4`
diff --git a/docs/de/_summary.md b/docs/de/_summary.md
index a894420a2..19c75ecd3 100644
--- a/docs/de/_summary.md
+++ b/docs/de/_summary.md
@@ -98,6 +98,7 @@
* [ISP Flashing Guide](de/isp_flashing_guide.md)
* [ARM Debugging Guide](de/arm_debugging.md)
* [I2C Driver](de/i2c_driver.md)
+ * [SPI Driver](de/spi_driver.md)
* [GPIO Controls](de/internals_gpio_control.md)
* [Proton C Conversion](de/proton_c_conversion.md)
diff --git a/docs/es/_summary.md b/docs/es/_summary.md
index 7dffea7d2..b58d825f7 100644
--- a/docs/es/_summary.md
+++ b/docs/es/_summary.md
@@ -98,6 +98,7 @@
* [Guía de flasheado de ISP](es/isp_flashing_guide.md)
* [Guía de depuración de ARM](es/arm_debugging.md)
* [Driver I2C](es/i2c_driver.md)
+ * [Driver SPI](es/spi_driver.md)
* [Controles GPIO](es/internals_gpio_control.md)
* [Conversión Proton C](es/proton_c_conversion.md)
diff --git a/docs/faq_debug.md b/docs/faq_debug.md
index 6c66defbd..08c84fe4f 100644
--- a/docs/faq_debug.md
+++ b/docs/faq_debug.md
@@ -160,10 +160,3 @@ As of now root of its cause is not clear but some build options seem to be relat
https://github.com/tmk/tmk_keyboard/issues/266
https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778
-
-
-
-## FLIP Doesn't Work
-### `AtLibUsbDfu.dll` Not Found
-Remove current driver and reinstall one FLIP provides from DeviceManager.
-http://imgur.com/a/bnwzy
diff --git a/docs/feature_advanced_keycodes.md b/docs/feature_advanced_keycodes.md
index b2abe5dae..b8664074a 100644
--- a/docs/feature_advanced_keycodes.md
+++ b/docs/feature_advanced_keycodes.md
@@ -6,11 +6,11 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|----------|-------------------------------|----------------------------------------------------|
|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` |
|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` |
-|`LALT(kc)`|`A(kc)` |Hold Left Alt and press `kc` |
+|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` |
|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` |
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
-|`RALT(kc)`|`ALGR(kc)` |Hold Right Alt and press `kc` |
+|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` |
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` |
|`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)` |Hold Left Shift and GUI and press `kc` |
|`LCA(kc)` | |Hold Left Control and Alt and press `kc` |
@@ -18,7 +18,7 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` |
|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc`|
-You can also chain them, for example `LCTL(LALT(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
+You can also chain them, for example `LCTL(LALT(KC_DEL))` or `C(A(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
# Legacy Content :id=legacy-content
diff --git a/docs/feature_debounce_type.md b/docs/feature_debounce_type.md
index b5e5b61bb..65b4ea1e5 100644
--- a/docs/feature_debounce_type.md
+++ b/docs/feature_debounce_type.md
@@ -38,5 +38,6 @@ For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computati
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
* eager_pk - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
* sym_g - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occured, all input changes are pushed.
+* sym_pk - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occured on that key, the key status change is pushed.
diff --git a/docs/feature_macros.md b/docs/feature_macros.md
index 1bd2d74e7..1c7705a51 100644
--- a/docs/feature_macros.md
+++ b/docs/feature_macros.md
@@ -161,11 +161,11 @@ There's also a couple of mod shortcuts you can use:
* `SS_LCTL(string)`
* `SS_LSFT(string)`
-* `SS_LALT(string)`
+* `SS_LALT(string)` or `SS_LOPT(string)`
* `SS_LGUI(string)`, `SS_LCMD(string)` or `SS_LWIN(string)`
* `SS_RCTL(string)`
* `SS_RSFT(string)`
-* `SS_RALT(string)` or `SS_ALGR(string)`
+* `SS_RALT(string)`, `SS_ROPT(string)` or `SS_ALGR(string)`
* `SS_RGUI(string)`, `SS_RCMD(string)` or `SS_RWIN(string)`
These press the respective modifier, send the supplied string and then release the modifier.
diff --git a/docs/feature_ps2_mouse.md b/docs/feature_ps2_mouse.md
index ce072fbe9..c1bd8bff5 100644
--- a/docs/feature_ps2_mouse.md
+++ b/docs/feature_ps2_mouse.md
@@ -266,6 +266,25 @@ To reverse the scroll axes you can put:
into config.h.
+### Rotate Mouse Axes :id=rotate-mouse-axes
+
+Transform the output of the device with a clockwise rotation of 90, 180, or 270
+degrees.
+
+When compensating for device orientation, rotate the output the same amount in
+the opposite direction. E.g. if the normal device orientation is considered to
+be North-facing, compensate as follows:
+
+```c
+#define PS2_MOUSE_ROTATE 270 /* Compensate for East-facing device orientation. */
+```
+```c
+#define PS2_MOUSE_ROTATE 180 /* Compensate for South-facing device orientation. */
+```
+```c
+#define PS2_MOUSE_ROTATE 90 /* Compensate for West-facing device orientation. */
+```
+
### Debug Settings :id=debug-settings
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
diff --git a/docs/flashing.md b/docs/flashing.md
index ab003308d..1f71c253c 100644
--- a/docs/flashing.md
+++ b/docs/flashing.md
@@ -26,7 +26,6 @@ Compatible flashers:
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI)
* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` in QMK (recommended command line)
-* [Atmel's Flip](http://www.microchip.com/developmenttools/productdetails.aspx?partno=flip) (not recommended)
Flashing sequence:
diff --git a/docs/fr-fr/_summary.md b/docs/fr-fr/_summary.md
index bb14d2f0a..25a593b2e 100644
--- a/docs/fr-fr/_summary.md
+++ b/docs/fr-fr/_summary.md
@@ -101,7 +101,8 @@
* [Guide des claviers soudés à la main](fr-fr/hand_wire.md)
* [Guide de flash de l’ISP](fr-fr/isp_flashing_guide.md)
* [Guide du débogage ARM](fr-fr/arm_debugging.md)
- * [Drivers i2c](fr-fr/i2c_driver.md)
+ * [Drivers I2C](fr-fr/i2c_driver.md)
+ * [Drivers SPI](fr-fr/spi_driver.md)
* [Contrôles des GPIO](fr-fr/internals_gpio_control.md)
* [Conversion en Proton C](fr-fr/proton_c_conversion.md)
diff --git a/docs/fr-fr/faq_debug.md b/docs/fr-fr/faq_debug.md
index 754c79921..9c12f2917 100644
--- a/docs/fr-fr/faq_debug.md
+++ b/docs/fr-fr/faq_debug.md
@@ -155,11 +155,3 @@ Pour le moment, l'origine du problème n'est pas comprise, mais certaines option
https://github.com/tmk/tmk_keyboard/issues/266
https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778
-
-## FLIP ne marche pas
-
-### `AtLibUsbDfu.dll` Not Found
-
-Supprimez le pilote actuel et réinstallez celui donné par FLIP dans le gestionnaire de périphériques.
-
-http://imgur.com/a/bnwzy
diff --git a/docs/fr-fr/flashing.md b/docs/fr-fr/flashing.md
index c380614a5..74eae4977 100644
--- a/docs/fr-fr/flashing.md
+++ b/docs/fr-fr/flashing.md
@@ -26,7 +26,6 @@ Méthodes de flash compatibles :
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (interface graphique recommandé)
* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` avec QMK (outil en ligne de commande recommandé)
-* [Atmel's Flip](http://www.microchip.com/developmenttools/productdetails.aspx?partno=flip) (non recommandé)
Ordre des actions :
diff --git a/docs/getting_started_vagrant.md b/docs/getting_started_vagrant.md
index da26682d7..7a4541cfc 100644
--- a/docs/getting_started_vagrant.md
+++ b/docs/getting_started_vagrant.md
@@ -20,7 +20,6 @@ The "easy" way to flash the firmware is using a tool from your host OS:
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox) (recommended)
* [Teensy Loader](https://www.pjrc.com/teensy/loader.html)
-* [Atmel FLIP](http://www.atmel.com/tools/flip.aspx)
If you want to program via the command line you can uncomment the ['modifyvm'] lines in the Vagrantfile to enable the USB passthrough into Linux and then program using the command line tools like dfu-util/dfu-programmer or you can install the Teensy CLI version.
diff --git a/docs/he-il/_summary.md b/docs/he-il/_summary.md
index 21059f997..bdacd0d1f 100644
--- a/docs/he-il/_summary.md
+++ b/docs/he-il/_summary.md
@@ -114,6 +114,7 @@
* [מדריך לצריבת ISP](he-il/isp_flashing_guide.md)
* [מדריך לדיבאגינג ARM](he-il/arm_debugging.md)
* [מנהל התקן I2C](he-il/i2c_driver.md)
+ * [מנהל התקן SPI](he-il/spi_driver.md)
* [בקרת GPIO](he-il/internals_gpio_control.md)
* [המרת Proton C](he-il/proton_c_conversion.md)
diff --git a/docs/ja/_summary.md b/docs/ja/_summary.md
index 10279471a..e6423c6c2 100644
--- a/docs/ja/_summary.md
+++ b/docs/ja/_summary.md
@@ -121,6 +121,7 @@
* [ドライバ](ja/hardware_drivers.md)
* [ADC ドライバ](ja/adc_driver.md)
* [I2C ドライバ](ja/i2c_driver.md)
+ * [SPI ドライバ](ja/spi_driver.md)
* [WS2812 ドライバ](ja/ws2812_driver.md)
* [EEPROM ドライバ](ja/eeprom_driver.md)
* [GPIO コントロール](ja/internals_gpio_control.md)
diff --git a/docs/ja/faq_debug.md b/docs/ja/faq_debug.md
index 8e42aebbb..856e9473a 100644
--- a/docs/ja/faq_debug.md
+++ b/docs/ja/faq_debug.md
@@ -152,10 +152,3 @@ https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034
https://github.com/tmk/tmk_keyboard/issues/266
https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778
-
-
-
-## FLIP が動作しない
-### `AtLibUsbDfu.dll` が見つかりません
-デバイスマネージャから現在のドライバを削除し、FLIP が提供するものを再インストールします。
-http://imgur.com/a/bnwzy
diff --git a/docs/ja/feature_advanced_keycodes.md b/docs/ja/feature_advanced_keycodes.md
index d208d7f92..c6e21feb9 100644
--- a/docs/ja/feature_advanced_keycodes.md
+++ b/docs/ja/feature_advanced_keycodes.md
@@ -54,11 +54,11 @@ QMK を使い始めたばかりの場合は、全てを単純にしたいでし
|----------|-------------------------------|----------------------------------------------------|
| `LCTL(kc)` | `C(kc)` | 左 Control を押しながら `kc` を押します。 |
| `LSFT(kc)` | `S(kc)` | 左 Shift を押しながら `kc` を押します。 |
-| `LALT(kc)` | `A(kc)` | 左 Alt を押しながら `kc`を押します。 |
+| `LALT(kc)` | `A(kc)`, `LOPT(kc)` | 左 Alt を押しながら `kc`を押します。 |
| `LGUI(kc)` | `G(kc)`, `LCMD(kc)`, `LWIN(kc)` | 左 GUI を押しながら `kc` を押します。 |
| `RCTL(kc)` | | 右 Control を押しながら `kc` を押します。 |
| `RSFT(kc)` | | 右 Shift を押しながら `kc` を押します。 |
-| `RALT(kc)` | `ALGR(kc)` | 右 Alt を押しながら `kc` を押します。 |
+| `RALT(kc)` | `ROPT(kc)`, `ALGR(kc)` | 右 Alt を押しながら `kc` を押します。 |
| `RGUI(kc)` | `RCMD(kc)`, `LWIN(kc)` | 右 GUI を押しながら `kc` を押します。 |
| `SGUI(kc)` | `SCMD(kc)`, `SWIN(kc)` | 左 Shift と左 GUI を押しながら `kc` を押します。 |
| `LCA(kc)` | | 左 Control と左 Alt を押しながら `kc` を押します。 |
diff --git a/docs/ja/feature_combo.md b/docs/ja/feature_combo.md
new file mode 100644
index 000000000..4fbd6847d
--- /dev/null
+++ b/docs/ja/feature_combo.md
@@ -0,0 +1,108 @@
+# コンボ
+
+<!---
+ original document: 0.8.94:docs/feature_combo.md
+ git diff 0.8.94 HEAD -- docs/feature_combo.md | cat
+-->
+
+コンボ機能は、同時押し方式でのカスタムアクション追加機能です。同時に複数のキーを押して、異なる効果を生み出すことができます。例えば、タッピング時間内で `A` と `S` を押すと、代わりに `ESC` が押されます。もっと複雑なタスクを実行させることもできます。
+
+この機能を有効にするには、`rules.mk` に `COMBO_ENABLE = yes` を追加する必要があります。
+
+さらに、使用するコンボの数を `config.h` の中で、`#define COMBO_COUNT 1` (1を使用するコンボの数で置き換えます)と書いて、指定する必要があります。
+<!-- At this time, this is necessary -->
+
+また、デフォルトでは、コンボのタッピング時間は `TAPPING_TERM` と同じ値に設定されます (ほとんどのキーボードではデフォルトで 200)。ただし、`config.h` で定義することにより異なる値を指定することができます。例えば: `#define COMBO_TERM 300` はコンボのためのタイムアウト時間を 300ms に設定します。
+
+次に、`keymap.c` ファイルに、`COMBO_END` で終了するキーのシーケンス、およびキーの組み合わせを列挙する構造体、その結果のアクションを定義する必要があります。
+
+```c
+const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END};
+combo_t key_combos[COMBO_COUNT] = {COMBO(test_combo, KC_ESC)};
+```
+
+これは、A と B のキーを押した場合に、"Escape" を送信します。
+
+!> このメソッドは[基本的なキーコード](ja/keycodes_basic.md)のみをサポートします。詳細な制御については例を見てください。
+
+## 例
+
+リストを追加したい場合は、以下のようなものを使います:
+
+```c
+enum combos {
+ AB_ESC,
+ JK_TAB
+};
+
+const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END};
+const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+ [AB_ESC] = COMBO(ab_combo, KC_ESC),
+ [JK_TAB] = COMBO(jk_combo, KC_TAB)
+};
+```
+
+より複雑な実装として、カスタム処理を追加するために `process_combo_event` 関数を使うことができます。
+
+```c
+enum combo_events {
+ ZC_COPY,
+ XV_PASTE
+};
+
+const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END};
+const uint16_t PROGMEM paste_combo[] = {KC_X, KC_V, COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+ [ZC_COPY] = COMBO_ACTION(copy_combo),
+ [XV_PASTE] = COMBO_ACTION(paste_combo),
+};
+
+void process_combo_event(uint8_t combo_index, bool pressed) {
+ switch(combo_index) {
+ case ZC_COPY:
+ if (pressed) {
+ tap_code16(LCTL(KC_C));
+ }
+ break;
+ case XV_PASTE:
+ if (pressed) {
+ tap_code16(LCTL(KC_V));
+ }
+ break;
+ }
+}
+```
+
+これは、Z と C を押すと Ctrl+C を送信し、X と V を押すと Ctrl+V を送信します。これを変更して、レイヤーの変更、サウンドの再生、設定の変更などを行うこともできます。
+
+## 追加の設定
+
+長いコンボあるいはさらに長いコンボを使っている場合、構造体があなたのしていることに対応するのに十分な大きさで無いかもしれないため、問題が発生するかもしれません。
+
+この場合、`config.h` ファイルに `#define EXTRA_LONG_COMBOS` または `#define EXTRA_EXTRA_LONG_COMBOS` のどちらかを追加することができます。
+
+`COMBO_ALLOW_ACTION_KEYS` を定義することでアクションキーを有効にすることもできます。
+
+## キーコード
+
+その場でコンボ機能を有効、無効および切り替えすることができます。ゲームなどで、一時的にそれらを無効にする必要がある場合に便利です。
+
+| キーコード | 説明 |
+|----------|---------------------------------|
+| `CMB_ON` | コンボ機能をオンにします |
+| `CMB_OFF` | コンボ機能をオフにします |
+| `CMB_TOG` | コンボ機能のオンとオフを切り替えます |
+
+## ユーザコールバック
+
+キーコードに加えて、状態を設定または状態をチェックするために使うことができる幾つかの関数があります:
+
+| 関数 | 説明 |
+|-----------|--------------------------------------------------------------------|
+| `combo_enable()` | コンボ機能を有効にします |
+| `combo_disable()` | コンボ機能を無効にし、コンボバッファをクリアします |
+| `combo_toggle()` | コンボ機能の状態を切り替えます |
+| `is_combo_enabled()` | コンボ機能の状態(true か false)を返します |
diff --git a/docs/ja/feature_dip_switch.md b/docs/ja/feature_dip_switch.md
new file mode 100644
index 000000000..1403485ca
--- /dev/null
+++ b/docs/ja/feature_dip_switch.md
@@ -0,0 +1,95 @@
+# DIP スイッチ
+
+<!---
+ original document: 0.8.94:docs/feature_dip_switch.md
+ git diff 0.8.94 HEAD -- docs/feature_dip_switch.md | cat
+-->
+
+DIP スイッチは、以下を `rules.mk` に追加することでサポートされます:
+
+ DIP_SWITCH_ENABLE = yes
+
+さらに、以下を `config.h` に追加します:
+
+```c
+#define DIP_SWITCH_PINS { B14, A15, A10, B9 }
+```
+
+## コールバック
+
+コールバック関数を `<keyboard>.c` に記述することができます:
+
+```c
+void dip_switch_update_kb(uint8_t index, bool active) {
+ dip_switch_update_user(index, active);
+}
+```
+
+
+あるいは `keymap.c` に記述することもできます:
+
+```c
+void dip_switch_update_user(uint8_t index, bool active) {
+ switch (index) {
+ case 0:
+ if(active) { audio_on(); } else { audio_off(); }
+ break;
+ case 1:
+ if(active) { clicky_on(); } else { clicky_off(); }
+ break;
+ case 2:
+ if(active) { music_on(); } else { music_off(); }
+ break;
+ case 3:
+ if (active) {
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(plover_song);
+ #endif
+ layer_on(_PLOVER);
+ } else {
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(plover_gb_song);
+ #endif
+ layer_off(_PLOVER);
+ }
+ break;
+ }
+}
+```
+
+更に、より複雑な処理ができるビットマスク関数をサポートします。
+
+
+```c
+void dip_switch_update_mask_kb(uint32_t state) {
+ dip_switch_update_mask_user(state);
+}
+```
+
+
+あるいは `keymap.c` に記述することもできます:
+
+```c
+void dip_switch_update_mask_user(uint32_t state) {
+ if (state & (1UL<<0) && state & (1UL<<1)) {
+ layer_on(_ADJUST); // C on esc
+ } else {
+ layer_off(_ADJUST);
+ }
+ if (state & (1UL<<0)) {
+ layer_on(_TEST_A); // A on ESC
+ } else {
+ layer_off(_TEST_A);
+ }
+ if (state & (1UL<<1)) {
+ layer_on(_TEST_B); // B on esc
+ } else {
+ layer_off(_TEST_B);
+ }
+}
+```
+
+
+## ハードウェア
+
+DIP スイッチの片側は MCU のピンへ直接配線し、もう一方の側はグラウンドに配線する必要があります。機能的に同じであるため、どちら側がどちらに接続されているかは問題にはならないはずです。
diff --git a/docs/ja/flashing.md b/docs/ja/flashing.md
index 62baa907d..713d4fdf9 100644
--- a/docs/ja/flashing.md
+++ b/docs/ja/flashing.md
@@ -31,7 +31,6 @@ BOOTLOADER = atmel-dfu
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI)
* QMK の [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` (推奨のコマンドライン)
-* [Atmel の Flip](http://www.microchip.com/developmenttools/productdetails.aspx?partno=flip) (非推奨)
書き込み手順:
diff --git a/docs/ja/getting_started_vagrant.md b/docs/ja/getting_started_vagrant.md
index 0bc5c4b79..66fb89510 100644
--- a/docs/ja/getting_started_vagrant.md
+++ b/docs/ja/getting_started_vagrant.md
@@ -25,7 +25,6 @@ Vagrant 以外に、適切なプロバイダがインストールされ、その
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox) (推奨)
* [Teensy ローダー](https://www.pjrc.com/teensy/loader.html)
-* [Atmel FLIP](http://www.atmel.com/tools/flip.aspx)
コマンドラインでプログラムしたい場合は、Vagranfile の ['modifyvm'] 行のコメントを解除して Linux への USB パススルーを有効にし、dfu-util/dfu-programmer のようなコマンドラインツールを使ってプログラムすることができます。あるいは Teensy CLI バージョンをインストールすることができます。
diff --git a/docs/keycodes.md b/docs/keycodes.md
index 1a388f106..18fd81118 100644
--- a/docs/keycodes.md
+++ b/docs/keycodes.md
@@ -175,11 +175,11 @@ See also: [Basic Keycodes](keycodes_basic.md)
|`KC_EXSEL` | |ExSel |
|`KC_LCTRL` |`KC_LCTL` |Left Control |
|`KC_LSHIFT` |`KC_LSFT` |Left Shift |
-|`KC_LALT` | |Left Alt |
+|`KC_LALT` |`KC_LOPT` |Left Alt (Option) |
|`KC_LGUI` |`KC_LCMD`, `KC_LWIN` |Left GUI (Windows/Command/Meta key) |
|`KC_RCTRL` |`KC_RCTL` |Right Control |
|`KC_RSHIFT` |`KC_RSFT` |Right Shift |
-|`KC_RALT` |`KC_ALGR` |Right Alt (AltGr) |
+|`KC_RALT` |`KC_ROPT`, `KC_ALGR` |Right Alt (Option/AltGr) |
|`KC_RGUI` |`KC_RCMD`, `KC_RWIN` |Right GUI (Windows/Command/Meta key) |
|`KC_SYSTEM_POWER` |`KC_PWR` |System Power Down |
|`KC_SYSTEM_SLEEP` |`KC_SLEP` |System Sleep |
@@ -378,11 +378,11 @@ See also: [Modifier Keys](feature_advanced_keycodes.md#modifier-keys)
|----------|-------------------------------|----------------------------------------------------|
|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` |
|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` |
-|`LALT(kc)`|`A(kc)` |Hold Left Alt and press `kc` |
+|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` |
|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` |
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
-|`RALT(kc)`|`ALGR(kc)` |Hold Right Alt and press `kc` |
+|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` |
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` |
|`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)` |Hold Left Shift and GUI and press `kc` |
|`LCA(kc)` | |Hold Left Control and Alt and press `kc` |
@@ -401,11 +401,11 @@ See also: [Mod-Tap](mod_tap.md)
|`MT(mod, kc)`| |`mod` when held, `kc` when tapped |
|`LCTL_T(kc)` |`CTL_T(kc)` |Left Control when held, `kc` when tapped |
|`LSFT_T(kc)` |`SFT_T(kc)` |Left Shift when held, `kc` when tapped |
-|`LALT_T(kc)` |`ALT_T(kc)` |Left Alt when held, `kc` when tapped |
+|`LALT_T(kc)` |`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |Left Alt when held, `kc` when tapped |
|`LGUI_T(kc)` |`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped |
|`RCTL_T(kc)` | |Right Control when held, `kc` when tapped |
|`RSFT_T(kc)` | |Right Shift when held, `kc` when tapped |
-|`RALT_T(kc)` |`ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
+|`RALT_T(kc)` |`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
|`RGUI_T(kc)` |`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped |
|`SGUI_T(kc)` |`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped |
diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md
index 75d58c1f1..09efc8c9c 100644
--- a/docs/keycodes_basic.md
+++ b/docs/keycodes_basic.md
@@ -112,11 +112,11 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07
|-----------|--------------------|------------------------------------|
|`KC_LCTRL` |`KC_LCTL` |Left Control |
|`KC_LSHIFT`|`KC_LSFT` |Left Shift |
-|`KC_LALT` | |Left Alt |
+|`KC_LALT` |`KC_LOPT` |Left Alt (Option) |
|`KC_LGUI` |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) |
|`KC_RCTRL` |`KC_RCTL` |Right Control |
|`KC_RSHIFT`|`KC_RSFT` |Right Shift |
-|`KC_RALT` |`KC_ALGR` |Right Alt (AltGr) |
+|`KC_RALT` |`KC_ROPT`, `KC_ALGR`|Right Alt (Option/AltGr) |
|`KC_RGUI` |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)|
## International
diff --git a/docs/mod_tap.md b/docs/mod_tap.md
index 2b86701ca..ced0beba9 100644
--- a/docs/mod_tap.md
+++ b/docs/mod_tap.md
@@ -31,11 +31,11 @@ For convenience, QMK includes some Mod-Tap shortcuts to make common combinations
|------------|-----------------------------------------------------------------|-------------------------------------------------------|
|`LCTL_T(kc)`|`CTL_T(kc)` |Left Control when held, `kc` when tapped |
|`LSFT_T(kc)`|`SFT_T(kc)` |Left Shift when held, `kc` when tapped |
-|`LALT_T(kc)`|`ALT_T(kc)` |Left Alt when held, `kc` when tapped |
+|`LALT_T(kc)`|`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |Left Alt when held, `kc` when tapped |
|`LGUI_T(kc)`|`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped |
|`RCTL_T(kc)`| |Right Control when held, `kc` when tapped |
|`RSFT_T(kc)`| |Right Shift when held, `kc` when tapped |
-|`RALT_T(kc)`|`ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
+|`RALT_T(kc)`|`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped |
|`SGUI_T(kc)`|`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped |
diff --git a/docs/newbs_getting_started.md b/docs/newbs_getting_started.md
index 8ffbb9117..c8916b0e2 100644
--- a/docs/newbs_getting_started.md
+++ b/docs/newbs_getting_started.md
@@ -78,7 +78,7 @@ After installing QMK you can set it up with this command:
In most situations you will want to answer Yes to all of the prompts.
-?> If you already know [how to use GitHub](getting_started_github.md), we recommend that you create your own fork and use `qmk setup <github_username>` to clone your personal fork. If you don't know what that means you can safely ignore this message.
+?> If you already know [how to use GitHub](getting_started_github.md), we recommend that you create your own fork and use `qmk setup <github_username>/qmk_firmware` to clone your personal fork. If you don't know what that means you can safely ignore this message.
## 4. Test Your Build Environment
diff --git a/docs/platformdev_chibios_earlyinit.md b/docs/platformdev_chibios_earlyinit.md
new file mode 100644
index 000000000..699c22377
--- /dev/null
+++ b/docs/platformdev_chibios_earlyinit.md
@@ -0,0 +1,53 @@
+# Arm/ChibiOS Early Initialization :id=chibios-early-init
+
+This page describes a part of QMK that is a somewhat advanced concept, and is only relevant to keyboard designers.
+
+QMK uses ChibiOS as the underlying layer to support a multitude of Arm-based devices. Each ChibiOS-supported keyboard has a low-level board definition which is responsible for initializing hardware peripherals such as the clocks, and GPIOs.
+
+Older QMK revisions required duplication of these board definitions inside your keyboard's directory in order to override such early initialization points; this is now abstracted into the following APIs, and allows usage of the board definitions supplied with ChibiOS itself. Check `<qmk_firmware>/lib/chibios/os/hal/boards` for the list of official definitions. If your keyboard needs extra initialization at a very early stage, consider providing keyboard-level overrides of the following APIs:
+
+## `early_hardware_init_pre()` :id=early-hardware-init-pre
+
+The function `early_hardware_init_pre` is the earliest possible code that can be executed by a keyboard firmware. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the start of the function.
+
+This is executed before RAM gets cleared, and before clocks or GPIOs are configured; any delays or preparation using GPIOs is not likely to work at this point. After executing this function, RAM on the MCU may be zero'ed. Assigning values to variables during execution of this function may be overwritten.
+
+As such, if you wish to override this API consider limiting use to writing to low-level registers. The default implementation of this function can be configured to jump to bootloader if a `RESET` key was pressed, by ensuring `#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE` is in the keyboard's `config.h` file.
+
+To implement your own version of this function, in your keyboard's source files:
+
+```c
+void early_hardware_init_pre(void) {
+ // do things with registers
+}
+```
+
+## `early_hardware_init_post()` :id=early-hardware-init-post
+
+The function `early_hardware_init_post` is the next earliest possible code that can be executed by a keyboard firmware. This is executed after RAM has been cleared, and clocks and GPIOs are configured. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the end of the function.
+
+Much like `early_hardware_init_pre`, ChibiOS has not yet been initialized either, so the same restrictions on delays and timing apply.
+
+If you wish to override this API, consider limiting functionality to register writes, variable initialization, and GPIO toggling. The default implementation of this function is to do nothing.
+
+To implement your own version of this function, in your keyboard's source files:
+
+```c
+void early_hardware_init_post(void) {
+ // toggle GPIO pins and write to variables
+}
+```
+
+## `board_init()` :id=board-init
+
+The function `board_init` is executed directly after the ChibiOS initialization routines have completed. At this stage, all normal low-level functionality should be available for use (including timers and delays), with the restriction that USB is not yet connected. This is intended as a replacement for the ChibiOS board definition's `boardInit` function.
+
+The default implementation of this function is to do nothing.
+
+To implement your own version of this function, in your keyboard's source files:
+
+```c
+void board_init(void) {
+ // initialize anything that requires ChibiOS
+}
+``` \ No newline at end of file
diff --git a/docs/proton_c_conversion.md b/docs/proton_c_conversion.md
index dc0a3f484..98f1508a9 100644
--- a/docs/proton_c_conversion.md
+++ b/docs/proton_c_conversion.md
@@ -1,5 +1,9 @@
# Converting a board to use the Proton C
+Since the Proton C is a drop-in replacement for a Pro Micro we've made it easy to use. This page documents a handy automated process for converting keyboards, as well as documenting the manual process if you'd like to make use of Proton C features that aren't available on Pro Micros.
+
+## Automatic Conversion
+
If a board currently supported in QMK uses a Pro Micro (or compatible board) and you want to use the Proton C, you can generate the firmware by appending `CONVERT_TO_PROTON_C=yes` (or `CTPC=yes`) to your make argument, like this:
make 40percentclub/mf68:default CTPC=yes
@@ -8,13 +12,15 @@ You can add the same argument to your keymap's `rules.mk`, which will accomplish
This exposes the `CONVERT_TO_PROTON_C` flag that you can use in your code with `#ifdef`s, like this:
- #ifdef CONVERT_TO_PROTON_C
- // Proton C code
- #else
- // Pro Micro code
- #endif
+```c
+#ifdef CONVERT_TO_PROTON_C
+ // Proton C code
+#else
+ // Pro Micro code
+#endif
+```
-Before being able to compile, you may get some errors about `PORTB/DDRB`, etc not being defined, so you'll need to convert the keyboard's code to use the [GPIO Controls](internals_gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
+If you get errors about `PORTB/DDRB`, etc not being defined, so you'll need to convert the keyboard's code to use the [GPIO Controls](internals_gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all.
The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this like to your `config.h`:
@@ -31,3 +37,54 @@ These are defaults based on what has been implemented for ARM boards.
| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration |
| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) |
| [Split keyboards](feature_split_keyboard.md) | Not supported yet |
+
+## Manual Conversion
+
+To use the Proton C natively, without having to specify `CTPC=yes`, you need to change the `MCU` line in `rules.mk`:
+
+```
+MCU = STM32F303
+```
+
+Remove these variables if they exist:
+
+* `BOOTLOADER`
+* `EXTRA_FLAGS`
+
+Finally convert all pin assignments in `config.h` to the stm32 equivalents.
+
+| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right |
+|-----------|----------|-|----------|-----------|
+| `D3` | `A9` | | 5v | RAW (5v) |
+| `D2` | `A10` | | GND | GND |
+| GND | GND | | FLASH | RESET |
+| GND | GND | | 3.3v | VCC <sup>1</sup> |
+| `D1` | `B7` | | `A2` | `F4` |
+| `D0` | `B6` | | `A1` | `F5` |
+| `D4` | `B5` | | `A0` | `F6` |
+| `C6` | `B4` | | `B8` | `F7` |
+| `D7` | `B3` | | `B13` | `B1` |
+| `E6` | `B2` | | `B14` | `B3` |
+| `B4` | `B1` | | `B15` | `B2` |
+| `B5` | `B0` | | `B9` | `B6` |
+| `B0` (RX LED) | `C13` <sup>2</sup> | | `C13` <sup>2</sup> | `D5` (TX LED) |
+
+You can also make use of several new pins on the extended portion of the Proton C:
+
+| Left | | Right |
+|------|-|-------|
+| `A4`<sup>3</sup> | | `B10` |
+| `A5`<sup>4</sup> | | `B11` |
+| `A6` | | `B12` |
+| `A7` | | `A14`<sup>5</sup> (SWCLK) |
+| `A8` | | `A13`<sup>5</sup> (SWDIO) |
+| `A15` | | RESET<sup>6</sup> |
+
+Notes:
+
+1. On a Pro Micro VCC can be 3.3v or 5v.
+2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`.
+3. `A4` is shared with the speaker.
+4. `A5` is shared with the speaker.
+5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last.
+6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU.
diff --git a/docs/pt-br/_summary.md b/docs/pt-br/_summary.md
index 9c29c5a3a..78b3b2021 100644
--- a/docs/pt-br/_summary.md
+++ b/docs/pt-br/_summary.md
@@ -98,6 +98,7 @@
* [ISP Flashing Guide](pt-br/isp_flashing_guide.md)
* [ARM Debugging Guide](pt-br/arm_debugging.md)
* [I2C Driver](pt-br/i2c_driver.md)
+ * [SPI Driver](pt-br/spi_driver.md)
* [GPIO Controls](pt-br/internals_gpio_control.md)
* [Proton C Conversion](pt-br/proton_c_conversion.md)
diff --git a/docs/ref_functions.md b/docs/ref_functions.md
index 708b0be28..57f701d79 100644
--- a/docs/ref_functions.md
+++ b/docs/ref_functions.md
@@ -8,7 +8,7 @@ There are actually separate functions that you can use there, depending on what
### `update_tri_layer(x, y, z)`
-The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it runs on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it runs off layer `z`.
+The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it turns on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it turns off layer `z`.
This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.
@@ -43,7 +43,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
```
### `update_tri_layer_state(state, x, y, z)`
-The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from they [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
+The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from the [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
The caveat to this method is that you cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it.
diff --git a/docs/reference_glossary.md b/docs/reference_glossary.md
index 08a22050c..4cdba024e 100644
--- a/docs/reference_glossary.md
+++ b/docs/reference_glossary.md
@@ -46,9 +46,6 @@ An IDE that is popular with many C developers.
## Firmware
The software that controls your MCU.
-## FLIP
-Software provided by Atmel for flashing AVR devices. We generally recommend [QMK Flasher](https://github.com/qmk/qmk_flasher) instead, but for some advanced use cases FLIP is required.
-
## git
Versioning software used at the command line
diff --git a/docs/ru-ru/_summary.md b/docs/ru-ru/_summary.md
index caa7cdd56..f893be3cf 100644
--- a/docs/ru-ru/_summary.md
+++ b/docs/ru-ru/_summary.md
@@ -99,6 +99,7 @@
* [ISP Flashing Guide](ru-ru/isp_flashing_guide.md)
* [ARM Debugging Guide](ru-ru/arm_debugging.md)
* [I2C Driver](ru-ru/i2c_driver.md)
+ * [SPI Driver](ru-ru/spi_driver.md)
* [WS2812 Driver](ru-ru/ws2812_driver.md)
* [GPIO Controls](ru-ru/internals_gpio_control.md)
* [Proton C Conversion](ru-ru/proton_c_conversion.md)
diff --git a/docs/spi_driver.md b/docs/spi_driver.md
new file mode 100644
index 000000000..e2b5b140b
--- /dev/null
+++ b/docs/spi_driver.md
@@ -0,0 +1,121 @@
+# SPI Master Driver
+
+The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs.
+
+## AVR Configuration
+
+No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU:
+
+|MCU |`SS`|`SCK`|`MOSI`|`MISO`|
+|---------------|----|-----|------|------|
+|ATMega16/32U2/4|`B0`|`B1` |`B2` |`B3` |
+|AT90USB64/128 |`B0`|`B1` |`B2` |`B3` |
+|ATmega32A |`B4`|`B7` |`B5` |`B6` |
+|ATmega328P |`B2`|`B5` |`B3` |`B4` |
+
+You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually.
+`SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`.
+
+## ChibiOS/ARM Configuration
+
+ARM support for this driver is not ready yet. Check back later!
+
+## Functions
+
+### `void spi_init(void)`
+
+Initialize the SPI driver. This function must be called only once, before any of the below functions can be called.
+
+---
+
+### `bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)`
+
+Start an SPI transaction.
+
+#### Arguments
+
+ - `pin_t slavePin`
+ The QMK pin to assert as the slave select pin, eg. `B4`.
+ - `bool lsbFirst`
+ Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first.
+ - `uint8_t mode`
+ The SPI mode to use:
+
+ |Mode|Clock Polarity |Clock Phase |
+ |----|--------------------|-----------------------|
+ |`0` |Leading edge rising |Sample on leading edge |
+ |`1` |Leading edge rising |Sample on trailing edge|
+ |`2` |Leading edge falling|Sample on leading edge |
+ |`3` |Leading edge falling|Sample on trailing edge|
+
+ - `uint16_t divisor`
+ The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`.
+
+#### Return Value
+
+`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`.
+
+---
+
+### `spi_status_t spi_write(uint8_t data)`
+
+Write a byte to the selected SPI device.
+
+#### Arguments
+
+ - `uint8_t data`
+ The byte to write.
+
+#### Return Value
+
+`SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`.
+
+---
+
+### `spi_status_t spi_read(void)`
+
+Read a byte from the selected SPI device.
+
+#### Return Value
+
+`SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device.
+
+---
+
+### `spi_status_t spi_transmit(const uint8_t *data, uint16_t length)`
+
+Send multiple bytes to the selected SPI device.
+
+#### Arguments
+
+ - `const uint8_t *data`
+ A pointer to the data to write from.
+ - `uint16_t length`
+ The number of bytes to write. Take care not to overrun the length of `data`.
+
+#### Return Value
+
+`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise.
+
+---
+
+### `spi_status_t spi_receive(uint8_t *data, uint16_t length)`
+
+Receive multiple bytes from the selected SPI device.
+
+#### Arguments
+
+ - `uint8_t *data`
+ A pointer to the buffer to read into.
+ - `uint16_t length`
+ The number of bytes to read. Take care not to overrun the length of `data`.
+
+#### Return Value
+
+`SPI_STATUS_TIMEOUT` if the internal transmission timeout period elapses, `SPI_STATUS_SUCCESS` on success, or `SPI_STATUS_ERROR` otherwise.
+
+---
+
+### `void spi_stop(void)`
+
+End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`.
diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md
index 12bd07a21..201b83894 100644
--- a/docs/zh-cn/_summary.md
+++ b/docs/zh-cn/_summary.md
@@ -104,6 +104,7 @@
* [ARM调试指南](zh-cn/arm_debugging.md)
* [ADC设备](zh-cn/adc_driver.md)
* [I2C设备](zh-cn/i2c_driver.md)
+ * [SPI设备](zh-cn/spi_driver.md)
* [WS2812设备](zh-cn/ws2812_driver.md)
* [EEPROM设备](zh-cn/eeprom_driver.md)
* [GPIO控制](zh-cn/internals_gpio_control.md)
diff --git a/docs/zh-cn/faq_debug.md b/docs/zh-cn/faq_debug.md
index 7eff7f265..71b575ea0 100644
--- a/docs/zh-cn/faq_debug.md
+++ b/docs/zh-cn/faq_debug.md
@@ -139,10 +139,3 @@ https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034
https://github.com/tmk/tmk_keyboard/issues/266
https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778
-
-
-
-## FLIP 不工作
-### `AtLibUsbDfu.dll` 未找到
-从设备管理器中删除当前驱动程序并在设备管理器重新安装一个FLIP提供的程序。
-http://imgur.com/a/bnwzy
diff --git a/docs/zh-cn/reference_glossary.md b/docs/zh-cn/reference_glossary.md
index 7b9adcc2a..0e0521221 100644
--- a/docs/zh-cn/reference_glossary.md
+++ b/docs/zh-cn/reference_glossary.md
@@ -46,9 +46,6 @@ Français (法国)标准键盘布局。用键盘的前六个字母命名。
## Firmware(固件)
用来控制单片机的软件。
-## FLIP
-爱特梅尔(Atmel)提供的AVR器件刷写软件。我们一般推荐 [QMK刷写工具](https://github.com/qmk/qmk_flasher),但是对于一些高级用例,需要FLIP。
-
## git
命令行版本控制软件
diff --git a/drivers/avr/spi_master.c b/drivers/avr/spi_master.c
new file mode 100644
index 000000000..32cc55c83
--- /dev/null
+++ b/drivers/avr/spi_master.c
@@ -0,0 +1,176 @@
+/* Copyright 2020
+ *
+ * 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 3 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include <avr/io.h>
+
+#include "spi_master.h"
+#include "quantum.h"
+#include "timer.h"
+
+#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
+# define SPI_SCK_PIN B1
+# define SPI_MOSI_PIN B2
+# define SPI_MISO_PIN B3
+#elif defined(__AVR_ATmega32A__)
+# define SPI_SCK_PIN B7
+# define SPI_MOSI_PIN B5
+# define SPI_MISO_PIN B6
+#elif defined(__AVR_ATmega328P__)
+# define SPI_SCK_PIN B5
+# define SPI_MOSI_PIN B3
+# define SPI_MISO_PIN B4
+#endif
+
+#ifndef SPI_TIMEOUT
+# define SPI_TIMEOUT 100
+#endif
+
+static pin_t currentSlavePin = NO_PIN;
+static uint8_t currentSlaveConfig = 0;
+static bool currentSlave2X = false;
+
+void spi_init(void) {
+ writePinHigh(SPI_SS_PIN);
+ setPinOutput(SPI_SCK_PIN);
+ setPinOutput(SPI_MOSI_PIN);
+ setPinInput(SPI_MISO_PIN);
+
+ SPCR = (_BV(SPE) | _BV(MSTR));
+}
+
+bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
+ if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
+ return false;
+ }
+
+ currentSlaveConfig = 0;
+
+ if (lsbFirst) {
+ currentSlaveConfig |= _BV(DORD);
+ }
+
+ switch (mode) {
+ case 1:
+ currentSlaveConfig |= _BV(CPHA);
+ break;
+ case 2:
+ currentSlaveConfig |= _BV(CPOL);
+ break;
+ case 3:
+ currentSlaveConfig |= (_BV(CPOL) | _BV(CPHA));
+ break;
+ }
+
+ uint16_t roundedDivisor = 1;
+ while (roundedDivisor < divisor) {
+ roundedDivisor <<= 1;
+ }
+
+ switch (roundedDivisor) {
+ case 16:
+ currentSlaveConfig |= _BV(SPR0);
+ break;
+ case 64:
+ currentSlaveConfig |= _BV(SPR1);
+ break;
+ case 128:
+ currentSlaveConfig |= (_BV(SPR1) | _BV(SPR0));
+ break;
+ case 2:
+ currentSlave2X = true;
+ break;
+ case 8:
+ currentSlave2X = true;
+ currentSlaveConfig |= _BV(SPR0);
+ break;
+ case 32:
+ currentSlave2X = true;
+ currentSlaveConfig |= _BV(SPR1);
+ break;
+ }
+
+ SPCR |= currentSlaveConfig;
+ if (currentSlave2X) {
+ SPSR |= _BV(SPI2X);
+ }
+ currentSlavePin = slavePin;
+ setPinOutput(currentSlavePin);
+ writePinLow(currentSlavePin);
+
+ return true;
+}
+
+spi_status_t spi_write(uint8_t data) {
+ SPDR = data;
+
+ uint16_t timeout_timer = timer_read();
+ while (!(SPSR & _BV(SPIF))) {
+ if ((timer_read() - timeout_timer) >= SPI_TIMEOUT) {
+ return SPI_STATUS_TIMEOUT;
+ }
+ }
+
+ return SPDR;
+}
+
+spi_status_t spi_read() {
+ SPDR = 0x00; // Dummy
+
+ uint16_t timeout_timer = timer_read();
+ while (!(SPSR & _BV(SPIF))) {
+ if ((timer_read() - timeout_timer) >= SPI_TIMEOUT) {
+ return SPI_STATUS_TIMEOUT;
+ }
+ }
+
+ return SPDR;
+}
+
+spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
+ spi_status_t status = SPI_STATUS_ERROR;
+
+ for (uint16_t i = 0; i < length; i++) {
+ status = spi_write(data[i]);
+ }
+
+ return status;
+}
+
+spi_status_t spi_receive(uint8_t *data, uint16_t length) {
+ spi_status_t status = SPI_STATUS_ERROR;
+
+ for (uint16_t i = 0; i < length; i++) {
+ status = spi_read();
+
+ if (status > 0) {
+ data[i] = status;
+ }
+ }
+
+ return (status < 0) ? status : SPI_STATUS_SUCCESS;
+}
+
+void spi_stop(void) {
+ if (currentSlavePin != NO_PIN) {
+ setPinOutput(currentSlavePin);
+ writePinHigh(currentSlavePin);
+ currentSlavePin = NO_PIN;
+ SPSR &= ~(_BV(SPI2X));
+ SPCR &= ~(currentSlaveConfig);
+ currentSlaveConfig = 0;
+ currentSlave2X = false;
+ }
+}
diff --git a/drivers/avr/spi_master.h b/drivers/avr/spi_master.h
new file mode 100644
index 000000000..b69c1cbd6
--- /dev/null
+++ b/drivers/avr/spi_master.h
@@ -0,0 +1,57 @@
+/* Copyright 2020
+ *
+ * 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 3 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 <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+typedef int16_t spi_status_t;
+
+// Hardware SS pin is defined in the header so that user code can refer to it
+#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
+# define SPI_SS_PIN B0
+#elif defined(__AVR_ATmega32A__)
+# define SPI_SS_PIN B4
+#elif defined(__AVR_ATmega328P__)
+# define SPI_SS_PIN B2
+#endif
+
+#define SPI_STATUS_SUCCESS (0)
+#define SPI_STATUS_ERROR (-1)
+#define SPI_STATUS_TIMEOUT (-2)
+
+#define SPI_TIMEOUT_IMMEDIATE (0)
+#define SPI_TIMEOUT_INFINITE (0xFFFF)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void spi_init(void);
+
+bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
+
+spi_status_t spi_write(uint8_t data);
+
+spi_status_t spi_read(void);
+
+spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
+
+spi_status_t spi_receive(uint8_t *data, uint16_t length);
+
+void spi_stop(void);
+#ifdef __cplusplus
+}
+#endif
diff --git a/keyboards/2_milk/2_milk.c b/keyboards/2_milk/2_milk.c
index 36d50e9c7..96071c2ad 100644
--- a/keyboards/2_milk/2_milk.c
+++ b/keyboards/2_milk/2_milk.c
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/2_milk/2_milk.h b/keyboards/2_milk/2_milk.h
index 8f294817f..7d90d2064 100644
--- a/keyboards/2_milk/2_milk.h
+++ b/keyboards/2_milk/2_milk.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/2_milk/config.h b/keyboards/2_milk/config.h
index 9e7228b17..e9a104117 100644
--- a/keyboards/2_milk/config.h
+++ b/keyboards/2_milk/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/2_milk/info.json b/keyboards/2_milk/info.json
index 0acf002f9..6dc4eeaf8 100644
--- a/keyboards/2_milk/info.json
+++ b/keyboards/2_milk/info.json
@@ -2,7 +2,7 @@
"keyboard_name": "2% Milk",
"keyboard_folder": "2_milk",
"url": "",
- "maintainer": "rionlion100",
+ "maintainer": "rionlion100 (Spaceman)",
"width": 1,
"height": 2,
"layouts": {
@@ -12,4 +12,3 @@
}
}
}
-
diff --git a/keyboards/2_milk/keymaps/copypasta/keymap.c b/keyboards/2_milk/keymaps/copypasta/keymap.c
index b9b8005a0..c82a6ff21 100644
--- a/keyboards/2_milk/keymaps/copypasta/keymap.c
+++ b/keyboards/2_milk/keymaps/copypasta/keymap.c
@@ -1,4 +1,3 @@
-
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
diff --git a/keyboards/2_milk/readme.md b/keyboards/2_milk/readme.md
index ce0f216bb..f3a85458c 100644
--- a/keyboards/2_milk/readme.md
+++ b/keyboards/2_milk/readme.md
@@ -4,7 +4,7 @@
A 2% Meme board themed around a milk carton
-Keyboard Maintainer: [Rionlion100](https://github.com/rionlion100)
+Keyboard Maintainer: Spaceman AKA:[Rionlion100](https://github.com/rionlion100)
Hardware Availability: [Open Source](https://github.com/Rionlion100/Spaceboards/tree/master/Keyboards/2%25%20Milk)
Make example for this keyboard (after setting up your build environment):
diff --git a/keyboards/aplx6/README.md b/keyboards/aplx6/README.md
new file mode 100644
index 000000000..55e73ea2d
--- /dev/null
+++ b/keyboards/aplx6/README.md
@@ -0,0 +1,41 @@
+# Aplx6
+
+![Front](https://i.imgur.com/flhSvAG.png)
+![Back](https://i.imgur.com/PXqNmUh.png)
+
+A stylish (2x3) 6-key MediaPad for your music and browser shortcuts. Designed to be assembled as a sandwich with a blank PCB, using M2.5 screws and spacers, your choice of MX- or Alps-compatible switches, and 1N4148 diodes.
+
+
+## RGB Underglow (WS2812)
+
+Just wire them to any of the unused ProMicro pins. Don't forget to edit-uncomment the `config.h` and the `rules.mk` for RGB underglow support, or even add your own functions and modes. Used pins can be found in `config.h` or in the [KiCad Schematic](https://github.com/Aplyard/Aplx6/blob/master/kiCad/xd6.sch). All ProMicro pins can be found [here](https://golem.hu/article/pro-micro-pinout/) along with the +2 pins mod.
+
+* Keyboard Maintainer: [Aplyard](https://github.com/Aplyard)
+* Hardware Supported: Aplx6 PCB, Pro Micro (ATmega32U4)
+* Hardware Availability: [GitHub](https://github.com/Aplyard/Aplx6)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make aplx6:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+---
+****Designed in**:**
+[KiCad](https://github.com/KiCad)
+
+**Components Footprints & Libraries :**
+[keebs.pretty](https://github.com/egladman/keebs.pretty)
+[keyboard_parts.pretty
+](https://github.com/tmk/keyboard_parts.pretty)
+[ProMicro KiCad](https://github.com/Biacco42/ProMicroKiCad)
+
+**Usefull Links:**
+[Qmk Online Configurator](https://config.qmk.fm/#)
+
+**Alternatives of qmk that worked for me:**
+[Keyboard Layout Editor](http://www.keyboard-layout-editor.com/#/)
+[Keyboard Plate & Case Builder](http://builder.swillkb.com/)
+[Firmware Builder](https://kbfirmware.com/)
+
+---
diff --git a/keyboards/aplx6/aplx6.c b/keyboards/aplx6/aplx6.c
new file mode 100644
index 000000000..3a294c199
--- /dev/null
+++ b/keyboards/aplx6/aplx6.c
@@ -0,0 +1,19 @@
+/*
+Copyright 2020 April Aplyard <alex.fragiou@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 "aplx6.h"
+
diff --git a/keyboards/aplx6/aplx6.h b/keyboards/aplx6/aplx6.h
new file mode 100644
index 000000000..6990d388e
--- /dev/null
+++ b/keyboards/aplx6/aplx6.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "quantum.h"
+
+#define LAYOUT( \
+ k000, k001, k002, \
+ k100, k101, k102 \
+) \
+{ \
+ { k000, k001, k002 }, \
+ { k100, k101, k102 } \
+}
+
diff --git a/keyboards/aplx6/config.h b/keyboards/aplx6/config.h
new file mode 100644
index 000000000..8db06d93c
--- /dev/null
+++ b/keyboards/aplx6/config.h
@@ -0,0 +1,49 @@
+/*
+Copyright 2020 April Aplyard <alex.fragiou@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/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xE0E0
+#define PRODUCT_ID 0x0030
+#define DEVICE_VER 0x0001
+#define MANUFACTURER Aplyard
+#define PRODUCT Aplx6
+#define DESCRIPTION Aplx6 MediaPad
+
+/* key matrix size */
+#define MATRIX_ROWS 2
+#define MATRIX_COLS 3
+
+/* pin-out */
+#define MATRIX_ROW_PINS { E6, B3 }
+#define MATRIX_COL_PINS { F7, B6, F4 }
+#define UNUSED_PINS
+
+
+/* ws2812 RGB LED */
+//#define RGB_DI_PIN X
+
+//#define RGBLIGHT_ANIMATIONS
+//#define RGBLED_NUM X // Number of LEDs
+
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION COL2ROW
+
diff --git a/keyboards/aplx6/keymaps/default/keymap.c b/keyboards/aplx6/keymaps/default/keymap.c
new file mode 100644
index 000000000..4c4f612a3
--- /dev/null
+++ b/keyboards/aplx6/keymaps/default/keymap.c
@@ -0,0 +1,38 @@
+#include QMK_KEYBOARD_H
+
+#define _MAIN 0
+#define _FN 1
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Keymap __MAIN: Default Layer
+ * ,--------------------------------.
+ * | .------. |-----|-----|-----| |
+ * | | | |Play |VolUp| Fn | |
+ * | | Pro | |-----|-----|-----| |
+ * | | Micro| --------------------|
+ * | | | |-----|-----|-----| |
+ * | '------' |Prev |VolD |Next | |
+ * | |||||| |-----|-----|-----| |
+ * '--------------------------------'
+ */
+ [_MAIN] = LAYOUT(
+ KC_MPLY, KC_VOLU, MO(1),
+ KC_MPRV, KC_VOLD, KC_MNXT
+ ),
+ /* Keymap __FN: Second Layer
+ * ,--------------------------------.
+ * | .------. |-----|-----|-----| |
+ * | | | |Calc |PgUp |TRANS| |
+ * | | Pro | |-----|-----|-----| |
+ * | | Micro| --------------------|
+ * | | | |-----|-----|-----| |
+ * | '------' |MyPC | PgD |RESET| |
+ * | |||||| |-----|-----|-----| |
+ * '--------------------------------'
+ */
+
+ [_FN] = LAYOUT(
+ KC_CALC, KC_PGUP, _______,
+ KC_MYCM, KC_PGDN, RESET
+ )
+};
diff --git a/keyboards/aplx6/rules.mk b/keyboards/aplx6/rules.mk
new file mode 100644
index 000000000..d2d1078d3
--- /dev/null
+++ b/keyboards/aplx6/rules.mk
@@ -0,0 +1,33 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = caterina
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # 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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+UNICODE_ENABLE = yes # Unicode
diff --git a/keyboards/bat43/info.json b/keyboards/bat43/info.json
new file mode 100644
index 000000000..dea07d298
--- /dev/null
+++ b/keyboards/bat43/info.json
@@ -0,0 +1,71 @@
+{
+ "keyboard_name": "bat43",
+ "url": "",
+ "maintainer": "yfuku",
+ "width": 15,
+ "height": 5.1,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label":"k00", "x":0, "y":1.43},
+ {"label":"k01", "x":1, "y":1.11},
+ {"label":"k02", "x":2, "y":0.38},
+ {"label":"k03", "x":3, "y":0},
+ {"label":"k04", "x":4, "y":0.05},
+ {"label":"k05", "x":5, "y":0.16},
+
+ {"label":"k40", "x":9, "y":0.16},
+ {"label":"k41", "x":10, "y":0.05},
+ {"label":"k42", "x":11, "y":0},
+ {"label":"k43", "x":12, "y":0.38},
+ {"label":"k44", "x":13, "y":1.11},
+ {"label":"k45", "x":14, "y":1.43},
+
+ {"label":"k10", "x":0, "y":2.43},
+ {"label":"k11", "x":1, "y":2.11},
+ {"label":"k12", "x":2, "y":1.38},
+ {"label":"k13", "x":3, "y":1},
+ {"label":"k14", "x":4, "y":1.05},
+ {"label":"k15", "x":5, "y":1.16},
+
+ {"label":"k30", "x":7, "y":1.16},
+
+ {"label":"k50", "x":9, "y":1.16},
+ {"label":"k51", "x":10, "y":1.05},
+ {"label":"k52", "x":11, "y":1},
+ {"label":"k53", "x":12, "y":1.38},
+ {"label":"k54", "x":13, "y":2.11},
+ {"label":"k55", "x":14, "y":2.43},
+
+ {"label":"k20", "x":0, "y":3.43},
+ {"label":"k21", "x":1, "y":3.11},
+ {"label":"k22", "x":2, "y":2.38},
+ {"label":"k23", "x":3, "y":2},
+ {"label":"k24", "x":4, "y":2.05},
+ {"label":"k25", "x":5, "y":2.16},
+
+ {"label":"k60", "x":9, "y":2.16},
+ {"label":"k61", "x":10, "y":2.05},
+ {"label":"k62", "x":11, "y":2},
+ {"label":"k63", "x":12, "y":2.38},
+ {"label":"k64", "x":13, "y":3.11},
+ {"label":"k65", "x":14, "y":3.43},
+
+ {"label":"k33", "x":4, "y":3.3},
+ {"label":"k34", "x":5, "y":3.3},
+ {"label":"k35", "x":6, "y":3.3},
+
+ {"label":"k70", "x":8, "y":3.3},
+ {"label":"k71", "x":9, "y":3.3},
+ {"label":"k72", "x":10, "y":3.3},
+
+ {"label":"k74", "x":5.1, "y":4.3, "w":0.8, "h":0.8},
+ {"label":"k75", "x":6.1, "y":4.3, "w":0.8, "h":0.8},
+
+ {"label":"k73", "x":8.1, "y":4.3, "w":0.8, "h":0.8},
+ {"label":"k31", "x":9.1, "y":4.3, "w":0.8, "h":0.8},
+ {"label":"k32", "x":10.1, "y":4.3, "w":0.8, "h":0.8}
+ ]
+ }
+ }
+}
diff --git a/keyboards/bm16a/config.h b/keyboards/bm16a/config.h
index fc0405475..249b57c35 100644
--- a/keyboards/bm16a/config.h
+++ b/keyboards/bm16a/config.h
@@ -19,8 +19,8 @@
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x424D
+#define VENDOR_ID 0x4B50 // "KP"
+#define PRODUCT_ID 0x016A
#define DEVICE_VER 0x0001
#define MANUFACTURER KPrepublic
#define PRODUCT bm16a
diff --git a/keyboards/bm16a/keymaps/via/keymap.c b/keyboards/bm16a/keymaps/via/keymap.c
new file mode 100644
index 000000000..5c8006759
--- /dev/null
+++ b/keyboards/bm16a/keymaps/via/keymap.c
@@ -0,0 +1,51 @@
+/* Copyright 2019
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+enum layers {
+ _BASE = 0,
+ _FN1,
+ _FN2,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT_ortho_4x4(
+ KC_PGUP, KC_HOME, KC_UP, KC_END ,
+ KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT,
+ KC_DOT, KC_VOLU, KC_MPLY, KC_MPRV,
+ MO(1), KC_VOLD, KC_MUTE, KC_MNXT
+ ),
+ [1] = LAYOUT_ortho_4x4(
+ 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
+ ),
+ [2] = LAYOUT_ortho_4x4(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+
+ [3] = LAYOUT_ortho_4x4(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ )
+};
diff --git a/keyboards/bm16a/keymaps/via/readme.md b/keyboards/bm16a/keymaps/via/readme.md
new file mode 100644
index 000000000..b38110875
--- /dev/null
+++ b/keyboards/bm16a/keymaps/via/readme.md
@@ -0,0 +1 @@
+# Via keymap for bm16a
diff --git a/keyboards/bm16a/keymaps/via/rules.mk b/keyboards/bm16a/keymaps/via/rules.mk
new file mode 100644
index 000000000..36b7ba9cb
--- /dev/null
+++ b/keyboards/bm16a/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
diff --git a/keyboards/botanicalkeyboards/fm2u/config.h b/keyboards/botanicalkeyboards/fm2u/config.h
new file mode 100644
index 000000000..944b7b3b2
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/config.h
@@ -0,0 +1,55 @@
+/*
+Copyright 2020 mechmerlin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x6969
+#define PRODUCT_ID 0x0001
+#define DEVICE_VER 0x0001
+#define MANUFACTURER botanicalkeyboards
+#define PRODUCT fm2u
+#define DESCRIPTION A 1 key macropad
+
+/* key matrix size */
+#define MATRIX_ROWS 1
+#define MATRIX_COLS 1
+
+/* Keyboard Matrix Assignments */
+#define DIRECT_PINS { \
+ { C4 } \
+}
+
+/*
+ * 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 UNUSED_PINS
+
+/* COL2ROW, ROW2COL*/
+#define DIODE_DIRECTION COL2ROW
+
+
+
diff --git a/keyboards/botanicalkeyboards/fm2u/fm2u.c b/keyboards/botanicalkeyboards/fm2u/fm2u.c
new file mode 100644
index 000000000..9729e5eec
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/fm2u.c
@@ -0,0 +1,17 @@
+/* Copyright 2020 mechmerlin
+ *
+ * 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 "fm2u.h"
diff --git a/keyboards/botanicalkeyboards/fm2u/fm2u.h b/keyboards/botanicalkeyboards/fm2u/fm2u.h
new file mode 100644
index 000000000..eb5564afc
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/fm2u.h
@@ -0,0 +1,46 @@
+/* Copyright 2020 mechmerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT_100u( \
+ k00 \
+) \
+{ \
+ { k00 } \
+}
+
+#define LAYOUT_125u LAYOUT_100u
+#define LAYOUT_150u LAYOUT_100u
+#define LAYOUT_175u LAYOUT_100u
+#define LAYOUT_200u LAYOUT_100u
+#define LAYOUT_225u LAYOUT_100u
+#define LAYOUT_275u LAYOUT_100u
+#define LAYOUT_300u LAYOUT_100u
+#define LAYOUT_600u LAYOUT_100u
+#define LAYOUT_625u LAYOUT_100u
+#define LAYOUT_700u LAYOUT_100u
+#define LAYOUT_iso LAYOUT_100u
diff --git a/keyboards/botanicalkeyboards/fm2u/info.json b/keyboards/botanicalkeyboards/fm2u/info.json
new file mode 100644
index 000000000..6831dad94
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/info.json
@@ -0,0 +1,56 @@
+{
+ "keyboard_name": "fm2u",
+ "url": "",
+ "maintainer": "qmk",
+ "width": 1,
+ "height": 1,
+ "layouts": {
+ "LAYOUT_100u": {
+ "layout": [{"x":0, "y":0}]
+ },
+
+ "LAYOUT_125u": {
+ "layout": [{"x":0, "y":0, "w":1.25}]
+ },
+
+ "LAYOUT_150u": {
+ "layout": [{"x":0, "y":0, "w":1.50}]
+ },
+
+ "LAYOUT_175u": {
+ "layout": [{"x":0, "y":0, "w":1.75}]
+ },
+
+ "LAYOUT_200u": {
+ "layout": [{"x":0, "y":0, "w":2.00}]
+ },
+
+ "LAYOUT_225u": {
+ "layout": [{"x":0, "y":0, "w":2.25}]
+ },
+
+ "LAYOUT_275u": {
+ "layout": [{"x":0, "y":0, "w":2.75}]
+ },
+
+ "LAYOUT_300u": {
+ "layout": [{"x":0, "y":0, "w":3.00}]
+ },
+
+ "LAYOUT_600u": {
+ "layout": [{"x":0, "y":0, "w":6.00}]
+ },
+
+ "LAYOUT_625u": {
+ "layout": [{"x":0, "y":0, "w":6.25}]
+ },
+
+ "LAYOUT_700u": {
+ "layout": [{"x":0, "y":0, "w":7.00}]
+ },
+
+ "LAYOUT_iso": {
+ "layout": [{"x":0.25, "y":0, "w":1.25, "h":2}]
+ }
+ }
+}
diff --git a/keyboards/botanicalkeyboards/fm2u/keymaps/default/keymap.c b/keyboards/botanicalkeyboards/fm2u/keymaps/default/keymap.c
new file mode 100644
index 000000000..afefa3533
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/keymaps/default/keymap.c
@@ -0,0 +1,25 @@
+/* Copyright 2020 mechmerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Base */
+ [0] = LAYOUT_100u(
+ KC_B
+ )
+};
+
diff --git a/keyboards/botanicalkeyboards/fm2u/keymaps/via/keymap.c b/keyboards/botanicalkeyboards/fm2u/keymaps/via/keymap.c
new file mode 100644
index 000000000..01b00f187
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/keymaps/via/keymap.c
@@ -0,0 +1,37 @@
+/* Copyright 2020 mechmerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Base */
+ [0] = LAYOUT_100u(
+ KC_B
+ ),
+
+ [1] = LAYOUT_100u(
+ KC_TRNS
+ ),
+
+ [2] = LAYOUT_100u(
+ KC_TRNS
+ ),
+
+ [3] = LAYOUT_100u(
+ KC_TRNS
+ ),
+};
+
diff --git a/keyboards/botanicalkeyboards/fm2u/keymaps/via/rules.mk b/keyboards/botanicalkeyboards/fm2u/keymaps/via/rules.mk
new file mode 100644
index 000000000..7d47e6b72
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/keymaps/via/rules.mk
@@ -0,0 +1,4 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/botanicalkeyboards/fm2u/readme.md b/keyboards/botanicalkeyboards/fm2u/readme.md
new file mode 100644
index 000000000..511c09214
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/readme.md
@@ -0,0 +1,13 @@
+# fm2u
+
+A 1 key macropad with USB C and atmega32u2 microcontroller.
+
+* Keyboard Maintainer: [MechMerlin](https://github.com/mechmerlin)
+* Hardware Supported: fm2u PCB
+* Hardware Availability: TBD
+
+Make example for this keyboard (after setting up your build environment):
+
+ make botanicalkeyboards/fm2u:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/botanicalkeyboards/fm2u/rules.mk b/keyboards/botanicalkeyboards/fm2u/rules.mk
new file mode 100644
index 000000000..4f7f9b286
--- /dev/null
+++ b/keyboards/botanicalkeyboards/fm2u/rules.mk
@@ -0,0 +1,32 @@
+# MCU name
+MCU = atmega32u2
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = atmel-dfu
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
diff --git a/keyboards/butterstick/keymaps/dennytom/README.md b/keyboards/butterstick/keymaps/dennytom/README.md
new file mode 100644
index 000000000..a75bcc750
--- /dev/null
+++ b/keyboards/butterstick/keymaps/dennytom/README.md
@@ -0,0 +1,11 @@
+# # Dennytom's Butterstick Layout
+
+This keymap is using a custom chording engine. Head out to my (DennyTom) user space to find the source files and details.
+
+To make a real keymap from the JSON file, run
+
+```sh
+python3 parser.py keymap_def.json keymap.c
+```
+
+Somehow it fits the whole keyboard on 20 keys. For longer typing sessions, use the ASET NIOP mode. \ No newline at end of file
diff --git a/keyboards/butterstick/keymaps/dennytom/keymap.c b/keyboards/butterstick/keymaps/dennytom/keymap.c
new file mode 100644
index 000000000..bfe0aa215
--- /dev/null
+++ b/keyboards/butterstick/keymaps/dennytom/keymap.c
@@ -0,0 +1,1418 @@
+#include QMK_KEYBOARD_H
+
+#define CHORD_TIMEOUT 100
+#define DANCE_TIMEOUT 200
+#define LEADER_TIMEOUT 750
+#define TAP_TIMEOUT 50
+#define LONG_PRESS_MULTIPLIER 3
+#define DYNAMIC_MACRO_MAX_LENGTH 20
+#define COMMAND_MAX_LENGTH 5
+#define LEADER_MAX_LENGTH 5
+#define HASH_TYPE uint32_t
+#define NUMBER_OF_KEYS 20
+#define DEFAULT_PSEUDOLAYER QWERTY
+
+#define H_TOP1 ((HASH_TYPE) 1 << 0)
+#define H_TOP2 ((HASH_TYPE) 1 << 1)
+#define H_TOP3 ((HASH_TYPE) 1 << 2)
+#define H_TOP4 ((HASH_TYPE) 1 << 3)
+#define H_TOP5 ((HASH_TYPE) 1 << 4)
+#define H_TOP6 ((HASH_TYPE) 1 << 5)
+#define H_TOP7 ((HASH_TYPE) 1 << 6)
+#define H_TOP8 ((HASH_TYPE) 1 << 7)
+#define H_TOP9 ((HASH_TYPE) 1 << 8)
+#define H_TOP0 ((HASH_TYPE) 1 << 9)
+#define H_BOT1 ((HASH_TYPE) 1 << 10)
+#define H_BOT2 ((HASH_TYPE) 1 << 11)
+#define H_BOT3 ((HASH_TYPE) 1 << 12)
+#define H_BOT4 ((HASH_TYPE) 1 << 13)
+#define H_BOT5 ((HASH_TYPE) 1 << 14)
+#define H_BOT6 ((HASH_TYPE) 1 << 15)
+#define H_BOT7 ((HASH_TYPE) 1 << 16)
+#define H_BOT8 ((HASH_TYPE) 1 << 17)
+#define H_BOT9 ((HASH_TYPE) 1 << 18)
+#define H_BOT0 ((HASH_TYPE) 1 << 19)
+
+enum internal_keycodes {
+ TOP1 = SAFE_RANGE,
+ TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP0, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT0,
+ FIRST_INTERNAL_KEYCODE = TOP1,
+ LAST_INTERNAL_KEYCODE = BOT0
+};
+
+enum pseudolayers {
+ ALWAYS_ON, QWERTY, NUM, MOV, MOUSE, ASETNIOP, ASETNIOP_123, ASETNIOP_FN
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_butter(TOP1, TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP0, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT0),
+};
+size_t keymapsCount = 1;
+
+uint8_t keycodes_buffer_array[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+uint8_t command_buffer[] = {
+ 0, 0, 0, 0, 0
+};
+
+uint16_t leader_buffer[] = {
+ 0, 0, 0, 0, 0
+};
+
+uint8_t dynamic_macro_buffer[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+enum chord_states {
+ IDLE,
+ READY,
+ ACTIVATED,
+ DEACTIVATED,
+ PRESS_FROM_ACTIVE,
+ FINISHED_FROM_ACTIVE,
+ IDLE_IN_DANCE,
+ READY_IN_DANCE,
+ FINISHED,
+ LOCKED,
+ READY_LOCKED,
+ RESTART,
+ IN_ONE_SHOT
+};
+
+struct Chord {
+ uint32_t keycodes_hash;
+ uint8_t pseudolayer;
+ uint8_t* state;
+ uint8_t* counter;
+ uint16_t value1;
+ uint8_t value2;
+ void (*function) (const struct Chord*);
+};
+
+uint8_t current_pseudolayer = DEFAULT_PSEUDOLAYER;
+bool lock_next = false;
+uint16_t chord_timer = 0;
+uint16_t dance_timer = 0;
+bool autoshift_mode = true;
+uint8_t keycode_index = 0;
+uint8_t command_mode = 0;
+uint8_t command_ind = 0;
+bool in_leader_mode = false;
+uint8_t leader_ind = 0;
+uint16_t leader_timer = 0;
+uint8_t dynamic_macro_mode = false;
+uint8_t dynamic_macro_ind = 0;
+bool a_key_went_through = false;
+struct Chord* last_chord = NULL;
+
+bool handle_US_ANSI_shifted_keys(int16_t keycode, bool in) {
+ bool is_US_ANSI_shifted = true;
+
+ int16_t regular_keycode = KC_NO;
+ switch (keycode) {
+ case KC_TILDE:
+ regular_keycode = KC_GRAVE;
+ break;
+ case KC_EXCLAIM:
+ regular_keycode = KC_1;
+ break;
+ case KC_AT:
+ regular_keycode = KC_2;
+ break;
+ case KC_HASH:
+ regular_keycode = KC_3;
+ break;
+ case KC_DOLLAR:
+ regular_keycode = KC_4;
+ break;
+ case KC_PERCENT:
+ regular_keycode = KC_5;
+ break;
+ case KC_CIRCUMFLEX:
+ regular_keycode = KC_6;
+ break;
+ case KC_AMPERSAND:
+ regular_keycode = KC_7;
+ break;
+ case KC_ASTERISK:
+ regular_keycode = KC_8;
+ break;
+ case KC_LEFT_PAREN:
+ regular_keycode = KC_9;
+ break;
+ case KC_RIGHT_PAREN:
+ regular_keycode = KC_0;
+ break;
+ case KC_UNDERSCORE:
+ regular_keycode = KC_MINUS;
+ break;
+ case KC_PLUS:
+ regular_keycode = KC_EQUAL;
+ break;
+ case KC_LEFT_CURLY_BRACE:
+ regular_keycode = KC_LBRACKET;
+ break;
+ case KC_RIGHT_CURLY_BRACE:
+ regular_keycode = KC_RBRACKET;
+ break;
+ case KC_PIPE:
+ regular_keycode = KC_BSLASH;
+ break;
+ case KC_COLON:
+ regular_keycode = KC_SCOLON;
+ break;
+ case KC_DOUBLE_QUOTE:
+ regular_keycode = KC_QUOTE;
+ break;
+ case KC_LEFT_ANGLE_BRACKET:
+ regular_keycode = KC_COMMA;
+ break;
+ case KC_RIGHT_ANGLE_BRACKET:
+ regular_keycode = KC_DOT;
+ break;
+ case KC_QUESTION:
+ regular_keycode = KC_SLASH;
+ break;
+ default:
+ is_US_ANSI_shifted = false;
+ }
+ if (is_US_ANSI_shifted) {
+ if (in) {
+ register_code(KC_LSFT);
+ register_code(regular_keycode);
+ } else {
+ unregister_code(regular_keycode);
+ unregister_code(KC_LSFT);
+ }
+ }
+ return is_US_ANSI_shifted;
+}
+
+void key_in(int16_t keycode) {
+ if (command_mode == 1 && command_ind < COMMAND_MAX_LENGTH) {
+ command_buffer[command_ind] = keycode;
+ command_ind++;
+ a_key_went_through = true;
+ } else if (in_leader_mode && leader_ind < LEADER_MAX_LENGTH) {
+ leader_buffer[leader_ind] = keycode;
+ leader_ind++;
+ a_key_went_through = true;
+ } else if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = keycode;
+ dynamic_macro_ind++;
+ a_key_went_through = true;
+ } else {
+ if (!handle_US_ANSI_shifted_keys(keycode, true)) {
+ register_code(keycode);
+ }
+ send_keyboard_report();
+ a_key_went_through = true;
+ }
+}
+
+void key_out(int16_t keycode) {
+ if (command_mode == 0) {
+ if (!handle_US_ANSI_shifted_keys(keycode, false)) {
+ if (command_mode == 0 && in_leader_mode == false && dynamic_macro_mode == false) {
+ unregister_code(keycode);
+ }
+ }
+ send_keyboard_report();
+ }
+}
+
+void tap_key(int16_t keycode) {
+ key_in(keycode);
+ wait_ms(TAP_TIMEOUT);
+ key_out(keycode);
+}
+void single_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value1);
+ break;
+ case DEACTIVATED:
+ key_out(self->value1);
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ key_out(self->value1);
+ break;
+ default:
+ break;
+ }
+}
+
+void key_layer_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value2;
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_mod_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value2);
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ key_out(self->value2);
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_key_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value2);
+ break;
+ case RESTART:
+ key_out(self->value2);
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance_impl(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ *self->counter = 0;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED_FROM_ACTIVE:
+ if (*self->counter == (LONG_PRESS_MULTIPLIER - 2)) {
+ key_in(KC_LSFT);
+ tap_key(self->value1);
+ key_out(KC_LSFT);
+ *self->state = IDLE;
+ // the skip to IDLE is usually just a lag optimization,
+ // in this case it has a logic function, on a short
+ // press (still longer than a tap) the key does not get shifted
+ } else {
+ *self->counter += 1;
+ *self->state = PRESS_FROM_ACTIVE;
+ dance_timer = timer_read();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance(const struct Chord* self) {
+ if (autoshift_mode) {
+ autoshift_dance_impl(self);
+ } else {
+ single_dance(self);
+ }
+}
+
+void autoshift_toggle(const struct Chord* self){
+ if (*self->state == ACTIVATED) {
+ autoshift_mode = !autoshift_mode;
+ *self->state = IDLE;
+ }
+}
+
+void temp_pseudolayer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value1;
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ current_pseudolayer = self->pseudolayer;
+ break;
+ default:
+ break;
+ }
+}
+
+void perm_pseudolayer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ current_pseudolayer = self->value1;
+ *self->state = IDLE;
+ }
+}
+
+void switch_layer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ layer_move(self->value1);
+ *self->state = IDLE;
+ }
+}
+
+void lock(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ lock_next = true;
+ *self->state = IDLE;
+ }
+}
+
+void one_shot_key(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ key_in(self->value1);
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value1);
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ key_out(self->value1);
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void one_shot_layer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->value1;
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ current_pseudolayer = self->value1;
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ current_pseudolayer = self->pseudolayer;
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void command(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ command_mode++;
+ *self->state = IDLE;
+ }
+}
+
+bool identical(uint16_t* buffer1, uint16_t* buffer2) {
+ bool same = true;
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ same = same && (buffer1[i] == buffer2[i]);
+ }
+ return same;
+}
+
+void leader(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ in_leader_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_record(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ dynamic_macro_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_next(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = 0;
+ dynamic_macro_ind++;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_end(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode) {
+ dynamic_macro_mode = false;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_play(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ int ind_start = 0;
+ while (ind_start < DYNAMIC_MACRO_MAX_LENGTH) {
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ break;
+ }
+ register_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ wait_ms(TAP_TIMEOUT);
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ ind_start = i + 1;
+ break;
+ }
+ unregister_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ *self->state = IDLE;
+ }
+}
+
+void clear(const struct Chord* self);
+
+void reset_keyboard_kb(void){
+#ifdef WATCHDOG_ENABLE
+ MCUSR = 0;
+ wdt_disable();
+ wdt_reset();
+#endif
+ reset_keyboard();
+}
+
+void reset(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ reset_keyboard_kb();
+ }
+}
+
+uint8_t state_0 = IDLE;
+const struct Chord chord_0 PROGMEM = {H_TOP1 + H_TOP2 + H_BOT1 + H_BOT2, ALWAYS_ON, &state_0, NULL, 0, 0, lock};
+uint8_t state_1 = IDLE;
+const struct Chord chord_1 PROGMEM = {H_TOP2 + H_TOP3 + H_BOT2 + H_BOT3, ALWAYS_ON, &state_1, NULL, 0, 0, autoshift_toggle};
+uint8_t state_2 = IDLE;
+const struct Chord chord_2 PROGMEM = {H_TOP5 + H_TOP6 + H_BOT5 + H_BOT6, ALWAYS_ON, &state_2, NULL, 0, 0, command};
+uint8_t state_3 = IDLE;
+const struct Chord chord_3 PROGMEM = {H_TOP1 + H_TOP2 + H_TOP9 + H_TOP0 + H_BOT1 + H_BOT2 + H_BOT9 + H_BOT0, ALWAYS_ON, &state_3, NULL, 0, 0, clear};
+uint8_t state_4 = IDLE;
+uint8_t counter_4 = 0;
+const struct Chord chord_4 PROGMEM = {H_TOP1, QWERTY, &state_4, &counter_4, KC_Q, 0, autoshift_dance};
+uint8_t state_5 = IDLE;
+uint8_t counter_5 = 0;
+const struct Chord chord_5 PROGMEM = {H_TOP2, QWERTY, &state_5, &counter_5, KC_W, 0, autoshift_dance};
+uint8_t state_6 = IDLE;
+uint8_t counter_6 = 0;
+const struct Chord chord_6 PROGMEM = {H_TOP3, QWERTY, &state_6, &counter_6, KC_E, 0, autoshift_dance};
+uint8_t state_7 = IDLE;
+uint8_t counter_7 = 0;
+const struct Chord chord_7 PROGMEM = {H_TOP4, QWERTY, &state_7, &counter_7, KC_R, 0, autoshift_dance};
+uint8_t state_8 = IDLE;
+uint8_t counter_8 = 0;
+const struct Chord chord_8 PROGMEM = {H_TOP5, QWERTY, &state_8, &counter_8, KC_T, 0, autoshift_dance};
+uint8_t state_9 = IDLE;
+uint8_t counter_9 = 0;
+const struct Chord chord_9 PROGMEM = {H_TOP6, QWERTY, &state_9, &counter_9, KC_Y, 0, autoshift_dance};
+uint8_t state_10 = IDLE;
+uint8_t counter_10 = 0;
+const struct Chord chord_10 PROGMEM = {H_TOP7, QWERTY, &state_10, &counter_10, KC_U, 0, autoshift_dance};
+uint8_t state_11 = IDLE;
+uint8_t counter_11 = 0;
+const struct Chord chord_11 PROGMEM = {H_TOP8, QWERTY, &state_11, &counter_11, KC_I, 0, autoshift_dance};
+uint8_t state_12 = IDLE;
+uint8_t counter_12 = 0;
+const struct Chord chord_12 PROGMEM = {H_TOP9, QWERTY, &state_12, &counter_12, KC_O, 0, autoshift_dance};
+uint8_t state_13 = IDLE;
+uint8_t counter_13 = 0;
+const struct Chord chord_13 PROGMEM = {H_TOP0, QWERTY, &state_13, &counter_13, KC_P, 0, autoshift_dance};
+uint8_t state_14 = IDLE;
+uint8_t counter_14 = 0;
+const struct Chord chord_14 PROGMEM = {H_TOP1 + H_BOT1, QWERTY, &state_14, &counter_14, KC_A, 0, autoshift_dance};
+uint8_t state_15 = IDLE;
+uint8_t counter_15 = 0;
+const struct Chord chord_15 PROGMEM = {H_TOP2 + H_BOT2, QWERTY, &state_15, &counter_15, KC_S, 0, autoshift_dance};
+uint8_t state_16 = IDLE;
+uint8_t counter_16 = 0;
+const struct Chord chord_16 PROGMEM = {H_TOP3 + H_BOT3, QWERTY, &state_16, &counter_16, KC_D, 0, autoshift_dance};
+uint8_t state_17 = IDLE;
+uint8_t counter_17 = 0;
+const struct Chord chord_17 PROGMEM = {H_TOP4 + H_BOT4, QWERTY, &state_17, &counter_17, KC_F, 0, autoshift_dance};
+uint8_t state_18 = IDLE;
+uint8_t counter_18 = 0;
+const struct Chord chord_18 PROGMEM = {H_TOP5 + H_BOT5, QWERTY, &state_18, &counter_18, KC_G, 0, autoshift_dance};
+uint8_t state_19 = IDLE;
+uint8_t counter_19 = 0;
+const struct Chord chord_19 PROGMEM = {H_TOP6 + H_BOT6, QWERTY, &state_19, &counter_19, KC_H, 0, autoshift_dance};
+uint8_t state_20 = IDLE;
+uint8_t counter_20 = 0;
+const struct Chord chord_20 PROGMEM = {H_TOP7 + H_BOT7, QWERTY, &state_20, &counter_20, KC_J, 0, autoshift_dance};
+uint8_t state_21 = IDLE;
+uint8_t counter_21 = 0;
+const struct Chord chord_21 PROGMEM = {H_TOP8 + H_BOT8, QWERTY, &state_21, &counter_21, KC_K, 0, autoshift_dance};
+uint8_t state_22 = IDLE;
+uint8_t counter_22 = 0;
+const struct Chord chord_22 PROGMEM = {H_TOP9 + H_BOT9, QWERTY, &state_22, &counter_22, KC_L, 0, autoshift_dance};
+uint8_t state_23 = IDLE;
+uint8_t counter_23 = 0;
+const struct Chord chord_23 PROGMEM = {H_TOP0 + H_BOT0, QWERTY, &state_23, &counter_23, KC_SCOLON, 0, autoshift_dance};
+uint8_t state_24 = IDLE;
+uint8_t counter_24 = 0;
+const struct Chord chord_24 PROGMEM = {H_BOT1, QWERTY, &state_24, &counter_24, KC_Z, 0, autoshift_dance};
+uint8_t state_25 = IDLE;
+uint8_t counter_25 = 0;
+const struct Chord chord_25 PROGMEM = {H_BOT2, QWERTY, &state_25, &counter_25, KC_X, 0, autoshift_dance};
+uint8_t state_26 = IDLE;
+uint8_t counter_26 = 0;
+const struct Chord chord_26 PROGMEM = {H_BOT3, QWERTY, &state_26, &counter_26, KC_C, 0, autoshift_dance};
+uint8_t state_27 = IDLE;
+uint8_t counter_27 = 0;
+const struct Chord chord_27 PROGMEM = {H_BOT4, QWERTY, &state_27, &counter_27, KC_V, 0, autoshift_dance};
+uint8_t state_28 = IDLE;
+uint8_t counter_28 = 0;
+const struct Chord chord_28 PROGMEM = {H_BOT5, QWERTY, &state_28, &counter_28, KC_B, 0, autoshift_dance};
+uint8_t state_29 = IDLE;
+uint8_t counter_29 = 0;
+const struct Chord chord_29 PROGMEM = {H_BOT6, QWERTY, &state_29, &counter_29, KC_N, 0, autoshift_dance};
+uint8_t state_30 = IDLE;
+uint8_t counter_30 = 0;
+const struct Chord chord_30 PROGMEM = {H_BOT7, QWERTY, &state_30, &counter_30, KC_M, 0, autoshift_dance};
+uint8_t state_31 = IDLE;
+uint8_t counter_31 = 0;
+const struct Chord chord_31 PROGMEM = {H_BOT8, QWERTY, &state_31, &counter_31, KC_COMMA, 0, autoshift_dance};
+uint8_t state_32 = IDLE;
+uint8_t counter_32 = 0;
+const struct Chord chord_32 PROGMEM = {H_BOT9, QWERTY, &state_32, &counter_32, KC_DOT, 0, autoshift_dance};
+uint8_t state_33 = IDLE;
+uint8_t counter_33 = 0;
+const struct Chord chord_33 PROGMEM = {H_BOT0, QWERTY, &state_33, &counter_33, KC_SLASH, 0, autoshift_dance};
+uint8_t state_34 = IDLE;
+const struct Chord chord_34 PROGMEM = {H_TOP1 + H_TOP2, QWERTY, &state_34, NULL, KC_ESC, 0, single_dance};
+uint8_t state_35 = IDLE;
+const struct Chord chord_35 PROGMEM = {H_TOP2 + H_TOP3, QWERTY, &state_35, NULL, MOV, 0, temp_pseudolayer};
+uint8_t state_36 = IDLE;
+const struct Chord chord_36 PROGMEM = {H_TOP3 + H_TOP4, QWERTY, &state_36, NULL, KC_TAB, 0, single_dance};
+uint8_t state_37 = IDLE;
+const struct Chord chord_37 PROGMEM = {H_TOP5 + H_TOP6, QWERTY, &state_37, NULL, KC_RGUI, 0, one_shot_key};
+uint8_t state_38 = IDLE;
+const struct Chord chord_38 PROGMEM = {H_TOP7 + H_TOP8, QWERTY, &state_38, NULL, KC_INS, 0, single_dance};
+uint8_t state_39 = IDLE;
+const struct Chord chord_39 PROGMEM = {H_TOP8 + H_TOP9, QWERTY, &state_39, NULL, KC_DEL, 0, single_dance};
+uint8_t state_40 = IDLE;
+const struct Chord chord_40 PROGMEM = {H_TOP9 + H_TOP0, QWERTY, &state_40, NULL, KC_BSPC, 0, single_dance};
+uint8_t state_41 = IDLE;
+const struct Chord chord_41 PROGMEM = {H_TOP9 + H_TOP0 + H_BOT9 + H_BOT0, QWERTY, &state_41, NULL, KC_ENTER, 0, single_dance};
+uint8_t state_42 = IDLE;
+const struct Chord chord_42 PROGMEM = {H_BOT1 + H_BOT2, QWERTY, &state_42, NULL, KC_LSFT, 0, one_shot_key};
+uint8_t state_43 = IDLE;
+const struct Chord chord_43 PROGMEM = {H_BOT2 + H_BOT3, QWERTY, &state_43, NULL, KC_LCTL, 0, one_shot_key};
+uint8_t state_44 = IDLE;
+const struct Chord chord_44 PROGMEM = {H_BOT3 + H_BOT4, QWERTY, &state_44, NULL, KC_LALT, 0, one_shot_key};
+uint8_t state_45 = IDLE;
+const struct Chord chord_45 PROGMEM = {H_BOT4 + H_BOT5, QWERTY, &state_45, NULL, NUM, 0, one_shot_layer};
+uint8_t state_46 = IDLE;
+const struct Chord chord_46 PROGMEM = {H_BOT5 + H_BOT6, QWERTY, &state_46, NULL, KC_LGUI, 0, one_shot_key};
+uint8_t state_47 = IDLE;
+const struct Chord chord_47 PROGMEM = {H_BOT6 + H_BOT7, QWERTY, &state_47, NULL, NUM, 0, one_shot_layer};
+uint8_t state_48 = IDLE;
+const struct Chord chord_48 PROGMEM = {H_BOT7 + H_BOT8, QWERTY, &state_48, NULL, KC_RALT, 0, one_shot_key};
+uint8_t state_49 = IDLE;
+const struct Chord chord_49 PROGMEM = {H_BOT8 + H_BOT9, QWERTY, &state_49, NULL, KC_RCTL, 0, one_shot_key};
+uint8_t state_50 = IDLE;
+const struct Chord chord_50 PROGMEM = {H_BOT9 + H_BOT0, QWERTY, &state_50, NULL, KC_RSFT, 0, one_shot_key};
+uint8_t state_51 = IDLE;
+const struct Chord chord_51 PROGMEM = {H_BOT1 + H_BOT0, QWERTY, &state_51, NULL, KC_SPACE, 0, single_dance};
+uint8_t state_52 = IDLE;
+const struct Chord chord_52 PROGMEM = {H_TOP1 + H_TOP2 + H_TOP3 + H_TOP4, QWERTY, &state_52, NULL, MOUSE, 0, temp_pseudolayer};
+uint8_t state_53 = IDLE;
+const struct Chord chord_53 PROGMEM = {H_TOP1 + H_TOP2 + H_TOP3 + H_TOP4, QWERTY, &state_53, NULL, ASETNIOP, 0, perm_pseudolayer};
+uint8_t state_54 = IDLE;
+uint8_t counter_54 = 0;
+const struct Chord chord_54 PROGMEM = {H_TOP1, NUM, &state_54, &counter_54, KC_1, 0, autoshift_dance};
+uint8_t state_55 = IDLE;
+uint8_t counter_55 = 0;
+const struct Chord chord_55 PROGMEM = {H_TOP2, NUM, &state_55, &counter_55, KC_2, 0, autoshift_dance};
+uint8_t state_56 = IDLE;
+uint8_t counter_56 = 0;
+const struct Chord chord_56 PROGMEM = {H_TOP3, NUM, &state_56, &counter_56, KC_3, 0, autoshift_dance};
+uint8_t state_57 = IDLE;
+uint8_t counter_57 = 0;
+const struct Chord chord_57 PROGMEM = {H_TOP4, NUM, &state_57, &counter_57, KC_4, 0, autoshift_dance};
+uint8_t state_58 = IDLE;
+uint8_t counter_58 = 0;
+const struct Chord chord_58 PROGMEM = {H_TOP5, NUM, &state_58, &counter_58, KC_5, 0, autoshift_dance};
+uint8_t state_59 = IDLE;
+uint8_t counter_59 = 0;
+const struct Chord chord_59 PROGMEM = {H_TOP6, NUM, &state_59, &counter_59, KC_6, 0, autoshift_dance};
+uint8_t state_60 = IDLE;
+uint8_t counter_60 = 0;
+const struct Chord chord_60 PROGMEM = {H_TOP7, NUM, &state_60, &counter_60, KC_7, 0, autoshift_dance};
+uint8_t state_61 = IDLE;
+uint8_t counter_61 = 0;
+const struct Chord chord_61 PROGMEM = {H_TOP8, NUM, &state_61, &counter_61, KC_8, 0, autoshift_dance};
+uint8_t state_62 = IDLE;
+uint8_t counter_62 = 0;
+const struct Chord chord_62 PROGMEM = {H_TOP9, NUM, &state_62, &counter_62, KC_9, 0, autoshift_dance};
+uint8_t state_63 = IDLE;
+uint8_t counter_63 = 0;
+const struct Chord chord_63 PROGMEM = {H_TOP0, NUM, &state_63, &counter_63, KC_0, 0, autoshift_dance};
+uint8_t state_64 = IDLE;
+const struct Chord chord_64 PROGMEM = {H_TOP1 + H_BOT1, NUM, &state_64, NULL, KC_F1, 0, single_dance};
+uint8_t state_65 = IDLE;
+const struct Chord chord_65 PROGMEM = {H_TOP2 + H_BOT2, NUM, &state_65, NULL, KC_F2, 0, single_dance};
+uint8_t state_66 = IDLE;
+const struct Chord chord_66 PROGMEM = {H_TOP3 + H_BOT3, NUM, &state_66, NULL, KC_F3, 0, single_dance};
+uint8_t state_67 = IDLE;
+const struct Chord chord_67 PROGMEM = {H_TOP4 + H_BOT4, NUM, &state_67, NULL, KC_F4, 0, single_dance};
+uint8_t state_68 = IDLE;
+const struct Chord chord_68 PROGMEM = {H_TOP5 + H_BOT5, NUM, &state_68, NULL, KC_F5, 0, single_dance};
+uint8_t state_69 = IDLE;
+const struct Chord chord_69 PROGMEM = {H_TOP6 + H_BOT6, NUM, &state_69, NULL, KC_F6, 0, single_dance};
+uint8_t state_70 = IDLE;
+const struct Chord chord_70 PROGMEM = {H_TOP7 + H_BOT7, NUM, &state_70, NULL, KC_F7, 0, single_dance};
+uint8_t state_71 = IDLE;
+const struct Chord chord_71 PROGMEM = {H_TOP8 + H_BOT8, NUM, &state_71, NULL, KC_F8, 0, single_dance};
+uint8_t state_72 = IDLE;
+const struct Chord chord_72 PROGMEM = {H_TOP9 + H_BOT9, NUM, &state_72, NULL, KC_F9, 0, single_dance};
+uint8_t state_73 = IDLE;
+const struct Chord chord_73 PROGMEM = {H_TOP0 + H_BOT0, NUM, &state_73, NULL, KC_F10, 0, single_dance};
+uint8_t state_74 = IDLE;
+uint8_t counter_74 = 0;
+const struct Chord chord_74 PROGMEM = {H_BOT1, NUM, &state_74, &counter_74, KC_GRAVE, 0, autoshift_dance};
+uint8_t state_75 = IDLE;
+uint8_t counter_75 = 0;
+const struct Chord chord_75 PROGMEM = {H_BOT2, NUM, &state_75, &counter_75, KC_MINUS, 0, autoshift_dance};
+uint8_t state_76 = IDLE;
+uint8_t counter_76 = 0;
+const struct Chord chord_76 PROGMEM = {H_BOT3, NUM, &state_76, &counter_76, KC_EQUAL, 0, autoshift_dance};
+uint8_t state_77 = IDLE;
+uint8_t counter_77 = 0;
+const struct Chord chord_77 PROGMEM = {H_BOT4, NUM, &state_77, &counter_77, KC_LBRACKET, 0, autoshift_dance};
+uint8_t state_78 = IDLE;
+uint8_t counter_78 = 0;
+const struct Chord chord_78 PROGMEM = {H_BOT5, NUM, &state_78, &counter_78, KC_RBRACKET, 0, autoshift_dance};
+uint8_t state_79 = IDLE;
+uint8_t counter_79 = 0;
+const struct Chord chord_79 PROGMEM = {H_BOT6, NUM, &state_79, &counter_79, KC_BSLASH, 0, autoshift_dance};
+uint8_t state_80 = IDLE;
+uint8_t counter_80 = 0;
+const struct Chord chord_80 PROGMEM = {H_BOT7, NUM, &state_80, &counter_80, KC_QUOTE, 0, autoshift_dance};
+uint8_t state_81 = IDLE;
+const struct Chord chord_81 PROGMEM = {H_BOT9, NUM, &state_81, NULL, KC_F11, 0, single_dance};
+uint8_t state_82 = IDLE;
+const struct Chord chord_82 PROGMEM = {H_BOT0, NUM, &state_82, NULL, KC_F12, 0, single_dance};
+uint8_t state_83 = IDLE;
+const struct Chord chord_83 PROGMEM = {H_TOP1 + H_TOP2, NUM, &state_83, NULL, KC_ESC, 0, single_dance};
+uint8_t state_84 = IDLE;
+const struct Chord chord_84 PROGMEM = {H_TOP3 + H_TOP4, NUM, &state_84, NULL, KC_TAB, 0, single_dance};
+uint8_t state_85 = IDLE;
+const struct Chord chord_85 PROGMEM = {H_TOP5 + H_TOP6, NUM, &state_85, NULL, KC_RGUI, 0, one_shot_key};
+uint8_t state_86 = IDLE;
+const struct Chord chord_86 PROGMEM = {H_TOP7 + H_TOP8, NUM, &state_86, NULL, KC_INS, 0, single_dance};
+uint8_t state_87 = IDLE;
+const struct Chord chord_87 PROGMEM = {H_TOP8 + H_TOP9, NUM, &state_87, NULL, KC_DEL, 0, single_dance};
+uint8_t state_88 = IDLE;
+const struct Chord chord_88 PROGMEM = {H_TOP9 + H_TOP0, NUM, &state_88, NULL, KC_BSPC, 0, single_dance};
+uint8_t state_89 = IDLE;
+const struct Chord chord_89 PROGMEM = {H_TOP9 + H_TOP0 + H_BOT9 + H_BOT0, NUM, &state_89, NULL, KC_ENTER, 0, single_dance};
+uint8_t state_90 = IDLE;
+const struct Chord chord_90 PROGMEM = {H_BOT1 + H_BOT2, NUM, &state_90, NULL, KC_LSFT, 0, one_shot_key};
+uint8_t state_91 = IDLE;
+const struct Chord chord_91 PROGMEM = {H_BOT2 + H_BOT3, NUM, &state_91, NULL, KC_LCTL, 0, one_shot_key};
+uint8_t state_92 = IDLE;
+const struct Chord chord_92 PROGMEM = {H_BOT3 + H_BOT4, NUM, &state_92, NULL, KC_LALT, 0, one_shot_key};
+uint8_t state_93 = IDLE;
+const struct Chord chord_93 PROGMEM = {H_BOT5 + H_BOT6, NUM, &state_93, NULL, KC_LGUI, 0, one_shot_key};
+uint8_t state_94 = IDLE;
+const struct Chord chord_94 PROGMEM = {H_BOT7 + H_BOT8, NUM, &state_94, NULL, KC_RALT, 0, one_shot_key};
+uint8_t state_95 = IDLE;
+const struct Chord chord_95 PROGMEM = {H_BOT8 + H_BOT9, NUM, &state_95, NULL, KC_RCTL, 0, one_shot_key};
+uint8_t state_96 = IDLE;
+const struct Chord chord_96 PROGMEM = {H_BOT9 + H_BOT0, NUM, &state_96, NULL, KC_RSFT, 0, one_shot_key};
+uint8_t state_97 = IDLE;
+const struct Chord chord_97 PROGMEM = {H_BOT1 + H_BOT0, NUM, &state_97, NULL, KC_SPACE, 0, single_dance};
+uint8_t state_98 = IDLE;
+const struct Chord chord_98 PROGMEM = {H_TOP7, MOV, &state_98, NULL, KC_HOME, 0, single_dance};
+uint8_t state_99 = IDLE;
+const struct Chord chord_99 PROGMEM = {H_TOP8, MOV, &state_99, NULL, KC_UP, 0, single_dance};
+uint8_t state_100 = IDLE;
+const struct Chord chord_100 PROGMEM = {H_TOP9, MOV, &state_100, NULL, KC_END, 0, single_dance};
+uint8_t state_101 = IDLE;
+const struct Chord chord_101 PROGMEM = {H_TOP0, MOV, &state_101, NULL, KC_PGUP, 0, single_dance};
+uint8_t state_102 = IDLE;
+const struct Chord chord_102 PROGMEM = {H_BOT3, MOV, &state_102, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_103 = IDLE;
+const struct Chord chord_103 PROGMEM = {H_BOT4, MOV, &state_103, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_104 = IDLE;
+const struct Chord chord_104 PROGMEM = {H_BOT5, MOV, &state_104, NULL, KC_LALT, 0, single_dance};
+uint8_t state_105 = IDLE;
+const struct Chord chord_105 PROGMEM = {H_BOT6, MOV, &state_105, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_106 = IDLE;
+const struct Chord chord_106 PROGMEM = {H_BOT7, MOV, &state_106, NULL, KC_LEFT, 0, single_dance};
+uint8_t state_107 = IDLE;
+const struct Chord chord_107 PROGMEM = {H_BOT8, MOV, &state_107, NULL, KC_DOWN, 0, single_dance};
+uint8_t state_108 = IDLE;
+const struct Chord chord_108 PROGMEM = {H_BOT9, MOV, &state_108, NULL, KC_RIGHT, 0, single_dance};
+uint8_t state_109 = IDLE;
+const struct Chord chord_109 PROGMEM = {H_BOT0, MOV, &state_109, NULL, KC_PGDN, 0, single_dance};
+uint8_t state_110 = IDLE;
+const struct Chord chord_110 PROGMEM = {H_TOP7, MOUSE, &state_110, NULL, KC_BTN1, 0, single_dance};
+uint8_t state_111 = IDLE;
+const struct Chord chord_111 PROGMEM = {H_TOP8, MOUSE, &state_111, NULL, KC_MS_U, 0, single_dance};
+uint8_t state_112 = IDLE;
+const struct Chord chord_112 PROGMEM = {H_TOP9, MOUSE, &state_112, NULL, KC_BTN2, 0, single_dance};
+uint8_t state_113 = IDLE;
+const struct Chord chord_113 PROGMEM = {H_TOP0, MOUSE, &state_113, NULL, KC_WH_U, 0, single_dance};
+uint8_t state_114 = IDLE;
+const struct Chord chord_114 PROGMEM = {H_BOT3, MOUSE, &state_114, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_115 = IDLE;
+const struct Chord chord_115 PROGMEM = {H_BOT4, MOUSE, &state_115, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_116 = IDLE;
+const struct Chord chord_116 PROGMEM = {H_BOT5, MOUSE, &state_116, NULL, KC_LALT, 0, single_dance};
+uint8_t state_117 = IDLE;
+const struct Chord chord_117 PROGMEM = {H_BOT6, MOUSE, &state_117, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_118 = IDLE;
+const struct Chord chord_118 PROGMEM = {H_BOT7, MOUSE, &state_118, NULL, KC_MS_L, 0, single_dance};
+uint8_t state_119 = IDLE;
+const struct Chord chord_119 PROGMEM = {H_BOT8, MOUSE, &state_119, NULL, KC_MS_D, 0, single_dance};
+uint8_t state_120 = IDLE;
+const struct Chord chord_120 PROGMEM = {H_BOT9, MOUSE, &state_120, NULL, KC_MS_R, 0, single_dance};
+uint8_t state_121 = IDLE;
+const struct Chord chord_121 PROGMEM = {H_BOT0, MOUSE, &state_121, NULL, KC_WH_D, 0, single_dance};
+uint8_t state_122 = IDLE;
+const struct Chord chord_122 PROGMEM = {H_TOP1, ASETNIOP, &state_122, NULL, KC_A, 0, single_dance};
+uint8_t state_123 = IDLE;
+const struct Chord chord_123 PROGMEM = {H_TOP2, ASETNIOP, &state_123, NULL, KC_S, 0, single_dance};
+uint8_t state_124 = IDLE;
+const struct Chord chord_124 PROGMEM = {H_TOP3, ASETNIOP, &state_124, NULL, KC_E, 0, single_dance};
+uint8_t state_125 = IDLE;
+const struct Chord chord_125 PROGMEM = {H_TOP4, ASETNIOP, &state_125, NULL, KC_T, 0, single_dance};
+uint8_t state_126 = IDLE;
+const struct Chord chord_126 PROGMEM = {H_TOP7, ASETNIOP, &state_126, NULL, KC_N, 0, single_dance};
+uint8_t state_127 = IDLE;
+const struct Chord chord_127 PROGMEM = {H_TOP8, ASETNIOP, &state_127, NULL, KC_I, 0, single_dance};
+uint8_t state_128 = IDLE;
+const struct Chord chord_128 PROGMEM = {H_TOP9, ASETNIOP, &state_128, NULL, KC_O, 0, single_dance};
+uint8_t state_129 = IDLE;
+const struct Chord chord_129 PROGMEM = {H_TOP0, ASETNIOP, &state_129, NULL, KC_P, 0, single_dance};
+uint8_t state_130 = IDLE;
+const struct Chord chord_130 PROGMEM = {H_TOP1 + H_TOP2, ASETNIOP, &state_130, NULL, KC_W, 0, single_dance};
+uint8_t state_131 = IDLE;
+const struct Chord chord_131 PROGMEM = {H_TOP2 + H_TOP3, ASETNIOP, &state_131, NULL, KC_D, 0, single_dance};
+uint8_t state_132 = IDLE;
+const struct Chord chord_132 PROGMEM = {H_TOP3 + H_TOP4, ASETNIOP, &state_132, NULL, KC_R, 0, single_dance};
+uint8_t state_133 = IDLE;
+const struct Chord chord_133 PROGMEM = {H_TOP4 + H_TOP7, ASETNIOP, &state_133, NULL, KC_B, 0, single_dance};
+uint8_t state_134 = IDLE;
+const struct Chord chord_134 PROGMEM = {H_TOP7 + H_TOP8, ASETNIOP, &state_134, NULL, KC_H, 0, single_dance};
+uint8_t state_135 = IDLE;
+const struct Chord chord_135 PROGMEM = {H_TOP8 + H_TOP9, ASETNIOP, &state_135, NULL, KC_L, 0, single_dance};
+uint8_t state_136 = IDLE;
+const struct Chord chord_136 PROGMEM = {H_TOP9 + H_TOP0, ASETNIOP, &state_136, NULL, KC_SCOLON, 0, single_dance};
+uint8_t state_137 = IDLE;
+const struct Chord chord_137 PROGMEM = {H_TOP1 + H_TOP3, ASETNIOP, &state_137, NULL, KC_X, 0, single_dance};
+uint8_t state_138 = IDLE;
+const struct Chord chord_138 PROGMEM = {H_TOP2 + H_TOP4, ASETNIOP, &state_138, NULL, KC_C, 0, single_dance};
+uint8_t state_139 = IDLE;
+const struct Chord chord_139 PROGMEM = {H_TOP3 + H_TOP7, ASETNIOP, &state_139, NULL, KC_Y, 0, single_dance};
+uint8_t state_140 = IDLE;
+const struct Chord chord_140 PROGMEM = {H_TOP4 + H_TOP8, ASETNIOP, &state_140, NULL, KC_V, 0, single_dance};
+uint8_t state_141 = IDLE;
+const struct Chord chord_141 PROGMEM = {H_TOP7 + H_TOP9, ASETNIOP, &state_141, NULL, KC_U, 0, single_dance};
+uint8_t state_142 = IDLE;
+const struct Chord chord_142 PROGMEM = {H_TOP1 + H_TOP4, ASETNIOP, &state_142, NULL, KC_F, 0, single_dance};
+uint8_t state_143 = IDLE;
+const struct Chord chord_143 PROGMEM = {H_TOP2 + H_TOP7, ASETNIOP, &state_143, NULL, KC_J, 0, single_dance};
+uint8_t state_144 = IDLE;
+const struct Chord chord_144 PROGMEM = {H_TOP3 + H_TOP8, ASETNIOP, &state_144, NULL, KC_COMMA, 0, single_dance};
+uint8_t state_145 = IDLE;
+const struct Chord chord_145 PROGMEM = {H_TOP4 + H_TOP9, ASETNIOP, &state_145, NULL, KC_G, 0, single_dance};
+uint8_t state_146 = IDLE;
+const struct Chord chord_146 PROGMEM = {H_TOP7 + H_TOP0, ASETNIOP, &state_146, NULL, KC_M, 0, single_dance};
+uint8_t state_147 = IDLE;
+const struct Chord chord_147 PROGMEM = {H_TOP1 + H_TOP7, ASETNIOP, &state_147, NULL, KC_Q, 0, single_dance};
+uint8_t state_148 = IDLE;
+const struct Chord chord_148 PROGMEM = {H_TOP2 + H_TOP8, ASETNIOP, &state_148, NULL, KC_K, 0, single_dance};
+uint8_t state_149 = IDLE;
+const struct Chord chord_149 PROGMEM = {H_TOP3 + H_TOP9, ASETNIOP, &state_149, NULL, KC_MINUS, 0, single_dance};
+uint8_t state_150 = IDLE;
+const struct Chord chord_150 PROGMEM = {H_TOP4 + H_TOP0, ASETNIOP, &state_150, NULL, KC_BSPC, 0, single_dance};
+uint8_t state_151 = IDLE;
+const struct Chord chord_151 PROGMEM = {H_TOP1 + H_TOP8, ASETNIOP, &state_151, NULL, KC_Z, 0, single_dance};
+uint8_t state_152 = IDLE;
+const struct Chord chord_152 PROGMEM = {H_TOP2 + H_TOP9, ASETNIOP, &state_152, NULL, KC_DOT, 0, single_dance};
+uint8_t state_153 = IDLE;
+const struct Chord chord_153 PROGMEM = {H_TOP3 + H_TOP0, ASETNIOP, &state_153, NULL, KC_QUOTE, 0, single_dance};
+uint8_t state_154 = IDLE;
+const struct Chord chord_154 PROGMEM = {H_TOP1 + H_TOP9, ASETNIOP, &state_154, NULL, KC_LBRACKET, 0, single_dance};
+uint8_t state_155 = IDLE;
+const struct Chord chord_155 PROGMEM = {H_TOP2 + H_TOP0, ASETNIOP, &state_155, NULL, KC_RBRACKET, 0, single_dance};
+uint8_t state_156 = IDLE;
+const struct Chord chord_156 PROGMEM = {H_TOP1 + H_TOP0, ASETNIOP, &state_156, NULL, KC_SLASH, 0, single_dance};
+uint8_t state_157 = IDLE;
+const struct Chord chord_157 PROGMEM = {H_TOP5, ASETNIOP, &state_157, NULL, KC_ESC, 0, single_dance};
+uint8_t state_158 = IDLE;
+const struct Chord chord_158 PROGMEM = {H_TOP6, ASETNIOP, &state_158, NULL, KC_DEL, 0, single_dance};
+uint8_t state_159 = IDLE;
+const struct Chord chord_159 PROGMEM = {H_BOT4, ASETNIOP, &state_159, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_160 = IDLE;
+const struct Chord chord_160 PROGMEM = {H_BOT5, ASETNIOP, &state_160, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_161 = IDLE;
+const struct Chord chord_161 PROGMEM = {H_BOT6, ASETNIOP, &state_161, NULL, KC_LALT, 0, single_dance};
+uint8_t state_162 = IDLE;
+uint8_t counter_162 = 0;
+const struct Chord chord_162 PROGMEM = {H_BOT7, ASETNIOP, &state_162, &counter_162, KC_SPACE, ASETNIOP_123, key_layer_dance};
+uint8_t state_163 = IDLE;
+const struct Chord chord_163 PROGMEM = {H_TOP5 + H_TOP6, ASETNIOP, &state_163, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_164 = IDLE;
+const struct Chord chord_164 PROGMEM = {H_TOP1 + H_TOP2 + H_TOP3 + H_TOP4, ASETNIOP, &state_164, NULL, QWERTY, 0, perm_pseudolayer};
+uint8_t state_165 = IDLE;
+const struct Chord chord_165 PROGMEM = {H_BOT4 + H_BOT7, ASETNIOP, &state_165, NULL, ASETNIOP_FN, 0, temp_pseudolayer};
+uint8_t state_166 = IDLE;
+const struct Chord chord_166 PROGMEM = {H_TOP1, ASETNIOP_123, &state_166, NULL, KC_1, 0, single_dance};
+uint8_t state_167 = IDLE;
+const struct Chord chord_167 PROGMEM = {H_TOP2, ASETNIOP_123, &state_167, NULL, KC_2, 0, single_dance};
+uint8_t state_168 = IDLE;
+const struct Chord chord_168 PROGMEM = {H_TOP3, ASETNIOP_123, &state_168, NULL, KC_3, 0, single_dance};
+uint8_t state_169 = IDLE;
+const struct Chord chord_169 PROGMEM = {H_TOP4, ASETNIOP_123, &state_169, NULL, KC_4, 0, single_dance};
+uint8_t state_170 = IDLE;
+const struct Chord chord_170 PROGMEM = {H_TOP7, ASETNIOP_123, &state_170, NULL, KC_7, 0, single_dance};
+uint8_t state_171 = IDLE;
+const struct Chord chord_171 PROGMEM = {H_TOP8, ASETNIOP_123, &state_171, NULL, KC_8, 0, single_dance};
+uint8_t state_172 = IDLE;
+const struct Chord chord_172 PROGMEM = {H_TOP9, ASETNIOP_123, &state_172, NULL, KC_9, 0, single_dance};
+uint8_t state_173 = IDLE;
+const struct Chord chord_173 PROGMEM = {H_TOP0, ASETNIOP_123, &state_173, NULL, KC_0, 0, single_dance};
+uint8_t state_174 = IDLE;
+const struct Chord chord_174 PROGMEM = {H_TOP3 + H_TOP4, ASETNIOP_123, &state_174, NULL, KC_5, 0, single_dance};
+uint8_t state_175 = IDLE;
+const struct Chord chord_175 PROGMEM = {H_TOP4 + H_TOP7, ASETNIOP_123, &state_175, NULL, KC_EQUAL, 0, single_dance};
+uint8_t state_176 = IDLE;
+const struct Chord chord_176 PROGMEM = {H_TOP7 + H_TOP8, ASETNIOP_123, &state_176, NULL, KC_6, 0, single_dance};
+uint8_t state_177 = IDLE;
+const struct Chord chord_177 PROGMEM = {H_TOP8 + H_TOP9, ASETNIOP_123, &state_177, NULL, KC_BSLASH, 0, single_dance};
+uint8_t state_178 = IDLE;
+const struct Chord chord_178 PROGMEM = {H_TOP9 + H_TOP0, ASETNIOP_123, &state_178, NULL, KC_SCOLON, 0, single_dance};
+uint8_t state_179 = IDLE;
+const struct Chord chord_179 PROGMEM = {H_TOP4 + H_TOP0, ASETNIOP_123, &state_179, NULL, KC_BSPC, 0, single_dance};
+uint8_t state_180 = IDLE;
+const struct Chord chord_180 PROGMEM = {H_TOP5, ASETNIOP_123, &state_180, NULL, KC_ESC, 0, single_dance};
+uint8_t state_181 = IDLE;
+const struct Chord chord_181 PROGMEM = {H_TOP6, ASETNIOP_123, &state_181, NULL, KC_DEL, 0, single_dance};
+uint8_t state_182 = IDLE;
+const struct Chord chord_182 PROGMEM = {H_BOT4, ASETNIOP_123, &state_182, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_183 = IDLE;
+const struct Chord chord_183 PROGMEM = {H_BOT5, ASETNIOP_123, &state_183, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_184 = IDLE;
+const struct Chord chord_184 PROGMEM = {H_BOT6, ASETNIOP_123, &state_184, NULL, KC_LALT, 0, single_dance};
+uint8_t state_185 = IDLE;
+const struct Chord chord_185 PROGMEM = {H_TOP5 + H_TOP6, ASETNIOP_123, &state_185, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_186 = IDLE;
+const struct Chord chord_186 PROGMEM = {H_TOP1, ASETNIOP_FN, &state_186, NULL, KC_HOME, 0, single_dance};
+uint8_t state_187 = IDLE;
+const struct Chord chord_187 PROGMEM = {H_TOP2, ASETNIOP_FN, &state_187, NULL, KC_PGDN, 0, single_dance};
+uint8_t state_188 = IDLE;
+const struct Chord chord_188 PROGMEM = {H_TOP3, ASETNIOP_FN, &state_188, NULL, KC_PGUP, 0, single_dance};
+uint8_t state_189 = IDLE;
+const struct Chord chord_189 PROGMEM = {H_TOP4, ASETNIOP_FN, &state_189, NULL, KC_END, 0, single_dance};
+uint8_t state_190 = IDLE;
+const struct Chord chord_190 PROGMEM = {H_TOP7, ASETNIOP_FN, &state_190, NULL, KC_LEFT, 0, single_dance};
+uint8_t state_191 = IDLE;
+const struct Chord chord_191 PROGMEM = {H_TOP8, ASETNIOP_FN, &state_191, NULL, KC_DOWN, 0, single_dance};
+uint8_t state_192 = IDLE;
+const struct Chord chord_192 PROGMEM = {H_TOP9, ASETNIOP_FN, &state_192, NULL, KC_UP, 0, single_dance};
+uint8_t state_193 = IDLE;
+const struct Chord chord_193 PROGMEM = {H_TOP0, ASETNIOP_FN, &state_193, NULL, KC_RIGHT, 0, single_dance};
+uint8_t state_194 = IDLE;
+const struct Chord chord_194 PROGMEM = {H_TOP1 + H_TOP2, ASETNIOP_FN, &state_194, NULL, KC_F1, 0, single_dance};
+uint8_t state_195 = IDLE;
+const struct Chord chord_195 PROGMEM = {H_TOP2 + H_TOP3, ASETNIOP_FN, &state_195, NULL, KC_F2, 0, single_dance};
+uint8_t state_196 = IDLE;
+const struct Chord chord_196 PROGMEM = {H_TOP3 + H_TOP4, ASETNIOP_FN, &state_196, NULL, KC_F3, 0, single_dance};
+uint8_t state_197 = IDLE;
+const struct Chord chord_197 PROGMEM = {H_TOP4 + H_TOP7, ASETNIOP_FN, &state_197, NULL, KC_F4, 0, single_dance};
+uint8_t state_198 = IDLE;
+const struct Chord chord_198 PROGMEM = {H_TOP7 + H_TOP8, ASETNIOP_FN, &state_198, NULL, KC_F5, 0, single_dance};
+uint8_t state_199 = IDLE;
+const struct Chord chord_199 PROGMEM = {H_TOP8 + H_TOP9, ASETNIOP_FN, &state_199, NULL, KC_F6, 0, single_dance};
+uint8_t state_200 = IDLE;
+const struct Chord chord_200 PROGMEM = {H_TOP9 + H_TOP0, ASETNIOP_FN, &state_200, NULL, KC_F7, 0, single_dance};
+uint8_t state_201 = IDLE;
+const struct Chord chord_201 PROGMEM = {H_TOP1 + H_TOP3, ASETNIOP_FN, &state_201, NULL, KC_F10, 0, single_dance};
+uint8_t state_202 = IDLE;
+const struct Chord chord_202 PROGMEM = {H_TOP8 + H_TOP0, ASETNIOP_FN, &state_202, NULL, KC_F8, 0, single_dance};
+uint8_t state_203 = IDLE;
+const struct Chord chord_203 PROGMEM = {H_TOP1 + H_TOP4, ASETNIOP_FN, &state_203, NULL, KC_F11, 0, single_dance};
+uint8_t state_204 = IDLE;
+const struct Chord chord_204 PROGMEM = {H_TOP7 + H_TOP0, ASETNIOP_FN, &state_204, NULL, KC_F9, 0, single_dance};
+uint8_t state_205 = IDLE;
+const struct Chord chord_205 PROGMEM = {H_TOP1 + H_TOP7, ASETNIOP_FN, &state_205, NULL, KC_F12, 0, single_dance};
+uint8_t state_206 = IDLE;
+const struct Chord chord_206 PROGMEM = {H_TOP4 + H_TOP0, ASETNIOP_FN, &state_206, NULL, KC_BSPC, 0, single_dance};
+uint8_t state_207 = IDLE;
+const struct Chord chord_207 PROGMEM = {H_TOP5, ASETNIOP_FN, &state_207, NULL, KC_ESC, 0, single_dance};
+uint8_t state_208 = IDLE;
+const struct Chord chord_208 PROGMEM = {H_TOP6, ASETNIOP_FN, &state_208, NULL, KC_DEL, 0, single_dance};
+uint8_t state_209 = IDLE;
+const struct Chord chord_209 PROGMEM = {H_BOT4, ASETNIOP_FN, &state_209, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_210 = IDLE;
+const struct Chord chord_210 PROGMEM = {H_BOT5, ASETNIOP_FN, &state_210, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_211 = IDLE;
+const struct Chord chord_211 PROGMEM = {H_BOT6, ASETNIOP_FN, &state_211, NULL, KC_LALT, 0, single_dance};
+uint8_t state_212 = IDLE;
+const struct Chord chord_212 PROGMEM = {H_TOP5 + H_TOP6, ASETNIOP_FN, &state_212, NULL, KC_LGUI, 0, single_dance};
+
+const struct Chord* const list_of_chords[] PROGMEM = {
+ &chord_0, &chord_1, &chord_2, &chord_3, &chord_4, &chord_5, &chord_6, &chord_7, &chord_8, &chord_9, &chord_10, &chord_11, &chord_12, &chord_13, &chord_14, &chord_15, &chord_16, &chord_17, &chord_18, &chord_19, &chord_20, &chord_21, &chord_22, &chord_23, &chord_24, &chord_25, &chord_26, &chord_27, &chord_28, &chord_29, &chord_30, &chord_31, &chord_32, &chord_33, &chord_34, &chord_35, &chord_36, &chord_37, &chord_38, &chord_39, &chord_40, &chord_41, &chord_42, &chord_43, &chord_44, &chord_45, &chord_46, &chord_47, &chord_48, &chord_49, &chord_50, &chord_51, &chord_52, &chord_53, &chord_54, &chord_55, &chord_56, &chord_57, &chord_58, &chord_59, &chord_60, &chord_61, &chord_62, &chord_63, &chord_64, &chord_65, &chord_66, &chord_67, &chord_68, &chord_69, &chord_70, &chord_71, &chord_72, &chord_73, &chord_74, &chord_75, &chord_76, &chord_77, &chord_78, &chord_79, &chord_80, &chord_81, &chord_82, &chord_83, &chord_84, &chord_85, &chord_86, &chord_87, &chord_88, &chord_89, &chord_90, &chord_91, &chord_92, &chord_93, &chord_94, &chord_95, &chord_96, &chord_97, &chord_98, &chord_99, &chord_100, &chord_101, &chord_102, &chord_103, &chord_104, &chord_105, &chord_106, &chord_107, &chord_108, &chord_109, &chord_110, &chord_111, &chord_112, &chord_113, &chord_114, &chord_115, &chord_116, &chord_117, &chord_118, &chord_119, &chord_120, &chord_121, &chord_122, &chord_123, &chord_124, &chord_125, &chord_126, &chord_127, &chord_128, &chord_129, &chord_130, &chord_131, &chord_132, &chord_133, &chord_134, &chord_135, &chord_136, &chord_137, &chord_138, &chord_139, &chord_140, &chord_141, &chord_142, &chord_143, &chord_144, &chord_145, &chord_146, &chord_147, &chord_148, &chord_149, &chord_150, &chord_151, &chord_152, &chord_153, &chord_154, &chord_155, &chord_156, &chord_157, &chord_158, &chord_159, &chord_160, &chord_161, &chord_162, &chord_163, &chord_164, &chord_165, &chord_166, &chord_167, &chord_168, &chord_169, &chord_170, &chord_171, &chord_172, &chord_173, &chord_174, &chord_175, &chord_176, &chord_177, &chord_178, &chord_179, &chord_180, &chord_181, &chord_182, &chord_183, &chord_184, &chord_185, &chord_186, &chord_187, &chord_188, &chord_189, &chord_190, &chord_191, &chord_192, &chord_193, &chord_194, &chord_195, &chord_196, &chord_197, &chord_198, &chord_199, &chord_200, &chord_201, &chord_202, &chord_203, &chord_204, &chord_205, &chord_206, &chord_207, &chord_208, &chord_209, &chord_210, &chord_211, &chord_212
+};
+
+const uint16_t** const leader_triggers PROGMEM = NULL;
+void (*leader_functions[]) (void) = {};
+
+#define NUMBER_OF_CHORDS 213
+#define NUMBER_OF_LEADER_COMBOS 0
+
+bool are_hashed_keycodes_in_sound(HASH_TYPE keycodes_hash, HASH_TYPE sound) {
+ return (keycodes_hash & sound) == keycodes_hash;
+}
+
+uint8_t keycode_to_index(uint16_t keycode) {
+ return keycode - FIRST_INTERNAL_KEYCODE;
+}
+
+void sound_keycode_array(uint16_t keycode) {
+ uint8_t index = keycode_to_index(keycode);
+ keycode_index++;
+ keycodes_buffer_array[index] = keycode_index;
+}
+
+void silence_keycode_hash_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ if (index_in_hash) {
+ uint8_t current_val = keycodes_buffer_array[i];
+ keycodes_buffer_array[i] = 0;
+ for (int j = 0; j < NUMBER_OF_KEYS; j++) {
+ if (keycodes_buffer_array[j] > current_val) {
+ keycodes_buffer_array[j]--;
+ }
+ }
+ keycode_index--;
+ }
+ }
+}
+
+bool are_hashed_keycodes_in_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ bool index_in_array = (bool) keycodes_buffer_array[i];
+ if (index_in_hash && !index_in_array) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void kill_one_shots(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == IN_ONE_SHOT) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ }
+}
+
+void process_finished_dances(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == ACTIVATED) {
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ } else if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = FINISHED;
+ chord->function(chord);
+ if (*chord->state == FINISHED) {
+ *chord->state = RESTART;
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ } else if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = FINISHED_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ }
+ }
+}
+
+uint8_t keycodes_buffer_array_min(uint8_t* first_keycode_index) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ if (keycodes_buffer_array[i] == 1) {
+ if (first_keycode_index != NULL) {
+ *first_keycode_index = (uint8_t) i;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void remove_subchords(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (!(*chord->state == READY || *chord->state == READY_IN_DANCE || *chord->state == READY_LOCKED)) {
+ continue;
+ }
+
+ struct Chord chord_storage_2;
+ struct Chord* chord_ptr_2;
+ struct Chord* chord_2;
+ for (int j = 0; j < NUMBER_OF_CHORDS; j++) {
+ if (i == j) {continue;}
+
+ chord_ptr_2 = (struct Chord*) pgm_read_word (&list_of_chords[j]);
+ memcpy_P(&chord_storage_2, chord_ptr_2, sizeof(struct Chord));
+ chord_2 = &chord_storage_2;
+
+ if (are_hashed_keycodes_in_sound(chord_2->keycodes_hash, chord->keycodes_hash)) {
+ if (*chord_2->state == READY) {
+ *chord_2->state = IDLE;
+ }
+ if (*chord_2->state == READY_IN_DANCE) {
+ *chord_2->state = IDLE_IN_DANCE;
+ }
+ if (*chord_2->state == READY_LOCKED) {
+ *chord_2->state = LOCKED;
+ }
+ }
+ }
+ }
+}
+
+void process_ready_chords(void) {
+ uint8_t first_keycode_index = 0;
+ while (keycodes_buffer_array_min(&first_keycode_index)) {
+ // find ready chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ // if the chord does not contain the first keycode
+ bool contains_first_keycode = ((uint32_t) 1 << first_keycode_index) & chord->keycodes_hash;
+ if (!contains_first_keycode) {
+ continue;
+ }
+
+ if (!are_hashed_keycodes_in_array(chord->keycodes_hash)){
+ continue;
+ }
+
+ if (*chord->state == LOCKED) {
+ *chord->state = READY_LOCKED;
+ continue;
+ }
+
+ if (!(chord->pseudolayer == current_pseudolayer || chord->pseudolayer == ALWAYS_ON)) {
+ continue;
+ }
+
+ if (*chord->state == IDLE) {
+ *chord->state = READY;
+ continue;
+ }
+
+ if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = READY_IN_DANCE;
+ }
+ }
+
+ // remove subchords
+ remove_subchords();
+
+ // execute logic
+ // this should be only one chord
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == READY_LOCKED) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ break;
+ }
+
+ if (*chord->state == READY || *chord->state == READY_IN_DANCE) {
+ if (last_chord && last_chord != chord) {
+ process_finished_dances();
+ }
+
+ bool lock_next_prev_state = lock_next;
+
+ *chord->state = ACTIVATED;
+ chord->function(chord);
+ dance_timer = timer_read();
+
+ if (lock_next && lock_next == lock_next_prev_state) {
+ lock_next = false;
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = LOCKED;
+ }
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ }
+ break;
+ }
+ }
+
+ // silence notes
+ silence_keycode_hash_array(chord->keycodes_hash);
+ }
+}
+
+void deactivate_active_chords(uint16_t keycode) {
+ HASH_TYPE hash = (HASH_TYPE)1 << (keycode - SAFE_RANGE);
+ bool broken;
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ broken = are_hashed_keycodes_in_sound(hash, chord->keycodes_hash);
+ if (!broken) {
+ continue;
+ }
+
+ switch (*chord->state) {
+ case ACTIVATED:
+ *chord->state = DEACTIVATED;
+ chord->function(chord);
+
+ if (*chord->state == DEACTIVATED) {
+ dance_timer = timer_read();
+ *chord->state = IDLE_IN_DANCE;
+ }
+ if (*chord->state != IN_ONE_SHOT) {
+ kill_one_shots();
+ }
+ break;
+ case PRESS_FROM_ACTIVE:
+ case FINISHED_FROM_ACTIVE:
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ kill_one_shots();
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+void process_command(void) {
+ command_mode = 0;
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ register_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ wait_ms(TAP_TIMEOUT);
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ unregister_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ command_buffer[i] = 0;
+ }
+ command_ind = 0;
+}
+
+void process_leader(void) {
+ in_leader_mode = false;
+ for (int i = 0; i < NUMBER_OF_LEADER_COMBOS; i++) {
+ uint16_t trigger[LEADER_MAX_LENGTH];
+ memcpy_P(trigger, leader_triggers[i], LEADER_MAX_LENGTH * sizeof(uint16_t));
+
+ if (identical(leader_buffer, trigger)) {
+ (*leader_functions[i])();
+ break;
+ }
+ }
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ leader_buffer[i] = 0;
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if (keycode < FIRST_INTERNAL_KEYCODE || keycode > LAST_INTERNAL_KEYCODE) {
+ return true;
+ }
+
+ if (record->event.pressed) {
+ sound_keycode_array(keycode);
+ } else {
+ process_ready_chords();
+ deactivate_active_chords(keycode);
+ }
+ chord_timer = timer_read();
+ leader_timer = timer_read();
+
+ return false;
+}
+
+void matrix_scan_user(void) {
+ bool chord_timer_expired = timer_elapsed(chord_timer) > CHORD_TIMEOUT;
+ if (chord_timer_expired && keycodes_buffer_array_min(NULL)) {
+ process_ready_chords();
+ }
+
+ bool dance_timer_expired = timer_elapsed(dance_timer) > DANCE_TIMEOUT;
+ if (dance_timer_expired) { // would love to have && in_dance but not sure how
+ process_finished_dances();
+ }
+
+ bool in_command_mode = command_mode == 2;
+ if (in_command_mode) {
+ process_command();
+ }
+
+ bool leader_timer_expired = timer_elapsed(leader_timer) > LEADER_TIMEOUT;
+ if (leader_timer_expired && in_leader_mode) {
+ process_leader();
+ }
+
+}
+
+void clear(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ // kill all chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ *chord->state = IDLE;
+
+ if (chord->counter) {
+ *chord->counter = 0;
+ }
+ }
+
+ // clear keyboard
+ clear_keyboard();
+ send_keyboard_report();
+
+ // switch to default pseudolayer
+ current_pseudolayer = DEFAULT_PSEUDOLAYER;
+
+ // clear all keyboard states
+ lock_next = false;
+ autoshift_mode = true;
+ command_mode = 0;
+ in_leader_mode = false;
+ leader_ind = 0;
+ dynamic_macro_mode = false;
+ a_key_went_through = false;
+
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ }
+} \ No newline at end of file
diff --git a/keyboards/butterstick/keymaps/dennytom/keymap_def.json b/keyboards/butterstick/keymaps/dennytom/keymap_def.json
new file mode 100644
index 000000000..16f02ca52
--- /dev/null
+++ b/keyboards/butterstick/keymaps/dennytom/keymap_def.json
@@ -0,0 +1,309 @@
+{
+ "keys": [
+ "TOP1", "TOP2", "TOP3", "TOP4", "TOP5", "TOP6", "TOP7", "TOP8", "TOP9", "TOP0",
+ "BOT1", "BOT2", "BOT3", "BOT4", "BOT5", "BOT6", "BOT7", "BOT8", "BOT9", "BOT0"
+ ],
+ "parameters": {
+ "layout_function_name": "LAYOUT_butter",
+ "chord_timeout": 100,
+ "dance_timeout": 200,
+ "leader_timeout": 750,
+ "tap_timeout": 50,
+ "command_max_length": 5,
+ "leader_max_length": 5,
+ "dynamic_macro_max_length": 20,
+ "string_max_length": 16,
+ "long_press_multiplier": 3,
+ "default_pseudolayer": "QWERTY"
+ },
+ "layers": [
+ {
+ "type": "auto"
+ }
+ ],
+ "chord_sets": [
+ {
+ "name": "rows",
+ "chords": [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP5"], ["TOP6"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP0"],
+ ["TOP1", "BOT1"], ["TOP2", "BOT2"], ["TOP3", "BOT3"], ["TOP4", "BOT4"], ["TOP5", "BOT5"], ["TOP6", "BOT6"], ["TOP7", "BOT7"], ["TOP8", "BOT8"], ["TOP9", "BOT9"], ["TOP0", "BOT0"],
+ ["BOT1"], ["BOT2"], ["BOT3"], ["BOT4"], ["BOT5"], ["BOT6"], ["BOT7"], ["BOT8"], ["BOT9"], ["BOT0"]
+ ]
+ },
+ {
+ "name": "cols",
+ "chords": [
+ ["TOP1", "TOP2"], ["TOP2", "TOP3"], ["TOP3", "TOP4"], ["TOP4", "TOP5"], ["TOP5", "TOP6"], ["TOP6", "TOP7"], ["TOP7", "TOP8"], ["TOP8", "TOP9"], ["TOP9", "TOP0"],
+ ["TOP1", "TOP2", "BOT1", "BOT2"], ["TOP2", "TOP3", "BOT2", "BOT3"], ["TOP3", "TOP4", "BOT3", "BOT4"], ["TOP4", "TOP5", "BOT4", "BOT5"], ["TOP5", "TOP6", "BOT5", "BOT6"], ["TOP6", "TOP7", "BOT6", "BOT7"], ["TOP7", "TOP8", "BOT7", "BOT8"], ["TOP8", "TOP9", "BOT8", "BOT9"], ["TOP9", "TOP0", "BOT9", "BOT0"],
+ ["BOT1", "BOT2"], ["BOT2", "BOT3"], ["BOT3", "BOT4"], ["BOT4", "BOT5"], ["BOT5", "BOT6"], ["BOT6", "BOT7"], ["BOT7", "BOT8"], ["BOT8", "BOT9"], ["BOT9", "BOT0"]
+ ]
+ },
+ {
+ "name": "asetniop",
+ "chords": [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP0"],
+ ["TOP1", "TOP2"], ["TOP2", "TOP3"], ["TOP3", "TOP4"], ["TOP4", "TOP7"], ["TOP7", "TOP8"], ["TOP8", "TOP9"], ["TOP9", "TOP0"],
+ ["TOP1", "TOP3"], ["TOP2", "TOP4"], ["TOP3", "TOP7"], ["TOP4", "TOP8"], ["TOP7", "TOP9"], ["TOP8", "TOP0"],
+ ["TOP1", "TOP4"], ["TOP2", "TOP7"], ["TOP3", "TOP8"], ["TOP4", "TOP9"], ["TOP7", "TOP0"],
+ ["TOP1", "TOP7"], ["TOP2", "TOP8"], ["TOP3", "TOP9"], ["TOP4", "TOP0"],
+ ["TOP1", "TOP8"], ["TOP2", "TOP9"], ["TOP3", "TOP0"],
+ ["TOP1", "TOP9"], ["TOP2", "TOP0"],
+ ["TOP1", "TOP0"]
+ ]
+ }
+ ],
+ "pseudolayers": [
+ {
+ "name": "ALWAYS_ON",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ "LOCK", " AT", " ", " ", " CMD", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ]
+ },
+ {
+ "type": "visual",
+ "chord": [
+ "X", "X", " ", " ", " ", " ", " ", " ", "X", "X",
+ "X", "X", " ", " ", " ", " ", " ", " ", "X", "X"
+ ],
+ "keycode": "CLEAR_KB"
+ }
+ ]
+ },
+ {
+ "name": "QWERTY",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "AS(Q)", "AS(W)", "AS(E)", "AS(R)", "AS(T)", "AS(Y)", "AS(U)", "AS(I)", "AS(O)", "AS(P)",
+ "AS(A)", "AS(S)", "AS(D)", "AS(F)", "AS(G)", "AS(H)", "AS(J)", "AS(K)", "AS(L)", "AS(;)",
+ "AS(Z)", "AS(X)", "AS(C)", "AS(V)", "AS(B)", "AS(N)", "AS(M)", "AS(,)", "AS(.)", "AS(/)"
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ESC", "MO(MOV)", " TAB", " ", "O(RGUI)", " ", " INS", " DEL", " BSPC",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ENTER",
+ "O(LSFT)", "O(LCTL)", "O(LALT)", "O(NUM)", "O(LGUI)", "O(NUM)", "O(RALT)", "O(RCTL)", "O(RSFT)"
+ ]
+ },
+ {
+ "type": "simple",
+ "chord": ["BOT1", "BOT0"],
+ "keycode": "SPACE"
+ },
+ {
+ "type": "visual",
+ "chord": [
+ "X", "X", "X", "X", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "MO(MOUSE)"
+ },
+ {
+ "type": "visual",
+ "chord": [
+ "X", "X", "X", "X", " ", " ", "X", "X", "X", "X",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "DF(ASETNIOP)"
+ }
+ ]
+ },
+ {
+ "name": "NUM",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "AS(1)", "AS(2)", "AS(3)", "AS(4)", "AS(5)", "AS(6)", "AS(7)", "AS(8)", "AS(9)", "AS(0)",
+ " F1", " F2", " F3", " F4", " F5", " F6", " F7", " F8", " F9", " F10",
+ "AS(`)", "AS(-)", "AS(=)", "AS([)", "AS(])", "AS(\\)", "AS(')", " ", " F11", " F12"
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ESC", " ", " TAB", " ", "O(RGUI)", " ", " INS", " DEL", " BSPC",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ENTER",
+ "O(LSFT)", "O(LCTL)", "O(LALT)", " ", "O(LGUI)", " ", "O(RALT)", "O(RCTL)", " O(RSFT)"
+ ]
+ },
+ {
+ "type": "simple",
+ "chord": ["BOT1", "BOT0"],
+ "keycode": "SPACE"
+ }
+ ]
+ },
+ {
+ "name": "MOV",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ", " ", " HOME", " UP", " END", " PGUP",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " LSFT", " LCTL", " LALT", " LGUI", " LEFT", " DOWN", "RIGHT", " PGDN"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "MOUSE",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ", " ", " BTN1", " MS_U", " BTN2", " WH_U",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " LSFT", " LCTL", " LALT", " LGUI", " MS_L", " MS_D", " MS_R", " WH_D"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ASETNIOP",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "asetniop",
+ "keycodes": [
+ "A", "S", "E", "T", "N", "I", "O", "P",
+ "W", "D", "R", "B", "H", "L", ";",
+ "X", "C", "Y", "V", "U", "",
+ "F", "J", ",", "G", "M",
+ "Q", "K", "-", "BSPC",
+ "Z", ".", "'",
+ "[", "]",
+ "/"
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ESC", " DEL", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", "LSFT", "LCTL", "LALT", "KL(SPACE, ASETNIOP_123)", "", "", ""
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ", " ", " ", " ", "LGUI", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ]
+ },
+ {
+ "type": "visual",
+ "chord": [
+ "X", "X", "X", "X", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "DF(QWERTY)"
+ },
+ {
+ "type": "visual",
+ "chord": [
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", "X", " ", " ", "X", " ", " ", " "
+ ],
+ "keycode": "MO(ASETNIOP_FN)"
+ }
+ ]
+ },
+ {
+ "name": "ASETNIOP_123",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "asetniop",
+ "keycodes": [
+ "1", "2", "3", "4", "7", "8", "9", "0",
+ " ", " ", "5", "=", "6", "\\", ";",
+ " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ",
+ " ", " ", " ", "BSPC",
+ " ", " ", " ",
+ " ", " ",
+ " "
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ESC", " DEL", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", "LSFT", "LCTL", "LALT", " ", " ", " ", " "
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ", " ", " ", " ", "LGUI", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ },
+ {
+ "name": "ASETNIOP_FN",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "asetniop",
+ "keycodes": [
+ "HOME", "PGDN", "PGUP", " END", "LEFT", "DOWN", " UP", "RIGHT",
+ " F1", " F2", " F3", " F4", " F5", " F6", " F7",
+ " F10", " ", " ", " ", " ", " F8",
+ " F11", " ", " ", " ", " F9",
+ " F12", " ", " ", "BSPC",
+ " ", " ", " ",
+ " ", " ",
+ " "
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ESC", " DEL", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", "LSFT", "LCTL", "LALT", " ", " ", " ", " "
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ " ", " ", " ", " ", "LGUI", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ }
+ ],
+ "leader_sequences": [],
+ "extra_code": "",
+ "extra_dependencies": []
+} \ No newline at end of file
diff --git a/keyboards/butterstick/keymaps/dennytom/rules.mk b/keyboards/butterstick/keymaps/dennytom/rules.mk
new file mode 100644
index 000000000..1155f72c0
--- /dev/null
+++ b/keyboards/butterstick/keymaps/dennytom/rules.mk
@@ -0,0 +1,8 @@
+MOUSEKEY_ENABLE = yes
+EXTRAKEY_ENABLE = yes
+CONSOLE_ENABLE = no
+# COMMAND_ENABLE = no
+NKRO_ENABLE = yes
+
+TMPVAR := $(SRC)
+SRC = $(filter-out sten.c, $(TMPVAR)) \ No newline at end of file
diff --git a/keyboards/cannonkeys/atlas/atlas.c b/keyboards/cannonkeys/atlas/atlas.c
new file mode 100644
index 000000000..8b0b236fe
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/atlas.c
@@ -0,0 +1 @@
+#include "atlas.h"
diff --git a/keyboards/cannonkeys/atlas/atlas.h b/keyboards/cannonkeys/atlas/atlas.h
new file mode 100644
index 000000000..b2f64dab7
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/atlas.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT_ortho_5x12_1x2uC( \
+ 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 , k47, k48, k49, k4a, k4b \
+) \
+{ \
+ { 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, KC_NO, k47, k48, k49, k4a, k4b }, \
+}
+
+#define LAYOUT_ortho_5x12( \
+ 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 \
+) \
+{ \
+ { 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 }, \
+}
+
+#define LAYOUT_ortho_5x12_2x2uC( \
+ 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, k46 , k48, k49, k4a, k4b \
+) \
+{ \
+ { 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, KC_NO, k46, KC_NO, k48, k49, k4a, k4b }, \
+}
diff --git a/keyboards/cannonkeys/atlas/chconf.h b/keyboards/cannonkeys/atlas/chconf.h
new file mode 100644
index 000000000..03f63da36
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/chconf.h
@@ -0,0 +1,714 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file rt/templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_6_0_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_ST_RESOLUTION)
+#define CH_CFG_ST_RESOLUTION 32
+#endif
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_CFG_ST_FREQUENCY)
+#define CH_CFG_ST_FREQUENCY 10000
+#endif
+
+/**
+ * @brief Time intervals data size.
+ * @note Allowed values are 16, 32 or 64 bits.
+ */
+#if !defined(CH_CFG_INTERVALS_SIZE)
+#define CH_CFG_INTERVALS_SIZE 32
+#endif
+
+/**
+ * @brief Time types data size.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_TIME_TYPES_SIZE)
+#define CH_CFG_TIME_TYPES_SIZE 32
+#endif
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#if !defined(CH_CFG_ST_TIMEDELTA)
+#define CH_CFG_ST_TIMEDELTA 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#if !defined(CH_CFG_TIME_QUANTUM)
+#define CH_CFG_TIME_QUANTUM 0
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#if !defined(CH_CFG_MEMCORE_SIZE)
+#define CH_CFG_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#if !defined(CH_CFG_NO_IDLE_THREAD)
+#define CH_CFG_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_OPTIMIZE_SPEED)
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_TM)
+#define CH_CFG_USE_TM FALSE
+#endif
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_REGISTRY)
+#define CH_CFG_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_WAITEXIT)
+#define CH_CFG_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES)
+#define CH_CFG_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MUTEXES)
+#define CH_CFG_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_CONDVARS)
+#define CH_CFG_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_EVENTS)
+#define CH_CFG_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MESSAGES)
+#define CH_CFG_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
+#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_MAILBOXES)
+#define CH_CFG_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMCORE)
+#define CH_CFG_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_CFG_USE_HEAP)
+#define CH_CFG_USE_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#define CH_CFG_USE_MEMPOOLS FALSE
+#endif
+
+/**
+ * @brief Objects FIFOs APIs.
+ * @details If enabled then the objects FIFOs APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#define CH_CFG_USE_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Pipes APIs.
+ * @details If enabled then the pipes APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_PIPES)
+#define CH_CFG_USE_PIPES FALSE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#if !defined(CH_CFG_USE_DYNAMIC)
+#define CH_CFG_USE_DYNAMIC FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Objects factory options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Objects Factory APIs.
+ * @details If enabled then the objects factory APIs are included in the
+ * kernel.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_CFG_USE_FACTORY)
+#define CH_CFG_USE_FACTORY FALSE
+#endif
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
+#endif
+
+/**
+ * @brief Enables the registry of generic objects.
+ */
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
+#endif
+
+/**
+ * @brief Enables factory for generic buffers.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#define CH_CFG_FACTORY_SEMAPHORES FALSE
+#endif
+
+/**
+ * @brief Enables factory for mailboxes.
+ */
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#define CH_CFG_FACTORY_MAILBOXES FALSE
+#endif
+
+/**
+ * @brief Enables factory for objects FIFOs.
+ */
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Enables factory for Pipes.
+ */
+#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_PIPES FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_STATISTICS)
+#define CH_DBG_STATISTICS FALSE
+#endif
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_MASK)
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+#endif
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING)
+#define CH_DBG_THREADS_PROFILING FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System structure extension.
+ * @details User fields added to the end of the @p ch_system_t structure.
+ */
+#define CH_CFG_SYSTEM_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief System initialization hook.
+ * @details User initialization code added to the @p chSysInit() function
+ * just before interrupts are enabled globally.
+ */
+#define CH_CFG_SYSTEM_INIT_HOOK() { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p _thread_init() function.
+ *
+ * @note It is invoked from within @p _thread_init() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/atlas/config.h b/keyboards/cannonkeys/atlas/config.h
new file mode 100644
index 000000000..6cd1d1b6e
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/config.h
@@ -0,0 +1,71 @@
+/*
+Copyright 2015 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/>.
+*/
+
+#pragma once
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCA04
+#define PRODUCT_ID 0xA7A5
+#define DEVICE_VER 0x0001
+#define MANUFACTURER CannonKeys
+#define PRODUCT Atlas
+#define DESCRIPTION Atlas Keyboard
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 12
+
+#define MATRIX_COL_PINS { A9, A10, A15, B9, C13, C14, C15, F0, F1, A0, A1, A2 }
+#define MATRIX_ROW_PINS { A8, B14, B12, B4, B3 }
+#define DIODE_DIRECTION COL2ROW
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 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
+
+#define RGBLIGHT_ANIMATIONS
+
+
+#define WS2812_SPI SPID2
+#define RGB_DI_PIN B15
+#define RGBLED_NUM 22
+#define WS2812_SPI_MOSI_PAL_MODE 0
+
+/*
+ * 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
diff --git a/keyboards/cannonkeys/atlas/halconf.h b/keyboards/cannonkeys/atlas/halconf.h
new file mode 100644
index 000000000..adb1a9071
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/halconf.h
@@ -0,0 +1,525 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#define _CHIBIOS_HAL_CONF_
+#define _CHIBIOS_HAL_CONF_VER_7_0_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the cryptographic subsystem.
+ */
+#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
+#define HAL_USE_CRY FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C TRUE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SIO subsystem.
+ */
+#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
+#define HAL_USE_SIO FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the TRNG subsystem.
+ */
+#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
+#define HAL_USE_TRNG FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/**
+ * @brief Enables the WSPI subsystem.
+ */
+#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
+#define HAL_USE_WSPI FALSE
+#endif
+
+/*===========================================================================*/
+/* PAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define PAL_USE_CALLBACKS FALSE
+#endif
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/**
+ * @brief Enforces the driver to use direct callbacks rather than OSAL events.
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define CAN_ENFORCE_USE_CALLBACKS FALSE
+#endif
+
+/*===========================================================================*/
+/* CRY driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the SW fall-back of the cryptographic driver.
+ * @details When enabled, this option, activates a fall-back software
+ * implementation for algorithms not supported by the underlying
+ * hardware.
+ * @note Fall-back implementations may not be present for all algorithms.
+ */
+#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_USE_FALLBACK FALSE
+#endif
+
+/**
+ * @brief Makes the driver forcibly use the fall-back implementations.
+ */
+#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_ENFORCE_FALLBACK FALSE
+#endif
+
+/*===========================================================================*/
+/* DAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
+#define DAC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define DAC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the zero-copy API.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief OCR initialization constant for V20 cards.
+ */
+#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR_V20 0x50FF8000U
+#endif
+
+/**
+ * @brief OCR initialization constant for non-V20 cards.
+ */
+#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR 0x80100000U
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables circular transfers APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
+#define SPI_USE_CIRCULAR FALSE
+#endif
+
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/**
+ * @brief Handling method for SPI CS line.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+/*===========================================================================*/
+/* WSPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
+#define WSPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define WSPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/atlas/info.json b/keyboards/cannonkeys/atlas/info.json
new file mode 100644
index 000000000..10d952973
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/info.json
@@ -0,0 +1,198 @@
+{
+ "keyboard_name": "Atlas",
+ "url": "https://cannonkeys.com",
+ "maintainer": "awkannan",
+ "width": 12,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_ortho_5x12": {
+ "layout": [
+ {"label":"`", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":7, "y":0},
+ {"label":"8", "x":8, "y":0},
+ {"label":"9", "x":9, "y":0},
+ {"label":"0", "x":10, "y":0},
+ {"label":"Backspace", "x":11, "y":0},
+ {"label":"Tab", "x":0, "y":1},
+ {"label":"Q", "x":1, "y":1},
+ {"label":"W", "x":2, "y":1},
+ {"label":"E", "x":3, "y":1},
+ {"label":"R", "x":4, "y":1},
+ {"label":"T", "x":5, "y":1},
+ {"label":"Y", "x":6, "y":1},
+ {"label":"U", "x":7, "y":1},
+ {"label":"I", "x":8, "y":1},
+ {"label":"O", "x":9, "y":1},
+ {"label":"P", "x":10, "y":1},
+ {"label":"Delete", "x":11, "y":1},
+ {"label":"Esc", "x":0, "y":2},
+ {"label":"A", "x":1, "y":2},
+ {"label":"S", "x":2, "y":2},
+ {"label":"D", "x":3, "y":2},
+ {"label":"F", "x":4, "y":2},
+ {"label":"G", "x":5, "y":2},
+ {"label":"H", "x":6, "y":2},
+ {"label":"J", "x":7, "y":2},
+ {"label":"K", "x":8, "y":2},
+ {"label":"L", "x":9, "y":2},
+ {"label":";", "x":10, "y":2},
+ {"label":"'", "x":11, "y":2},
+ {"label":"Shift", "x":0, "y":3},
+ {"label":"Z", "x":1, "y":3},
+ {"label":"X", "x":2, "y":3},
+ {"label":"C", "x":3, "y":3},
+ {"label":"V", "x":4, "y":3},
+ {"label":"B", "x":5, "y":3},
+ {"label":"N", "x":6, "y":3},
+ {"label":"M", "x":7, "y":3},
+ {"label":",", "x":8, "y":3},
+ {"label":".", "x":9, "y":3},
+ {"label":"/", "x":10, "y":3},
+ {"label":"Enter", "x":11, "y":3},
+ {"label":"Fn", "x":0, "y":4},
+ {"label":"Ctrl", "x":1, "y":4},
+ {"label":"Alt", "x":2, "y":4},
+ {"label":"Meta", "x":3, "y":4},
+ {"label":"Lower", "x":4, "y":4},
+ {"label":"Space", "x":5, "y":4},
+ {"label":"Space", "x":6, "y":4},
+ {"label":"Raise", "x":7, "y":4},
+ {"label":"Left", "x":8, "y":4},
+ {"label":"Down", "x":9, "y":4},
+ {"label":"Up", "x":10, "y":4},
+ {"label":"Right", "x":11, "y":4}
+ ]
+ },
+ "LAYOUT_ortho_5x12_1x2uC": {
+ "layout": [
+ {"label":"`", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":7, "y":0},
+ {"label":"8", "x":8, "y":0},
+ {"label":"9", "x":9, "y":0},
+ {"label":"0", "x":10, "y":0},
+ {"label":"Backspace", "x":11, "y":0},
+ {"label":"Tab", "x":0, "y":1},
+ {"label":"Q", "x":1, "y":1},
+ {"label":"W", "x":2, "y":1},
+ {"label":"E", "x":3, "y":1},
+ {"label":"R", "x":4, "y":1},
+ {"label":"T", "x":5, "y":1},
+ {"label":"Y", "x":6, "y":1},
+ {"label":"U", "x":7, "y":1},
+ {"label":"I", "x":8, "y":1},
+ {"label":"O", "x":9, "y":1},
+ {"label":"P", "x":10, "y":1},
+ {"label":"Delete", "x":11, "y":1},
+ {"label":"Esc", "x":0, "y":2},
+ {"label":"A", "x":1, "y":2},
+ {"label":"S", "x":2, "y":2},
+ {"label":"D", "x":3, "y":2},
+ {"label":"F", "x":4, "y":2},
+ {"label":"G", "x":5, "y":2},
+ {"label":"H", "x":6, "y":2},
+ {"label":"J", "x":7, "y":2},
+ {"label":"K", "x":8, "y":2},
+ {"label":"L", "x":9, "y":2},
+ {"label":";", "x":10, "y":2},
+ {"label":"'", "x":11, "y":2},
+ {"label":"Shift", "x":0, "y":3},
+ {"label":"Z", "x":1, "y":3},
+ {"label":"X", "x":2, "y":3},
+ {"label":"C", "x":3, "y":3},
+ {"label":"V", "x":4, "y":3},
+ {"label":"B", "x":5, "y":3},
+ {"label":"N", "x":6, "y":3},
+ {"label":"M", "x":7, "y":3},
+ {"label":",", "x":8, "y":3},
+ {"label":".", "x":9, "y":3},
+ {"label":"/", "x":10, "y":3},
+ {"label":"Enter", "x":11, "y":3},
+ {"label":"Fn", "x":0, "y":4},
+ {"label":"Ctrl", "x":1, "y":4},
+ {"label":"Alt", "x":2, "y":4},
+ {"label":"Meta", "x":3, "y":4},
+ {"label":"Lower", "x":4, "y":4},
+ {"label":"Space", "x":5, "y":4, "w":2},
+ {"label":"Raise", "x":7, "y":4},
+ {"label":"Left", "x":8, "y":4},
+ {"label":"Down", "x":9, "y":4},
+ {"label":"Up", "x":10, "y":4},
+ {"label":"Right", "x":11, "y":4}
+ ]
+ },
+ "LAYOUT_ortho_5x12_2x2uC": {
+ "layout": [
+ {"label":"`", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":7, "y":0},
+ {"label":"8", "x":8, "y":0},
+ {"label":"9", "x":9, "y":0},
+ {"label":"0", "x":10, "y":0},
+ {"label":"Backspace", "x":11, "y":0},
+ {"label":"Tab", "x":0, "y":1},
+ {"label":"Q", "x":1, "y":1},
+ {"label":"W", "x":2, "y":1},
+ {"label":"E", "x":3, "y":1},
+ {"label":"R", "x":4, "y":1},
+ {"label":"T", "x":5, "y":1},
+ {"label":"Y", "x":6, "y":1},
+ {"label":"U", "x":7, "y":1},
+ {"label":"I", "x":8, "y":1},
+ {"label":"O", "x":9, "y":1},
+ {"label":"P", "x":10, "y":1},
+ {"label":"Delete", "x":11, "y":1},
+ {"label":"Esc", "x":0, "y":2},
+ {"label":"A", "x":1, "y":2},
+ {"label":"S", "x":2, "y":2},
+ {"label":"D", "x":3, "y":2},
+ {"label":"F", "x":4, "y":2},
+ {"label":"G", "x":5, "y":2},
+ {"label":"H", "x":6, "y":2},
+ {"label":"J", "x":7, "y":2},
+ {"label":"K", "x":8, "y":2},
+ {"label":"L", "x":9, "y":2},
+ {"label":";", "x":10, "y":2},
+ {"label":"'", "x":11, "y":2},
+ {"label":"Shift", "x":0, "y":3},
+ {"label":"Z", "x":1, "y":3},
+ {"label":"X", "x":2, "y":3},
+ {"label":"C", "x":3, "y":3},
+ {"label":"V", "x":4, "y":3},
+ {"label":"B", "x":5, "y":3},
+ {"label":"N", "x":6, "y":3},
+ {"label":"M", "x":7, "y":3},
+ {"label":",", "x":8, "y":3},
+ {"label":".", "x":9, "y":3},
+ {"label":"/", "x":10, "y":3},
+ {"label":"Enter", "x":11, "y":3},
+ {"label":"Fn", "x":0, "y":4},
+ {"label":"Ctrl", "x":1, "y":4},
+ {"label":"Alt", "x":2, "y":4},
+ {"label":"Meta", "x":3, "y":4},
+ {"label":"Space1", "x":4, "y":4, "w":2},
+ {"label":"Space2", "x":6, "y":4, "w":2},
+ {"label":"Left", "x":8, "y":4},
+ {"label":"Down", "x":9, "y":4},
+ {"label":"Up", "x":10, "y":4},
+ {"label":"Right", "x":11, "y":4}
+ ]
+ }
+ }
+ }
diff --git a/keyboards/cannonkeys/atlas/keymaps/default/keymap.c b/keyboards/cannonkeys/atlas/keymaps/default/keymap.c
new file mode 100644
index 000000000..705d31a40
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/keymaps/default/keymap.c
@@ -0,0 +1,93 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _RAISE,
+ _LOWER
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Tab | Q | W | E | R | T | Y | U | I | O | P | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | 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 |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_BASE] = LAYOUT_ortho_5x12( \
+ 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_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL, \
+ 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, \
+ BL_TOGG, KC_LCTL, KC_LALT, KC_LGUI, MO(_LOWER), KC_SPC, KC_SPC, MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+),
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT_ortho_5x12( \
+ 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_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______, \
+ RESET, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT_ortho_5x12( \
+ 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_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______, \
+ RGB_TOG, RGB_MOD, BL_INC, BL_DEC, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+)
+};
diff --git a/keyboards/cannonkeys/atlas/keymaps/via/keymap.c b/keyboards/cannonkeys/atlas/keymaps/via/keymap.c
new file mode 100644
index 000000000..2e72c8f9d
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/keymaps/via/keymap.c
@@ -0,0 +1,102 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _RAISE,
+ _LOWER,
+ _EXTRA
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Tab | Q | W | E | R | T | Y | U | I | O | P | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | 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 |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_BASE] = LAYOUT_ortho_5x12( \
+ 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_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL, \
+ 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, \
+ BL_TOGG, KC_LCTL, KC_LALT, KC_LGUI, MO(_LOWER), KC_SPC, KC_SPC, MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+),
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT_ortho_5x12( \
+ 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_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______, \
+ RESET, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT_ortho_5x12( \
+ 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_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______, \
+ RGB_TOG, RGB_MOD, BL_INC, BL_DEC, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+[_EXTRA] = LAYOUT_ortho_5x12( \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
+)
+};
diff --git a/keyboards/cannonkeys/atlas/keymaps/via/rules.mk b/keyboards/cannonkeys/atlas/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/cannonkeys/atlas/mcuconf.h b/keyboards/cannonkeys/atlas/mcuconf.h
new file mode 100644
index 000000000..048eb4df6
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/mcuconf.h
@@ -0,0 +1,176 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+/*
+ * STM32F0xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F0xx_MCUCONF
+// #define STM32F070xB
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_HSI_ENABLED TRUE
+#define STM32_HSI14_ENABLED TRUE
+#define STM32_HSI48_ENABLED FALSE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
+#define STM32_PREDIV_VALUE 1
+#define STM32_PLLMUL_VALUE 12
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE STM32_PPRE_DIV1
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_USBSW STM32_USBSW_HSI48
+#define STM32_CECSW STM32_CECSW_HSI
+#define STM32_I2C1SW STM32_I2C1SW_HSI
+#define STM32_USART1SW STM32_USART1SW_PCLK
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 2
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 2
+#define STM32_GPT_TIM2_IRQ_PRIORITY 2
+#define STM32_GPT_TIM3_IRQ_PRIORITY 2
+#define STM32_GPT_TIM14_IRQ_PRIORITY 2
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 TRUE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C2_IRQ_PRIORITY 3
+#define STM32_I2C_USE_DMA TRUE
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 3
+#define STM32_ICU_TIM2_IRQ_PRIORITY 3
+#define STM32_ICU_TIM3_IRQ_PRIORITY 3
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 TRUE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 3
+#define STM32_PWM_TIM2_IRQ_PRIORITY 3
+#define STM32_PWM_TIM3_IRQ_PRIORITY 3
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 3
+#define STM32_SERIAL_USART2_PRIORITY 3
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 2
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 3
+#define STM32_UART_USART2_IRQ_PRIORITY 3
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/cannonkeys/atlas/readme.md b/keyboards/cannonkeys/atlas/readme.md
new file mode 100644
index 000000000..a11117b8e
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/readme.md
@@ -0,0 +1,10 @@
+# CannonKeys Atlas
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: STM32F072CBT6
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/atlas:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/cannonkeys/atlas/rules.mk b/keyboards/cannonkeys/atlas/rules.mk
new file mode 100644
index 000000000..8037597b5
--- /dev/null
+++ b/keyboards/cannonkeys/atlas/rules.mk
@@ -0,0 +1,16 @@
+# MCU Name
+MCU = STM32F072
+
+# Build Options
+# comment out to disable the options.
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+NKRO_ENABLE = yes # USB Nkey Rollover
+CUSTOM_MATRIX = no # Custom matrix file
+BACKLIGHT_ENABLE = no
+RGBLIGHT_ENABLE = yes
+WS2812_DRIVER = spi
diff --git a/keyboards/cannonkeys/db60/chconf.h b/keyboards/cannonkeys/db60/chconf.h
new file mode 100644
index 000000000..03f63da36
--- /dev/null
+++ b/keyboards/cannonkeys/db60/chconf.h
@@ -0,0 +1,714 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file rt/templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_6_0_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_ST_RESOLUTION)
+#define CH_CFG_ST_RESOLUTION 32
+#endif
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_CFG_ST_FREQUENCY)
+#define CH_CFG_ST_FREQUENCY 10000
+#endif
+
+/**
+ * @brief Time intervals data size.
+ * @note Allowed values are 16, 32 or 64 bits.
+ */
+#if !defined(CH_CFG_INTERVALS_SIZE)
+#define CH_CFG_INTERVALS_SIZE 32
+#endif
+
+/**
+ * @brief Time types data size.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_TIME_TYPES_SIZE)
+#define CH_CFG_TIME_TYPES_SIZE 32
+#endif
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#if !defined(CH_CFG_ST_TIMEDELTA)
+#define CH_CFG_ST_TIMEDELTA 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#if !defined(CH_CFG_TIME_QUANTUM)
+#define CH_CFG_TIME_QUANTUM 0
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#if !defined(CH_CFG_MEMCORE_SIZE)
+#define CH_CFG_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#if !defined(CH_CFG_NO_IDLE_THREAD)
+#define CH_CFG_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_OPTIMIZE_SPEED)
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_TM)
+#define CH_CFG_USE_TM FALSE
+#endif
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_REGISTRY)
+#define CH_CFG_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_WAITEXIT)
+#define CH_CFG_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES)
+#define CH_CFG_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MUTEXES)
+#define CH_CFG_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_CONDVARS)
+#define CH_CFG_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_EVENTS)
+#define CH_CFG_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MESSAGES)
+#define CH_CFG_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
+#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_MAILBOXES)
+#define CH_CFG_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMCORE)
+#define CH_CFG_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_CFG_USE_HEAP)
+#define CH_CFG_USE_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#define CH_CFG_USE_MEMPOOLS FALSE
+#endif
+
+/**
+ * @brief Objects FIFOs APIs.
+ * @details If enabled then the objects FIFOs APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#define CH_CFG_USE_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Pipes APIs.
+ * @details If enabled then the pipes APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_PIPES)
+#define CH_CFG_USE_PIPES FALSE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#if !defined(CH_CFG_USE_DYNAMIC)
+#define CH_CFG_USE_DYNAMIC FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Objects factory options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Objects Factory APIs.
+ * @details If enabled then the objects factory APIs are included in the
+ * kernel.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_CFG_USE_FACTORY)
+#define CH_CFG_USE_FACTORY FALSE
+#endif
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
+#endif
+
+/**
+ * @brief Enables the registry of generic objects.
+ */
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
+#endif
+
+/**
+ * @brief Enables factory for generic buffers.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#define CH_CFG_FACTORY_SEMAPHORES FALSE
+#endif
+
+/**
+ * @brief Enables factory for mailboxes.
+ */
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#define CH_CFG_FACTORY_MAILBOXES FALSE
+#endif
+
+/**
+ * @brief Enables factory for objects FIFOs.
+ */
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Enables factory for Pipes.
+ */
+#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_PIPES FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_STATISTICS)
+#define CH_DBG_STATISTICS FALSE
+#endif
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_MASK)
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+#endif
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING)
+#define CH_DBG_THREADS_PROFILING FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System structure extension.
+ * @details User fields added to the end of the @p ch_system_t structure.
+ */
+#define CH_CFG_SYSTEM_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief System initialization hook.
+ * @details User initialization code added to the @p chSysInit() function
+ * just before interrupts are enabled globally.
+ */
+#define CH_CFG_SYSTEM_INIT_HOOK() { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p _thread_init() function.
+ *
+ * @note It is invoked from within @p _thread_init() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/db60/config.h b/keyboards/cannonkeys/db60/config.h
new file mode 100644
index 000000000..54995c6b2
--- /dev/null
+++ b/keyboards/cannonkeys/db60/config.h
@@ -0,0 +1,78 @@
+/*
+Copyright 2015 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/>.
+*/
+
+#pragma once
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCA04
+#define PRODUCT_ID 0xDB60
+#define DEVICE_VER 0x0001
+
+#define MANUFACTURER CannonKeys
+#define PRODUCT DB60
+#define DESCRIPTION DB60 Keyboard
+
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 15
+
+#define MATRIX_COL_PINS { B11, B10, B2, A9, A15, B3, B4, B5, B6, B7, B8, B9, C13, C14, C15 }
+#define MATRIX_ROW_PINS { B1, B0, A7, A5, A4 }
+#define DIODE_DIRECTION COL2ROW
+
+
+#define BACKLIGHT_PIN A6
+#define BACKLIGHT_PWM_DRIVER PWMD3
+#define BACKLIGHT_PWM_CHANNEL 1
+#define BACKLIGHT_PAL_MODE 1
+#define BACKLIGHT_LEVELS 6
+#define BACKLIGHT_BREATHING
+#define BREATHING_PERIOD 6
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 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
+
+#define RGBLIGHT_ANIMATIONS
+#define WS2812_SPI SPID2
+#define RGB_DI_PIN B15
+#define RGBLED_NUM 20
+#define WS2812_SPI_MOSI_PAL_MODE 0
+
+/*
+ * 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
diff --git a/keyboards/cannonkeys/db60/db60.c b/keyboards/cannonkeys/db60/db60.c
new file mode 100644
index 000000000..25344360b
--- /dev/null
+++ b/keyboards/cannonkeys/db60/db60.c
@@ -0,0 +1 @@
+#include "db60.h"
diff --git a/keyboards/cannonkeys/db60/db60.h b/keyboards/cannonkeys/db60/db60.h
new file mode 100644
index 000000000..741ab7d0e
--- /dev/null
+++ b/keyboards/cannonkeys/db60/db60.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "quantum.h"
+
+#define KNO KC_NO
+
+#define LAYOUT_60_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, K1E, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2E, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
+ K40, K41, K42, K45, K4A, K4B, K4C, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, KNO}, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, KNO, K1E }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KNO, KNO, K2E }, \
+ { K30, KNO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KNO, KNO }, \
+ { K40, K41, K42, KNO, KNO, K45, KNO, KNO, KNO, KNO, K4A, K4B, K4C, KNO, K4E } \
+}
+
+#define LAYOUT_60_tsangan_hhkb( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1E, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2E, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E,\
+ K40, K41, K42, K45, K4B, K4C, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E}, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, KNO, K1E }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KNO, KNO, K2E }, \
+ { K30, KNO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KNO, K3E }, \
+ { K40, K41, K42, KNO, KNO, K45, KNO, KNO, KNO, KNO, KNO, K4B, K4C, KNO, K4E } \
+}
+
+#define LAYOUT_60_iso( \
+ 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, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
+ K40, K41, K42, K45, K4A, K4B, K4C, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, KNO}, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, KNO, KNO }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KNO, K2E }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KNO, KNO }, \
+ { K40, K41, K42, KNO, KNO, K45, KNO, KNO, KNO, KNO, K4A, K4B, K4C, KNO, K4E } \
+}
+
+#define LAYOUT_all( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E,\
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1E, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E,\
+ K40, K41, K42, K45, K4A, K4B, K4C, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E}, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, KNO, K1E }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KNO, K2E }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KNO, K3E }, \
+ { K40, K41, K42, KNO, KNO, K45, KNO, KNO, KNO, KNO, K4A, K4B, K4C, KNO, K4E } \
+}
diff --git a/keyboards/cannonkeys/db60/halconf.h b/keyboards/cannonkeys/db60/halconf.h
new file mode 100644
index 000000000..adb1a9071
--- /dev/null
+++ b/keyboards/cannonkeys/db60/halconf.h
@@ -0,0 +1,525 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#define _CHIBIOS_HAL_CONF_
+#define _CHIBIOS_HAL_CONF_VER_7_0_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the cryptographic subsystem.
+ */
+#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
+#define HAL_USE_CRY FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C TRUE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SIO subsystem.
+ */
+#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
+#define HAL_USE_SIO FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the TRNG subsystem.
+ */
+#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
+#define HAL_USE_TRNG FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/**
+ * @brief Enables the WSPI subsystem.
+ */
+#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
+#define HAL_USE_WSPI FALSE
+#endif
+
+/*===========================================================================*/
+/* PAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define PAL_USE_CALLBACKS FALSE
+#endif
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/**
+ * @brief Enforces the driver to use direct callbacks rather than OSAL events.
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define CAN_ENFORCE_USE_CALLBACKS FALSE
+#endif
+
+/*===========================================================================*/
+/* CRY driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the SW fall-back of the cryptographic driver.
+ * @details When enabled, this option, activates a fall-back software
+ * implementation for algorithms not supported by the underlying
+ * hardware.
+ * @note Fall-back implementations may not be present for all algorithms.
+ */
+#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_USE_FALLBACK FALSE
+#endif
+
+/**
+ * @brief Makes the driver forcibly use the fall-back implementations.
+ */
+#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_ENFORCE_FALLBACK FALSE
+#endif
+
+/*===========================================================================*/
+/* DAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
+#define DAC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define DAC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the zero-copy API.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief OCR initialization constant for V20 cards.
+ */
+#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR_V20 0x50FF8000U
+#endif
+
+/**
+ * @brief OCR initialization constant for non-V20 cards.
+ */
+#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR 0x80100000U
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables circular transfers APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
+#define SPI_USE_CIRCULAR FALSE
+#endif
+
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/**
+ * @brief Handling method for SPI CS line.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+/*===========================================================================*/
+/* WSPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
+#define WSPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define WSPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/db60/info.json b/keyboards/cannonkeys/db60/info.json
new file mode 100644
index 000000000..3576880b4
--- /dev/null
+++ b/keyboards/cannonkeys/db60/info.json
@@ -0,0 +1,19 @@
+{
+ "keyboard_name": "DB60",
+ "url": "https://cannonkeys.com",
+ "maintainer": "awkannan",
+ "width": 15,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_60_ansi": {
+ "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ },
+ "LAYOUT_60_tsangan_hhkb": {
+ "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"x":14, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.5}, {"label":"Win", "x":1.5, "y":4}, {"label":"Alt", "x":2.5, "y":4, "w":1.5}, {"x":4, "y":4, "w":7}, {"label":"Alt", "x":11, "y":4, "w":1.5}, {"label":"Win", "x":12.5, "y":4}, {"label":"Ctrl", "x":13.5, "y":4, "w":1.5}]
+ },
+ "LAYOUT_60_iso": {
+ "layout": [{"label":"\u00ac", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"\"", "x":2, "y":0}, {"label":"\u00a3", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"@", "x":11.75, "y":2}, {"label":"~", "x":12.75, "y":2}, {"label":"Enter", "x":13.75, "y":1, "w":1.25, "h":2}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"label":"|", "x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"AltGr", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ }
+ }
+
+ }
diff --git a/keyboards/cannonkeys/db60/keymaps/default/keymap.c b/keyboards/cannonkeys/db60/keymaps/default/keymap.c
new file mode 100644
index 000000000..9c834aa13
--- /dev/null
+++ b/keyboards/cannonkeys/db60/keymaps/default/keymap.c
@@ -0,0 +1,45 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_60_ansi(
+ KC_GESC, 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,
+ 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_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, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_60_ansi(
+ KC_GESC, 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_DEL,
+ RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_BRTG, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_INC, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_GRV, _______, _______, _______, _______, _______, _______, RESET
+ )
+};
diff --git a/keyboards/cannonkeys/db60/keymaps/iso/keymap.c b/keyboards/cannonkeys/db60/keymaps/iso/keymap.c
new file mode 100644
index 000000000..52fca7d16
--- /dev/null
+++ b/keyboards/cannonkeys/db60/keymaps/iso/keymap.c
@@ -0,0 +1,45 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_60_iso(
+ KC_GESC, 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_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, 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_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_60_iso(
+ KC_GESC, 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_DEL,
+ RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_BRTG, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_INC, _______, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_GRV, _______, _______, _______, _______, _______, _______, RESET
+ )
+};
diff --git a/keyboards/cannonkeys/db60/keymaps/tsangan/keymap.c b/keyboards/cannonkeys/db60/keymaps/tsangan/keymap.c
new file mode 100644
index 000000000..996a3d536
--- /dev/null
+++ b/keyboards/cannonkeys/db60/keymaps/tsangan/keymap.c
@@ -0,0 +1,46 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_60_tsangan_hhkb(
+ KC_GESC, 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_DEL,
+ 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_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(_FN1),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_60_tsangan_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_DEL, _______,
+ RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_BRTG, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_INC, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, RESET
+ )
+};
diff --git a/keyboards/cannonkeys/db60/keymaps/via/keymap.c b/keyboards/cannonkeys/db60/keymaps/via/keymap.c
new file mode 100644
index 000000000..47af39164
--- /dev/null
+++ b/keyboards/cannonkeys/db60/keymaps/via/keymap.c
@@ -0,0 +1,63 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1,
+ _FN2,
+ _FN3
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_all(
+ KC_GESC, 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_DEL,
+ 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_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, 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, MO(_FN1),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_all(
+ 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_DEL, _______,
+ RGB_TOG, RGB_MOD, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_BRTG, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_INC, BL_DEC, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, RESET
+ ),
+
+ [_FN2] = LAYOUT_all(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ [_FN3] = LAYOUT_all(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
diff --git a/keyboards/cannonkeys/db60/keymaps/via/rules.mk b/keyboards/cannonkeys/db60/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/cannonkeys/db60/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/cannonkeys/db60/mcuconf.h b/keyboards/cannonkeys/db60/mcuconf.h
new file mode 100644
index 000000000..048eb4df6
--- /dev/null
+++ b/keyboards/cannonkeys/db60/mcuconf.h
@@ -0,0 +1,176 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+/*
+ * STM32F0xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F0xx_MCUCONF
+// #define STM32F070xB
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_HSI_ENABLED TRUE
+#define STM32_HSI14_ENABLED TRUE
+#define STM32_HSI48_ENABLED FALSE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
+#define STM32_PREDIV_VALUE 1
+#define STM32_PLLMUL_VALUE 12
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE STM32_PPRE_DIV1
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_USBSW STM32_USBSW_HSI48
+#define STM32_CECSW STM32_CECSW_HSI
+#define STM32_I2C1SW STM32_I2C1SW_HSI
+#define STM32_USART1SW STM32_USART1SW_PCLK
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 2
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 2
+#define STM32_GPT_TIM2_IRQ_PRIORITY 2
+#define STM32_GPT_TIM3_IRQ_PRIORITY 2
+#define STM32_GPT_TIM14_IRQ_PRIORITY 2
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 TRUE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C2_IRQ_PRIORITY 3
+#define STM32_I2C_USE_DMA TRUE
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 3
+#define STM32_ICU_TIM2_IRQ_PRIORITY 3
+#define STM32_ICU_TIM3_IRQ_PRIORITY 3
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 TRUE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 3
+#define STM32_PWM_TIM2_IRQ_PRIORITY 3
+#define STM32_PWM_TIM3_IRQ_PRIORITY 3
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 3
+#define STM32_SERIAL_USART2_PRIORITY 3
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 2
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 3
+#define STM32_UART_USART2_IRQ_PRIORITY 3
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/cannonkeys/db60/readme.md b/keyboards/cannonkeys/db60/readme.md
new file mode 100644
index 000000000..c1000ae2c
--- /dev/null
+++ b/keyboards/cannonkeys/db60/readme.md
@@ -0,0 +1,12 @@
+# CannonKeys DB60
+
+DB60 "Daughterboard 60" Keyboard
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: STM32F072CBT6
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/db60:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/cannonkeys/db60/rules.mk b/keyboards/cannonkeys/db60/rules.mk
new file mode 100644
index 000000000..126728650
--- /dev/null
+++ b/keyboards/cannonkeys/db60/rules.mk
@@ -0,0 +1,21 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+NKRO_ENABLE = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = yes
+RGBLIGHT_ENABLE = yes
+WS2812_DRIVER = spi
+
+LAYOUTS = 60_ansi 60_tsangan_hhkb 60_iso
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/cannonkeys/devastatingtkl/chconf.h b/keyboards/cannonkeys/devastatingtkl/chconf.h
new file mode 100644
index 000000000..03f63da36
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/chconf.h
@@ -0,0 +1,714 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file rt/templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_6_0_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_ST_RESOLUTION)
+#define CH_CFG_ST_RESOLUTION 32
+#endif
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_CFG_ST_FREQUENCY)
+#define CH_CFG_ST_FREQUENCY 10000
+#endif
+
+/**
+ * @brief Time intervals data size.
+ * @note Allowed values are 16, 32 or 64 bits.
+ */
+#if !defined(CH_CFG_INTERVALS_SIZE)
+#define CH_CFG_INTERVALS_SIZE 32
+#endif
+
+/**
+ * @brief Time types data size.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_TIME_TYPES_SIZE)
+#define CH_CFG_TIME_TYPES_SIZE 32
+#endif
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#if !defined(CH_CFG_ST_TIMEDELTA)
+#define CH_CFG_ST_TIMEDELTA 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#if !defined(CH_CFG_TIME_QUANTUM)
+#define CH_CFG_TIME_QUANTUM 0
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#if !defined(CH_CFG_MEMCORE_SIZE)
+#define CH_CFG_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#if !defined(CH_CFG_NO_IDLE_THREAD)
+#define CH_CFG_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_OPTIMIZE_SPEED)
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_TM)
+#define CH_CFG_USE_TM FALSE
+#endif
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_REGISTRY)
+#define CH_CFG_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_WAITEXIT)
+#define CH_CFG_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES)
+#define CH_CFG_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MUTEXES)
+#define CH_CFG_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_CONDVARS)
+#define CH_CFG_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_EVENTS)
+#define CH_CFG_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MESSAGES)
+#define CH_CFG_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
+#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_MAILBOXES)
+#define CH_CFG_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMCORE)
+#define CH_CFG_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_CFG_USE_HEAP)
+#define CH_CFG_USE_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#define CH_CFG_USE_MEMPOOLS FALSE
+#endif
+
+/**
+ * @brief Objects FIFOs APIs.
+ * @details If enabled then the objects FIFOs APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#define CH_CFG_USE_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Pipes APIs.
+ * @details If enabled then the pipes APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_PIPES)
+#define CH_CFG_USE_PIPES FALSE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#if !defined(CH_CFG_USE_DYNAMIC)
+#define CH_CFG_USE_DYNAMIC FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Objects factory options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Objects Factory APIs.
+ * @details If enabled then the objects factory APIs are included in the
+ * kernel.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_CFG_USE_FACTORY)
+#define CH_CFG_USE_FACTORY FALSE
+#endif
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
+#endif
+
+/**
+ * @brief Enables the registry of generic objects.
+ */
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
+#endif
+
+/**
+ * @brief Enables factory for generic buffers.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#define CH_CFG_FACTORY_SEMAPHORES FALSE
+#endif
+
+/**
+ * @brief Enables factory for mailboxes.
+ */
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#define CH_CFG_FACTORY_MAILBOXES FALSE
+#endif
+
+/**
+ * @brief Enables factory for objects FIFOs.
+ */
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Enables factory for Pipes.
+ */
+#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_PIPES FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_STATISTICS)
+#define CH_DBG_STATISTICS FALSE
+#endif
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_MASK)
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+#endif
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING)
+#define CH_DBG_THREADS_PROFILING FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System structure extension.
+ * @details User fields added to the end of the @p ch_system_t structure.
+ */
+#define CH_CFG_SYSTEM_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief System initialization hook.
+ * @details User initialization code added to the @p chSysInit() function
+ * just before interrupts are enabled globally.
+ */
+#define CH_CFG_SYSTEM_INIT_HOOK() { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p _thread_init() function.
+ *
+ * @note It is invoked from within @p _thread_init() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/devastatingtkl/config.h b/keyboards/cannonkeys/devastatingtkl/config.h
new file mode 100644
index 000000000..8f589bf12
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/config.h
@@ -0,0 +1,77 @@
+/*
+Copyright 2015 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/>.
+*/
+
+#pragma once
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCA04
+#define PRODUCT_ID 0xDE57
+#define DEVICE_VER 0x0001
+#define MANUFACTURER CannonKeys
+#define PRODUCT DevastatingTKL
+#define DESCRIPTION Devastating Keyboard
+
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 18
+
+#define MATRIX_COL_PINS { B1, B2, B10, B11, B12, B14, A8, A9, A10, A3, B0, A2, A1, A7, A0, B4, B6, B7 }
+#define MATRIX_ROW_PINS { A15, B3, B5, A4, A5, F1 }
+#define DIODE_DIRECTION COL2ROW
+
+
+#define BACKLIGHT_PIN A6
+#define BACKLIGHT_PWM_DRIVER PWMD3
+#define BACKLIGHT_PWM_CHANNEL 1
+#define BACKLIGHT_PAL_MODE 1
+#define BACKLIGHT_LEVELS 6
+#define BACKLIGHT_BREATHING
+#define BREATHING_PERIOD 6
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 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
+
+#define RGBLIGHT_ANIMATIONS
+#define RGB_DI_PIN B15
+#define RGBLED_NUM 20
+#define WS2812_SPI SPID2
+#define WS2812_SPI_MOSI_PAL_MODE 0
+
+/*
+ * 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
diff --git a/keyboards/cannonkeys/devastatingtkl/devastatingtkl.c b/keyboards/cannonkeys/devastatingtkl/devastatingtkl.c
new file mode 100644
index 000000000..46072b409
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/devastatingtkl.c
@@ -0,0 +1 @@
+#include "devastatingtkl.h"
diff --git a/keyboards/cannonkeys/devastatingtkl/devastatingtkl.h b/keyboards/cannonkeys/devastatingtkl/devastatingtkl.h
new file mode 100644
index 000000000..2ad5c2c71
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/devastatingtkl.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT_all( \
+ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K014, K015, K016, K017, \
+ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117, \
+ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, K215, K216, K217, \
+ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K314, \
+ K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K414, K416, \
+ K500, K501, K502, K506, K510, K511, K512, K514, K515, K516, K517 \
+) { \
+ { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, KC_NO, K014, K015, K016, K017 }, \
+ { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117 }, \
+ { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, KC_NO, K214, K215, K216, K217 }, \
+ { K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, KC_NO, K314, KC_NO, KC_NO, KC_NO }, \
+ { K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, KC_NO, K414, KC_NO, K416, KC_NO }, \
+ { K500, K501, K502, KC_NO, KC_NO, KC_NO, K506, KC_NO, KC_NO, KC_NO, K510, K511, K512, KC_NO, K514, K515, K516, K517 } \
+}
diff --git a/keyboards/cannonkeys/devastatingtkl/halconf.h b/keyboards/cannonkeys/devastatingtkl/halconf.h
new file mode 100644
index 000000000..adb1a9071
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/halconf.h
@@ -0,0 +1,525 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#define _CHIBIOS_HAL_CONF_
+#define _CHIBIOS_HAL_CONF_VER_7_0_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the cryptographic subsystem.
+ */
+#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
+#define HAL_USE_CRY FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C TRUE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SIO subsystem.
+ */
+#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
+#define HAL_USE_SIO FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the TRNG subsystem.
+ */
+#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
+#define HAL_USE_TRNG FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/**
+ * @brief Enables the WSPI subsystem.
+ */
+#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
+#define HAL_USE_WSPI FALSE
+#endif
+
+/*===========================================================================*/
+/* PAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define PAL_USE_CALLBACKS FALSE
+#endif
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/**
+ * @brief Enforces the driver to use direct callbacks rather than OSAL events.
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define CAN_ENFORCE_USE_CALLBACKS FALSE
+#endif
+
+/*===========================================================================*/
+/* CRY driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the SW fall-back of the cryptographic driver.
+ * @details When enabled, this option, activates a fall-back software
+ * implementation for algorithms not supported by the underlying
+ * hardware.
+ * @note Fall-back implementations may not be present for all algorithms.
+ */
+#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_USE_FALLBACK FALSE
+#endif
+
+/**
+ * @brief Makes the driver forcibly use the fall-back implementations.
+ */
+#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_ENFORCE_FALLBACK FALSE
+#endif
+
+/*===========================================================================*/
+/* DAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
+#define DAC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define DAC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the zero-copy API.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief OCR initialization constant for V20 cards.
+ */
+#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR_V20 0x50FF8000U
+#endif
+
+/**
+ * @brief OCR initialization constant for non-V20 cards.
+ */
+#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR 0x80100000U
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables circular transfers APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
+#define SPI_USE_CIRCULAR FALSE
+#endif
+
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/**
+ * @brief Handling method for SPI CS line.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+/*===========================================================================*/
+/* WSPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
+#define WSPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define WSPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/devastatingtkl/info.json b/keyboards/cannonkeys/devastatingtkl/info.json
new file mode 100644
index 000000000..042410e28
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/info.json
@@ -0,0 +1,13 @@
+{
+ "keyboard_name": "DevastatingTKL",
+ "url": "https://cannonkeys.com",
+ "maintainer": "awkannan",
+ "width": 18.25,
+ "height": 6.25,
+ "layouts": {
+ "LAYOUT_all": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"F1", "x":1.25, "y":0}, {"label":"F2", "x":2.25, "y":0}, {"label":"F3", "x":3.25, "y":0}, {"label":"F4", "x":4.25, "y":0}, {"label":"F5", "x":5.5, "y":0}, {"label":"F6", "x":6.5, "y":0}, {"label":"F7", "x":7.5, "y":0}, {"label":"F8", "x":8.5, "y":0}, {"label":"F9", "x":9.75, "y":0}, {"label":"F10", "x":10.75, "y":0}, {"label":"F11", "x":11.75, "y":0}, {"label":"F12", "x":12.75, "y":0}, {"x":14, "y":0}, {"label":"PrtSc", "x":15.25, "y":0}, {"label":"Scroll Lock", "x":16.25, "y":0}, {"label":"Pause", "x":17.25, "y":0}, {"label":"~", "x":0, "y":1.25}, {"label":"!", "x":1, "y":1.25}, {"label":"@", "x":2, "y":1.25}, {"label":"#", "x":3, "y":1.25}, {"label":"$", "x":4, "y":1.25}, {"label":"%", "x":5, "y":1.25}, {"label":"^", "x":6, "y":1.25}, {"label":"&", "x":7, "y":1.25}, {"label":"*", "x":8, "y":1.25}, {"label":"(", "x":9, "y":1.25}, {"label":")", "x":10, "y":1.25}, {"label":"_", "x":11, "y":1.25}, {"label":"+", "x":12, "y":1.25}, {"x":13, "y":1.25}, {"x":14, "y":1.25}, {"label":"Insert", "x":15.25, "y":1.25}, {"label":"Home", "x":16.25, "y":1.25}, {"label":"PgUp", "x":17.25, "y":1.25}, {"label":"Tab", "x":0, "y":2.25, "w":1.5}, {"label":"Q", "x":1.5, "y":2.25}, {"label":"W", "x":2.5, "y":2.25}, {"label":"E", "x":3.5, "y":2.25}, {"label":"R", "x":4.5, "y":2.25}, {"label":"T", "x":5.5, "y":2.25}, {"label":"Y", "x":6.5, "y":2.25}, {"label":"U", "x":7.5, "y":2.25}, {"label":"I", "x":8.5, "y":2.25}, {"label":"O", "x":9.5, "y":2.25}, {"label":"P", "x":10.5, "y":2.25}, {"label":"{", "x":11.5, "y":2.25}, {"label":"}", "x":12.5, "y":2.25}, {"label":"|", "x":13.5, "y":2.25, "w":1.5}, {"label":"Delete", "x":15.25, "y":2.25}, {"label":"End", "x":16.25, "y":2.25}, {"label":"PgDn", "x":17.25, "y":2.25}, {"label":"Caps Lock", "x":0, "y":3.25, "w":1.75}, {"label":"A", "x":1.75, "y":3.25}, {"label":"S", "x":2.75, "y":3.25}, {"label":"D", "x":3.75, "y":3.25}, {"label":"F", "x":4.75, "y":3.25}, {"label":"G", "x":5.75, "y":3.25}, {"label":"H", "x":6.75, "y":3.25}, {"label":"J", "x":7.75, "y":3.25}, {"label":"K", "x":8.75, "y":3.25}, {"label":"L", "x":9.75, "y":3.25}, {"label":":", "x":10.75, "y":3.25}, {"label":"\"", "x":11.75, "y":3.25}, {"x":12.75, "y":3.25}, {"x":13.75, "y":3.25, "w":1.25}, {"label":"Shift", "x":0, "y":4.25, "w":1.25}, {"x":1.25, "y":4.25}, {"label":"Z", "x":2.25, "y":4.25}, {"label":"X", "x":3.25, "y":4.25}, {"label":"C", "x":4.25, "y":4.25}, {"label":"V", "x":5.25, "y":4.25}, {"label":"B", "x":6.25, "y":4.25}, {"label":"N", "x":7.25, "y":4.25}, {"label":"M", "x":8.25, "y":4.25}, {"label":"<", "x":9.25, "y":4.25}, {"label":">", "x":10.25, "y":4.25}, {"label":"?", "x":11.25, "y":4.25}, {"label":"Shift", "x":12.25, "y":4.25, "w":1.75}, {"x":14, "y":4.25}, {"label":"\u2191", "x":16.25, "y":4.25}, {"label":"Ctrl", "x":0, "y":5.25, "w":1.25}, {"label":"Win", "x":1.25, "y":5.25, "w":1.25}, {"label":"Alt", "x":2.5, "y":5.25, "w":1.25}, {"x":3.75, "y":5.25, "w":6.25}, {"label":"Alt", "x":10, "y":5.25, "w":1.25}, {"label":"Fn", "x":11.25, "y":5.25, "w":1.25}, {"label":"Menu", "x":12.5, "y":5.25, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":5.25, "w":1.25}, {"label":"\u2190", "x":15.25, "y":5.25}, {"label":"\u2193", "x":16.25, "y":5.25}, {"label":"\u2192", "x":17.25, "y":5.25}]
+ }
+ }
+
+ }
diff --git a/keyboards/cannonkeys/devastatingtkl/keymaps/default/keymap.c b/keyboards/cannonkeys/devastatingtkl/keymaps/default/keymap.c
new file mode 100644
index 000000000..6b870b6e1
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/keymaps/default/keymap.c
@@ -0,0 +1,41 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_H
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_BASE] = LAYOUT_all(
+ 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_MPLY, 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_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_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, 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_TRNS, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [_FN1] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, KC_TRNS, BL_TOGG, BL_DEC, BL_INC,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/cannonkeys/devastatingtkl/keymaps/via/keymap.c b/keyboards/cannonkeys/devastatingtkl/keymaps/via/keymap.c
new file mode 100644
index 000000000..33f15901e
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/keymaps/via/keymap.c
@@ -0,0 +1,59 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_H
+enum layer_names {
+ _BASE,
+ _FN1,
+ _FN2,
+ _FN3
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_BASE] = LAYOUT_all(
+ 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_MPLY, 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_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_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, 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_TRNS, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [_FN1] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, KC_TRNS, BL_TOGG, BL_DEC, BL_INC,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ [_FN2] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ [_FN3] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
+
+};
diff --git a/keyboards/cannonkeys/devastatingtkl/keymaps/via/rules.mk b/keyboards/cannonkeys/devastatingtkl/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/cannonkeys/devastatingtkl/mcuconf.h b/keyboards/cannonkeys/devastatingtkl/mcuconf.h
new file mode 100644
index 000000000..048eb4df6
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/mcuconf.h
@@ -0,0 +1,176 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+/*
+ * STM32F0xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F0xx_MCUCONF
+// #define STM32F070xB
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_HSI_ENABLED TRUE
+#define STM32_HSI14_ENABLED TRUE
+#define STM32_HSI48_ENABLED FALSE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
+#define STM32_PREDIV_VALUE 1
+#define STM32_PLLMUL_VALUE 12
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE STM32_PPRE_DIV1
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_USBSW STM32_USBSW_HSI48
+#define STM32_CECSW STM32_CECSW_HSI
+#define STM32_I2C1SW STM32_I2C1SW_HSI
+#define STM32_USART1SW STM32_USART1SW_PCLK
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 2
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 2
+#define STM32_GPT_TIM2_IRQ_PRIORITY 2
+#define STM32_GPT_TIM3_IRQ_PRIORITY 2
+#define STM32_GPT_TIM14_IRQ_PRIORITY 2
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 TRUE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C2_IRQ_PRIORITY 3
+#define STM32_I2C_USE_DMA TRUE
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 3
+#define STM32_ICU_TIM2_IRQ_PRIORITY 3
+#define STM32_ICU_TIM3_IRQ_PRIORITY 3
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 TRUE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 3
+#define STM32_PWM_TIM2_IRQ_PRIORITY 3
+#define STM32_PWM_TIM3_IRQ_PRIORITY 3
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 3
+#define STM32_SERIAL_USART2_PRIORITY 3
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 2
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 3
+#define STM32_UART_USART2_IRQ_PRIORITY 3
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/cannonkeys/devastatingtkl/readme.md b/keyboards/cannonkeys/devastatingtkl/readme.md
new file mode 100644
index 000000000..9d706ab65
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/readme.md
@@ -0,0 +1,12 @@
+# CannonKeys DevastatingTKL
+
+DevastatingTKL Keyboard
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: STM32F072CBT6
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/devastatingtkl:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/cannonkeys/devastatingtkl/rules.mk b/keyboards/cannonkeys/devastatingtkl/rules.mk
new file mode 100644
index 000000000..9c3d0179f
--- /dev/null
+++ b/keyboards/cannonkeys/devastatingtkl/rules.mk
@@ -0,0 +1,20 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+NKRO_ENABLE = yes # USB Nkey Rollover
+CUSTOM_MATRIX = no # Custom matrix file
+BACKLIGHT_ENABLE = yes
+RGBLIGHT_ENABLE = yes
+WS2812_DRIVER = spi
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/cannonkeys/rekt1800/chconf.h b/keyboards/cannonkeys/rekt1800/chconf.h
new file mode 100644
index 000000000..03f63da36
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/chconf.h
@@ -0,0 +1,714 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file rt/templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_6_0_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_ST_RESOLUTION)
+#define CH_CFG_ST_RESOLUTION 32
+#endif
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_CFG_ST_FREQUENCY)
+#define CH_CFG_ST_FREQUENCY 10000
+#endif
+
+/**
+ * @brief Time intervals data size.
+ * @note Allowed values are 16, 32 or 64 bits.
+ */
+#if !defined(CH_CFG_INTERVALS_SIZE)
+#define CH_CFG_INTERVALS_SIZE 32
+#endif
+
+/**
+ * @brief Time types data size.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_TIME_TYPES_SIZE)
+#define CH_CFG_TIME_TYPES_SIZE 32
+#endif
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#if !defined(CH_CFG_ST_TIMEDELTA)
+#define CH_CFG_ST_TIMEDELTA 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#if !defined(CH_CFG_TIME_QUANTUM)
+#define CH_CFG_TIME_QUANTUM 0
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#if !defined(CH_CFG_MEMCORE_SIZE)
+#define CH_CFG_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#if !defined(CH_CFG_NO_IDLE_THREAD)
+#define CH_CFG_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_OPTIMIZE_SPEED)
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_TM)
+#define CH_CFG_USE_TM FALSE
+#endif
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_REGISTRY)
+#define CH_CFG_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_WAITEXIT)
+#define CH_CFG_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES)
+#define CH_CFG_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MUTEXES)
+#define CH_CFG_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_CONDVARS)
+#define CH_CFG_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_EVENTS)
+#define CH_CFG_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MESSAGES)
+#define CH_CFG_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
+#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_MAILBOXES)
+#define CH_CFG_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMCORE)
+#define CH_CFG_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_CFG_USE_HEAP)
+#define CH_CFG_USE_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#define CH_CFG_USE_MEMPOOLS FALSE
+#endif
+
+/**
+ * @brief Objects FIFOs APIs.
+ * @details If enabled then the objects FIFOs APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#define CH_CFG_USE_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Pipes APIs.
+ * @details If enabled then the pipes APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_PIPES)
+#define CH_CFG_USE_PIPES FALSE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#if !defined(CH_CFG_USE_DYNAMIC)
+#define CH_CFG_USE_DYNAMIC FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Objects factory options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Objects Factory APIs.
+ * @details If enabled then the objects factory APIs are included in the
+ * kernel.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_CFG_USE_FACTORY)
+#define CH_CFG_USE_FACTORY FALSE
+#endif
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
+#endif
+
+/**
+ * @brief Enables the registry of generic objects.
+ */
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
+#endif
+
+/**
+ * @brief Enables factory for generic buffers.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#define CH_CFG_FACTORY_SEMAPHORES FALSE
+#endif
+
+/**
+ * @brief Enables factory for mailboxes.
+ */
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#define CH_CFG_FACTORY_MAILBOXES FALSE
+#endif
+
+/**
+ * @brief Enables factory for objects FIFOs.
+ */
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Enables factory for Pipes.
+ */
+#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_PIPES FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_STATISTICS)
+#define CH_DBG_STATISTICS FALSE
+#endif
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_MASK)
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+#endif
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING)
+#define CH_DBG_THREADS_PROFILING FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System structure extension.
+ * @details User fields added to the end of the @p ch_system_t structure.
+ */
+#define CH_CFG_SYSTEM_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief System initialization hook.
+ * @details User initialization code added to the @p chSysInit() function
+ * just before interrupts are enabled globally.
+ */
+#define CH_CFG_SYSTEM_INIT_HOOK() { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p _thread_init() function.
+ *
+ * @note It is invoked from within @p _thread_init() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/rekt1800/config.h b/keyboards/cannonkeys/rekt1800/config.h
new file mode 100644
index 000000000..1fc60bef9
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/config.h
@@ -0,0 +1,74 @@
+/*
+Copyright 2015 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/>.
+*/
+
+#pragma once
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCA04
+#define PRODUCT_ID 0x2377
+#define DEVICE_VER 0x0001
+#define MANUFACTURER CannonKeys
+#define PRODUCT Rekt1800
+#define DESCRIPTION Rekt1800 Keyboard
+
+/* key matrix size */
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 19
+
+#define MATRIX_COL_PINS { B12, A14, A15, B3, B4, B5, B6, B7, B8, B9, A7, B0, B1, B2, B10, A3, A4, A5, C15 }
+#define MATRIX_ROW_PINS { C13, C14, A0, A1, A2, B11 }
+#define DIODE_DIRECTION COL2ROW
+
+#define BACKLIGHT_PIN A6
+#define BACKLIGHT_PWM_DRIVER PWMD3
+#define BACKLIGHT_PWM_CHANNEL 1
+#define BACKLIGHT_PAL_MODE 1
+#define BACKLIGHT_LEVELS 6
+#define BACKLIGHT_BREATHING
+#define BREATHING_PERIOD 6
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 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
+
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
+
+/*
+ * 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
diff --git a/keyboards/cannonkeys/rekt1800/halconf.h b/keyboards/cannonkeys/rekt1800/halconf.h
new file mode 100644
index 000000000..921803762
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/halconf.h
@@ -0,0 +1,525 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#define _CHIBIOS_HAL_CONF_
+#define _CHIBIOS_HAL_CONF_VER_7_0_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the cryptographic subsystem.
+ */
+#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
+#define HAL_USE_CRY FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C FALSE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SIO subsystem.
+ */
+#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
+#define HAL_USE_SIO FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the TRNG subsystem.
+ */
+#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
+#define HAL_USE_TRNG FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/**
+ * @brief Enables the WSPI subsystem.
+ */
+#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
+#define HAL_USE_WSPI FALSE
+#endif
+
+/*===========================================================================*/
+/* PAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define PAL_USE_CALLBACKS FALSE
+#endif
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/**
+ * @brief Enforces the driver to use direct callbacks rather than OSAL events.
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define CAN_ENFORCE_USE_CALLBACKS FALSE
+#endif
+
+/*===========================================================================*/
+/* CRY driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the SW fall-back of the cryptographic driver.
+ * @details When enabled, this option, activates a fall-back software
+ * implementation for algorithms not supported by the underlying
+ * hardware.
+ * @note Fall-back implementations may not be present for all algorithms.
+ */
+#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_USE_FALLBACK FALSE
+#endif
+
+/**
+ * @brief Makes the driver forcibly use the fall-back implementations.
+ */
+#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_ENFORCE_FALLBACK FALSE
+#endif
+
+/*===========================================================================*/
+/* DAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
+#define DAC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define DAC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the zero-copy API.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief OCR initialization constant for V20 cards.
+ */
+#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR_V20 0x50FF8000U
+#endif
+
+/**
+ * @brief OCR initialization constant for non-V20 cards.
+ */
+#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR 0x80100000U
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables circular transfers APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
+#define SPI_USE_CIRCULAR FALSE
+#endif
+
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/**
+ * @brief Handling method for SPI CS line.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+/*===========================================================================*/
+/* WSPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
+#define WSPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define WSPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/cannonkeys/rekt1800/info.json b/keyboards/cannonkeys/rekt1800/info.json
new file mode 100644
index 000000000..32942f1ec
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/info.json
@@ -0,0 +1,12 @@
+{
+ "keyboard_name": "Rekt1800",
+ "url": "https://cannonkeys.com",
+ "maintainer": "awkannan",
+ "width": 19.5,
+ "height": 6.5,
+ "layouts": {
+ "LAYOUT_all": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"F1", "x":1.25, "y":0}, {"label":"F2", "x":2.25, "y":0}, {"label":"F3", "x":3.25, "y":0}, {"label":"F4", "x":4.25, "y":0}, {"label":"F5", "x":5.5, "y":0}, {"label":"F6", "x":6.5, "y":0}, {"label":"F7", "x":7.5, "y":0}, {"label":"F8", "x":8.5, "y":0}, {"label":"F9", "x":9.75, "y":0}, {"label":"F10", "x":10.75, "y":0}, {"label":"F11", "x":11.75, "y":0}, {"label":"F12", "x":12.75, "y":0}, {"x":14, "y":0}, {"label":"PrtSc", "x":15.5, "y":0}, {"label":"Scroll Lock", "x":16.5, "y":0}, {"label":"Pause", "x":17.5, "y":0}, {"x":18.5, "y":0}, {"label":"~", "x":0, "y":1.25}, {"label":"!", "x":1, "y":1.25}, {"label":"@", "x":2, "y":1.25}, {"label":"#", "x":3, "y":1.25}, {"label":"$", "x":4, "y":1.25}, {"label":"%", "x":5, "y":1.25}, {"label":"^", "x":6, "y":1.25}, {"label":"&", "x":7, "y":1.25}, {"label":"*", "x":8, "y":1.25}, {"label":"(", "x":9, "y":1.25}, {"label":")", "x":10, "y":1.25}, {"label":"_", "x":11, "y":1.25}, {"label":"+", "x":12, "y":1.25}, {"x":13, "y":1.25}, {"x":14, "y":1.25}, {"label":"Insert", "x":15.5, "y":1.25}, {"label":"Home", "x":16.5, "y":1.25}, {"label":"PgUp", "x":17.5, "y":1.25}, {"x":18.5, "y":1.25}, {"label":"Tab", "x":0, "y":2.25, "w":1.5}, {"label":"Q", "x":1.5, "y":2.25}, {"label":"W", "x":2.5, "y":2.25}, {"label":"E", "x":3.5, "y":2.25}, {"label":"R", "x":4.5, "y":2.25}, {"label":"T", "x":5.5, "y":2.25}, {"label":"Y", "x":6.5, "y":2.25}, {"label":"U", "x":7.5, "y":2.25}, {"label":"I", "x":8.5, "y":2.25}, {"label":"O", "x":9.5, "y":2.25}, {"label":"P", "x":10.5, "y":2.25}, {"label":"{", "x":11.5, "y":2.25}, {"label":"}", "x":12.5, "y":2.25}, {"label":"|", "x":13.5, "y":2.25, "w":1.5}, {"label":"Delete", "x":15.5, "y":2.25}, {"label":"End", "x":16.5, "y":2.25}, {"label":"PgDn", "x":17.5, "y":2.25}, {"x":18.5, "y":2.25}, {"label":"Caps Lock", "x":0, "y":3.25, "w":1.75}, {"label":"A", "x":1.75, "y":3.25}, {"label":"S", "x":2.75, "y":3.25}, {"label":"D", "x":3.75, "y":3.25}, {"label":"F", "x":4.75, "y":3.25}, {"label":"G", "x":5.75, "y":3.25}, {"label":"H", "x":6.75, "y":3.25}, {"label":"J", "x":7.75, "y":3.25}, {"label":"K", "x":8.75, "y":3.25}, {"label":"L", "x":9.75, "y":3.25}, {"label":":", "x":10.75, "y":3.25}, {"label":"\"", "x":11.75, "y":3.25}, {"x":12.75, "y":3.25}, {"label":"Enter", "x":13.75, "y":3.25, "w":1.25}, {"x":15.5, "y":3.25}, {"x":16.5, "y":3.25}, {"x":17.5, "y":3.25}, {"x":18.5, "y":3.25}, {"label":"Shift", "x":0, "y":4.25, "w":1.25}, {"x":1.25, "y":4.25}, {"label":"Z", "x":2.25, "y":4.25}, {"label":"X", "x":3.25, "y":4.25}, {"label":"C", "x":4.25, "y":4.25}, {"label":"V", "x":5.25, "y":4.25}, {"label":"B", "x":6.25, "y":4.25}, {"label":"N", "x":7.25, "y":4.25}, {"label":"M", "x":8.25, "y":4.25}, {"label":"<", "x":9.25, "y":4.25}, {"label":">", "x":10.25, "y":4.25}, {"label":"?", "x":11.25, "y":4.25}, {"label":"Shift", "x":12.25, "y":4.25, "w":1.75}, {"label":"\u2191", "x":14.25, "y":4.5}, {"x":15.5, "y":4.25}, {"x":16.5, "y":4.25}, {"x":17.5, "y":4.25}, {"x":18.5, "y":4.25, "h":2}, {"label":"Ctrl", "x":0, "y":5.25, "w":1.25}, {"label":"Alt", "x":1.25, "y":5.25, "w":1.25}, {"label":"Alt", "x":2.5, "y":5.25, "w":1.25}, {"x":3.75, "y":5.25, "w":6.25}, {"label":"Alt", "x":10, "y":5.25, "w":1.5}, {"label":"Ctrl", "x":11.5, "y":5.25, "w":1.5}, {"label":"\u2190", "x":13.25, "y":5.5}, {"label":"\u2193", "x":14.25, "y":5.5}, {"label":"\u2192", "x":15.25, "y":5.5}, {"x":16.5, "y":5.25}, {"x":17.5, "y":5.25}]
+ }
+ }
+}
diff --git a/keyboards/cannonkeys/rekt1800/keymaps/default/keymap.c b/keyboards/cannonkeys/rekt1800/keymaps/default/keymap.c
new file mode 100644
index 000000000..98e16e700
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/keymaps/default/keymap.c
@@ -0,0 +1,48 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_BASE] = LAYOUT_all(
+ 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_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ 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_BSPC, 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_P7, KC_P8, KC_P9, KC_PPLS,
+ 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_NUBS, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LSFT, KC_NUHS, 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_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ ),
+
+ [_FN1] = LAYOUT_all(
+ 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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ BL_BRTG, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ BL_INC, BL_DEC, BL_TOGG, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ )
+};
diff --git a/keyboards/cannonkeys/rekt1800/keymaps/via/keymap.c b/keyboards/cannonkeys/rekt1800/keymaps/via/keymap.c
new file mode 100644
index 000000000..d267302b3
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/keymaps/via/keymap.c
@@ -0,0 +1,58 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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.
+enum layer_names {
+ _BASE,
+ _FN1,
+ _FN2,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_BASE] = LAYOUT_all(
+ 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_DEL, KC_INS, KC_PGUP, KC_PGDN,
+ 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_BSPC, 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_P7, KC_P8, KC_P9, KC_PPLS,
+ 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_NUBS, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LSFT, KC_NUHS, 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_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ ),
+
+ [_FN1] = LAYOUT_all(
+ 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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ BL_BRTG, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ BL_INC, BL_DEC, BL_TOGG, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+
+ [_FN2] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ )
+};
diff --git a/keyboards/cannonkeys/rekt1800/keymaps/via/rules.mk b/keyboards/cannonkeys/rekt1800/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/cannonkeys/rekt1800/mcuconf.h b/keyboards/cannonkeys/rekt1800/mcuconf.h
new file mode 100644
index 000000000..43fe0a462
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/mcuconf.h
@@ -0,0 +1,176 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+/*
+ * STM32F0xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F0xx_MCUCONF
+// #define STM32F070xB
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_HSI_ENABLED TRUE
+#define STM32_HSI14_ENABLED TRUE
+#define STM32_HSI48_ENABLED FALSE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
+#define STM32_PREDIV_VALUE 1
+#define STM32_PLLMUL_VALUE 12
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE STM32_PPRE_DIV1
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_USBSW STM32_USBSW_HSI48
+#define STM32_CECSW STM32_CECSW_HSI
+#define STM32_I2C1SW STM32_I2C1SW_HSI
+#define STM32_USART1SW STM32_USART1SW_PCLK
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 2
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 2
+#define STM32_GPT_TIM2_IRQ_PRIORITY 2
+#define STM32_GPT_TIM3_IRQ_PRIORITY 2
+#define STM32_GPT_TIM14_IRQ_PRIORITY 2
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 FALSE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C2_IRQ_PRIORITY 3
+#define STM32_I2C_USE_DMA TRUE
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 3
+#define STM32_ICU_TIM2_IRQ_PRIORITY 3
+#define STM32_ICU_TIM3_IRQ_PRIORITY 3
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 TRUE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 3
+#define STM32_PWM_TIM2_IRQ_PRIORITY 3
+#define STM32_PWM_TIM3_IRQ_PRIORITY 3
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 3
+#define STM32_SERIAL_USART2_PRIORITY 3
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 2
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 3
+#define STM32_UART_USART2_IRQ_PRIORITY 3
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/cannonkeys/rekt1800/readme.md b/keyboards/cannonkeys/rekt1800/readme.md
new file mode 100644
index 000000000..5daf03b9a
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/readme.md
@@ -0,0 +1,10 @@
+# CannonKeys Rekt1800
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: STM32F072CBT6
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/rekt1800:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/cannonkeys/rekt1800/rekt1800.c b/keyboards/cannonkeys/rekt1800/rekt1800.c
new file mode 100644
index 000000000..3a8673b95
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/rekt1800.c
@@ -0,0 +1 @@
+#include "rekt1800.h"
diff --git a/keyboards/cannonkeys/rekt1800/rekt1800.h b/keyboards/cannonkeys/rekt1800/rekt1800.h
new file mode 100644
index 000000000..18d72dfdf
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/rekt1800.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "quantum.h"
+#define K_NO KC_NO
+
+#define LAYOUT_all( \
+ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K014, K015, K016, K017, K018, \
+ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117, K118, \
+ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, K215, K216, K217, K218, \
+ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K314, K315, K316, K317, K318, \
+ K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K414, K415, K416, K417, K418, \
+ K500, K501, K502, K506, K510, K511, K512, K514, K515, K516, K517 \
+) { \
+ { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K_NO, K014, K015, K016, K017, K018 }, \
+ { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, K115, K116, K117, K118 }, \
+ { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K_NO, K214, K215, K216, K217, K218 }, \
+ { K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K_NO, K314, K315, K316, K317, K318 }, \
+ { K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K_NO, K414, K415, K416, K417, K418 }, \
+ { K500, K501, K502, K_NO, K_NO, K_NO, K506, K_NO, K_NO, K_NO, K510, K511, K512, K_NO, K514, K515, K516, K517, K_NO } \
+}
diff --git a/keyboards/cannonkeys/rekt1800/rules.mk b/keyboards/cannonkeys/rekt1800/rules.mk
new file mode 100644
index 000000000..c8f75b7dd
--- /dev/null
+++ b/keyboards/cannonkeys/rekt1800/rules.mk
@@ -0,0 +1,19 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+NKRO_ENABLE = yes # USB Nkey Rollover
+CUSTOM_MATRIX = no # Custom matrix file
+BACKLIGHT_ENABLE = yes
+RGBLIGHT_ENABLE = no
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/doro67/multi/keymaps/konstantin/rules.mk b/keyboards/doro67/multi/keymaps/konstantin/rules.mk
index 041d32114..c3a73fd84 100644
--- a/keyboards/doro67/multi/keymaps/konstantin/rules.mk
+++ b/keyboards/doro67/multi/keymaps/konstantin/rules.mk
@@ -3,6 +3,7 @@ BOOTMAGIC_ENABLE = no
COMMAND_ENABLE = yes
CONSOLE_ENABLE = yes
EXTRAKEY_ENABLE = yes
+GRAVE_ESC_ENABLE = no
MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
SPACE_CADET_ENABLE = no
diff --git a/keyboards/dp60/config.h b/keyboards/dp60/config.h
index 29d5e3c2a..3875d303e 100644
--- a/keyboards/dp60/config.h
+++ b/keyboards/dp60/config.h
@@ -16,7 +16,7 @@
/* key matrix size */
#define MATRIX_ROWS 5
-#define MATRIX_COLS 14
+#define MATRIX_COLS 15
#define UNUSED_PINS
#define DIODE_DIRECTION COL2ROW
@@ -49,7 +49,3 @@
#define DRIVER_1_LED_TOTAL 36
#define DRIVER_2_LED_TOTAL 36
#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
-
-#if defined(VIA_ENABLE)
-# define DYNAMIC_KEYMAP_LAYER_COUNT 2
-#endif
diff --git a/keyboards/dp60/keymaps/via/keymap.c b/keyboards/dp60/keymaps/via/keymap.c
index 2e2694326..822705576 100644
--- a/keyboards/dp60/keymaps/via/keymap.c
+++ b/keyboards/dp60/keymaps/via/keymap.c
@@ -14,4 +14,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______,_______,_______,_______,_______,KC_LEFT,KC_DOWN, KC_UP,KC_RIGHT,KC_HOME,KC_END,_______,
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
_______,_______,_______, _______, _______,_______,TG(0),_______),
+
+ [2] = LAYOUT_60_ansi_split_bs_rshift(
+ _______, _______,_______, _______,_______, _______,_______, _______,_______, _______,_______, _______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
+ _______,_______,_______, _______, _______,_______,_______,_______),
+
+ [3] = LAYOUT_60_ansi_split_bs_rshift(
+ _______, _______,_______, _______,_______, _______,_______, _______,_______, _______,_______, _______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______,_______,
+ _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,
+ _______,_______,_______, _______, _______,_______,_______,_______)
}; \ No newline at end of file
diff --git a/keyboards/dp60/keymaps/via/rules.mk b/keyboards/dp60/keymaps/via/rules.mk
index 036bd6d1c..36b7ba9cb 100644
--- a/keyboards/dp60/keymaps/via/rules.mk
+++ b/keyboards/dp60/keymaps/via/rules.mk
@@ -1 +1,2 @@
-VIA_ENABLE = yes \ No newline at end of file
+VIA_ENABLE = yes
+LTO_ENABLE = yes
diff --git a/keyboards/ergodox_ez/keymaps/pvinis/keymap.c b/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
index dc804d632..c4b1b3b82 100644
--- a/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/pvinis/keymap.c
@@ -1,38 +1,36 @@
// pvinis ergodox ez
-// ,------------------------------------. ,------------------------------------.
-// | | | | | | | | | | | | | | | |
-// |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
-// | | | | | | | | | | | | | | | |
-// |------+----+----+----x----x----| | | |----x----x----+----+----+------|
-// | | | | | | |----| |----| | | | | | |
-// |------+----+----+----x----x----| | | |----x----x----+----+----+------|
-// | | | | | | | | | | | | | | | |
-// `------+----+----+----+----+---------' `---------+----+----+----+----+------'
-// | | | | | | | | | | | |
-// `------------------------' `------------------------'
-// ,---------. ,---------.
-// | | | | | |
-// ,----+----+----| |----+----+----.
-// | | | | | | | |
-// | | |----| |----| | |
-// | | | | | | | |
-// `--------------' `--------------'
-
+// ,------------------------------------. ┌────┬────┬────┬────┬────┬────┬──────┐
+// | | | | | | | | │ │ │ │ │ │ │ │
+// |------+----+----+----+----+---------| ├────┼────┼────┼────┼────┼────┼──────┤
+// | | | | | | | | │ │ │ │ │ │ │ │
+// |------+----+----+----x----x----| | │ ├────╆━━━━╅────┼────┼────┼──────┤
+// | | | | | | |----| ├────┤ ┃ ┃ │ │ │ │
+// |------+----+----+----x----x----| | │ ├────╄━━━━╃────┼────┼────┼──────┤
+// | | | | | | | | │ │ │ │ │ │ │ │
+// `------+----+----+----+----+---------' └────┴────┼────┼────┼────┼────┼────┬─┘
+// | | | | | | │ │ │ │ │ │
+// `------------------------' └────┴────┴────┴────┴────┘
+// ,---------. ┌────┬────┐
+// | | | │ │ │
+// ,----+----+----| ├────┼────┼────┐
+// | | | | │ │ │ │
+// | | |----| ├────┤ │ │
+// | | | | │ │ │ │
+// `--------------' └────┴────┴────┘
#include QMK_KEYBOARD_H
#include "pvinis.h"
#include "mousekey.h"
-
// layers
enum {
- MOUSE = 8,
+ MOUSE = 8,
};
// extra keys
enum {
- NONE = 30,
- TD_LAYR, // SYSCTL and MOUSE layer switch
+ NONE = 30,
+ TD_LAYR, // SYSCTL and MOUSE layer switch
};
// application selection
@@ -41,158 +39,170 @@ enum {
#define AP_XCOD ALLM(KC_X)
#define AP_MSGR ALLM(KC_M)
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // ,------------------------------------. ,------------------------------------.
- // |4xFLSH| | | | | |Opt | | | | | | | | |
- // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
- // | Tab | | | | | | | | | | | | | | |
- // |------+----+----+----x----x----| | | |----x----x----+----+----+------|
- // |EscCtl| | | | | |----| |----| | | | | | Ent |
- // |------+----+----+----x----x----| | | |----x----x----+----+----+------|
- // |LShift| | | | | | | | | | | | | |RShift|
- // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
- // | | | | |Cmd | | | | | | |
- // `------------------------' `------------------------'
- // ,---------. ,---------.
- // |QWER| | | | |
- // ,----+----+----| |----+----+----.
- // | Ba | L | | | | | |
- // | ck |Shi |----| |----| |Spc |
- // | spc| ft | | | | | |
- // `--------------' `--------------'
- [LR_BASE] = LAYOUT_ergodox_pretty_wrapper(
- TD_3FLS, _______, _______, _______, _______, _______, KC_LALT, _______, _______, _______, _______, _______, _______, _______,
- KC_TAB , _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- PV_ESCC, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ENT ,
- KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT,
- _______, _______, _______, KC_LGUI, SYMBOL , SYSCTL , KC_RALT, _______, _______, _______,
- QWERTY , CARPALX, _______, _______,
- _______, _______,
- KC_BSPC, _______, _______, _______, _______, KC_SPC
- ),
+ // ,------------------------------------. ,------------------------------------.
+ // |4xFLSH| | | | | |Opt | | | | | | | | |
+ // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
+ // | Tab | | | | | | | | | | | | | | |
+ // |------+----+----+----x----x----| | | |----x----x----+----+----+------|
+ // |EscCtl| | | | | |----| |----| | | | | | Ent |
+ // |------+----+----+----x----x----| | | |----x----x----+----+----+------|
+ // |LShift| | | | | | | | | | | | | |RShift|
+ // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
+ // | | | |Cmd |LOWR| |RASE|RAlt| | | |
+ // `------------------------' `------------------------'
+ // ,---------. ,---------.
+ // |QWER| | | | |
+ // ,----+----+----| |----+----+----.
+ // | Ba | L | | | | | |
+ // | ck |Shi |----| |----| |Spc |
+ // | spc| ft | | | | | |
+ // `--------------' `--------------'
+ [LR_BASE] = LAYOUT_ergodox_pretty_wrapper(
+ // clang-format off
+ TD_3FLS, _______, _______, _______, _______, _______, KC_LALT, _______, _______, _______, _______, _______, _______, _______,
+ KC_TAB , _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ PV_ESCC, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ENT ,
+ KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT,
+ _______, _______, _______, KC_LGUI, SYMBOL , SYSCTL , KC_RALT, _______, _______, _______,
+ QWERTY , CARPALX, _______, _______,
+ _______, _______,
+ KC_BSPC, _______, _______, _______, _______, KC_SPC
+ // clang-format on
+ ),
- // ,------------------------------------. ,------------------------------------.
- // | | NUMBERS_L | | | - | NUMBERS_R | = |
- // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
- // | | | [ | | ] | | |
- // |------+ | | | | +------|
- // | | QWERTY_L |----| |----| QWERTY_R | |
- // |------+ | ( | | ) | +------|
- // | | | | | | | |
- // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
- // | | ` | | | | | | | | ' | |
- // `------------------------' `------------------------'
- // ,---------. ,---------.
- // | | | | | |
- // ,----+----+----| |----+----+----.
- // | | | | | | | |
- // | | |----| |----| | |
- // | | | | | | | |
- // `--------------' `--------------'
- // See `users/pvinis/pvinis.h`
- [LR_QWERTY] = LAYOUT_ergodox_pretty_wrapper(
- _______, ________________NUMBERS_L__________________, _______, KC_MINS, ________________NUMBERS_R__________________, KC_EQL ,
- _______, _________________QWERTY_L1_________________, KC_LBRC, KC_RBRC, _________________QWERTY_R1_________________, _______,
- _______, _____________MOD_QWERTY_L2_________________, _____________MOD_QWERTY_R2_________________, _______,
- _______, _________________QWERTY_L3_________________, KC_LPRN, KC_RPRN, _________________QWERTY_R3_________________, _______,
- _______, KC_GRV, _______, _______, _______, _______, _______, _______, KC_QUOT , _______,
- _______, _______, _______, _______,
- _______, _______,
- _______, _______, _______, _______, _______, _______
+ // ,------------------------------------. ,------------------------------------.
+ // | | NUMBERS_L | | | - | NUMBERS_R | = |
+ // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
+ // | | | [ | | ] | | |
+ // |------+ | | | | +------|
+ // | | QWERTY_L |----| |----| QWERTY_R | |
+ // |------+ | ( | | ) | +------|
+ // | | | | | | | |
+ // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
+ // | | ` | | | | | | | | ' | |
+ // `------------------------' `------------------------'
+ // ,---------. ,---------.
+ // | | | | | |
+ // ,----+----+----| |----+----+----.
+ // | | | | | | | |
+ // | | |----| |----| | |
+ // | | | | | | | |
+ // `--------------' `--------------'
+ // See `users/pvinis/pvinis.h`
+ [LR_QWERTY] = LAYOUT_ergodox_pretty_wrapper(
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, _______, KC_MINS, ________________NUMBERS_R__________________, KC_EQL ,
+ _______, _________________QWERTY_L1_________________, KC_LBRC, KC_RBRC, _________________QWERTY_R1_________________, _______,
+ _______, _____________MOD_QWERTY_L2_________________, _____________MOD_QWERTY_R2_________________, _______,
+ _______, _________________QWERTY_L3_________________, KC_LPRN, KC_RPRN, _________________QWERTY_R3_________________, _______,
+ _______, KC_GRV, _______, _______, _______, _______, _______, _______, KC_QUOT , _______,
+ _______, _______, _______, _______,
+ _______, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format off
),
- // ,------------------------------------. ,------------------------------------.
- // | | NUMBERS_L | | | | NUMBERS_R | |
- // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
- // | | | | | | | |
- // |------+ | | | | +------|
- // | | CARPALX_L |----| |----| CARPALX_R | |
- // |------+ | | | | +------|
- // | | | | | | | |
- // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
- // | | | | | | | | | | | |
- // `------------------------' `------------------------'
- // ,---------. ,---------.
- // | | | | | |
- // ,----+----+----| |----+----+----.
- // | | | | | | | |
- // | | |----| |----| | |
- // | | | | | | | |
- // `--------------' `--------------'
- // See `users/pvinis/pvinis.h`
+ // ,------------------------------------. ,------------------------------------.
+ // | | NUMBERS_L | | | | NUMBERS_R | |
+ // |------+----+----+----+----+---------| |----+----+----+----+----+----+------|
+ // | | | | | | | |
+ // |------+ | | | | +------|
+ // | | CARPALX_L |----| |----| CARPALX_R | |
+ // |------+ | | | | +------|
+ // | | | | | | | |
+ // `------+----+----+----+----+---------' `---------+----+----+----+----+------'
+ // | | | | | | | | | | | |
+ // `------------------------' `------------------------'
+ // ,---------. ,---------.
+ // | | | | | |
+ // ,----+----+----| |----+----+----.
+ // | | | | | | | |
+ // | | |----| |----| | |
+ // | | | | | | | |
+ // `--------------' `--------------'
+ // See `users/pvinis/pvinis.h`
[LR_CARPALX] = LAYOUT_ergodox_pretty_wrapper(
- _______, ________________NUMBERS_L__________________, _______, _______, ________________NUMBERS_R__________________, _______,
- _______, ________________CARPALX_L1_________________, _______, _______, ________________CARPALX_R1_________________, _______,
- _______, ________________CARPALX_L2_________________, ________________CARPALX_R2_________________, _______,
- _______, ________________CARPALX_L3_________________, _______, _______, ________________CARPALX_R3_________________, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______,
- _______, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, _______, _______, ________________NUMBERS_R__________________, _______,
+ _______, ________________CARPALX_L1_________________, _______, _______, ________________CARPALX_R1_________________, _______,
+ _______, ________________CARPALX_L2_________________, ________________CARPALX_R2_________________, _______,
+ _______, ________________CARPALX_L3_________________, _______, _______, ________________CARPALX_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- // See `users/pvinis/pvinis.h`
- [LR_SYMBOL] = LAYOUT_ergodox_pretty_wrapper(
- _______, ______________________F_L__________________, KC_F11 , KC_F12 , ______________________F_R__________________, _______,
- _______, _________________SYMBOL_L1_________________, _______, _______, _________________SYMBOL_R1_________________, _______,
- _______, _________________SYMBOL_L2_________________, _________________SYMBOL_R2_________________, _______,
- _______, _________________SYMBOL_L3_________________, _______, _______, _________________SYMBOL_R3_________________, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______,
- _______, _______,
- _______, _______, _______, _______, _______, _______
+ // See `users/pvinis/pvinis.h`
+ [LR_SYMBOL] = LAYOUT_ergodox_pretty_wrapper(
+ // clang-format off
+ _______, ______________________F_L__________________, KC_F11 , KC_F12 , ______________________F_R__________________, _______,
+ _______, _________________SYMBOL_L1_________________, _______, _______, _________________SYMBOL_R1_________________, _______,
+ _______, _________________SYMBOL_L2_________________, _________________SYMBOL_R2_________________, _______,
+ _______, _________________SYMBOL_L3_________________, _______, _______, _________________SYMBOL_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format off
),
- // See `users/pvinis/pvinis.h`
+ // See `users/pvinis/pvinis.h`
[LR_SYSCTL] = LAYOUT_ergodox_pretty_wrapper(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _________________SYSCTL_R1_________________, _______,
- _______, _______, _______, _______, _______, _______, _________________SYSCTL_R2_________________, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _________________SYSCTL_R3_________________, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ // clang-format off
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _________________SYSCTL_R1_________________, _______,
+ _______, _______, _______, _______, _______, _______, _________________SYSCTL_R2_________________, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _________________SYSCTL_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______,
- _______, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ _______, _______, _______, _______,
+ _______, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- // See `users/pvinis/pvinis.h`
- [LR_KBCTL] = LAYOUT_ergodox_pretty_wrapper(
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R1_________________, XXXXXXX,
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R2_________________, XXXXXXX,
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R3_________________, XXXXXXX,
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // See `users/pvinis/pvinis.h`
+ [LR_KBCTL] = LAYOUT_ergodox_pretty_wrapper(
+ // clang-format off
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R1_________________, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R2_________________, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, __________________KBCTL_R3_________________, 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
+ // clang-format on
+ ),
-/* MOUSE
- * a keymap to control my system.
- *
- * ,--------------------------------------------------. ,--------------------------------------------------.
- * | ^ | | | | | | | | | | | | | | |
- * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
- * | | | | | | | | | | | | MsUp | | | |
- * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
- * | | | | | | |------| |------| |MsLeft| MsDn |MsRght| | |
- * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
- * | | | | | | | | | | | | | | | |
- * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
- * | | | | | | | | | | | |
- * `----------------------------------' `----------------------------------'
- * ,-------------. ,-------------.
- * | | | | |MidClk|
- * ,------|------|------| |------+------+------.
- * | | | | | |Left |Right |
- * | | |------| |------| Click| Click|
- * | | | ^ | | | | |
- * `--------------------' `--------------------'
- */
- [MOUSE] = LAYOUT_ergodox_pretty(
+ /* MOUSE
+ * a keymap to control my system.
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | ^ | | | | | | | | | | | | | | |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | | | | | | | | | | | MsUp | | | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | | | | | |------| |------| |MsLeft| MsDn |MsRght| | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | | | | | | | | | | | | | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | | | | |
+ * `----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | |MidClk|
+ * ,------|------|------| |------+------+------.
+ * | | | | | |Left |Right |
+ * | | |------| |------| Click| Click|
+ * | | | ^ | | | | |
+ * `--------------------' `--------------------'
+ */
+ [MOUSE] = LAYOUT_ergodox_pretty(
+ // clang-format off
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
@@ -212,53 +222,54 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
,KC_NO ,KC_NO
,KC_NO
,KC_NO ,KC_NO ,KC_NO
- ),
+ // clang-format on
+ ),
};
-
// keyboard initialization
-void keyboard_post_init_user_local(void) {
- ergodox_led_all_on();
- for (int i = LED_BRIGHTNESS_HI; i > LED_BRIGHTNESS_LO; i--) {
- ergodox_led_all_set(i);
- wait_ms(5);
- }
- wait_ms(1000);
- for (int i = LED_BRIGHTNESS_LO; i > 0; i--) {
- ergodox_led_all_set(i);
- wait_ms(10);
- }
- ergodox_led_all_off();
+void keyboard_post_init_user_keymap(void) {
+ ergodox_led_all_on();
+ for (int i = LED_BRIGHTNESS_HI; i > LED_BRIGHTNESS_LO; i--) {
+ ergodox_led_all_set(i);
+ wait_ms(5);
+ }
+ wait_ms(1000);
+ for (int i = LED_BRIGHTNESS_LO; i > 0; i--) {
+ ergodox_led_all_set(i);
+ wait_ms(10);
+ }
+ ergodox_led_all_off();
- // restore default brightness for future use
- ergodox_led_all_set(LED_BRIGHTNESS_HI);
+ // restore default brightness for future use
+ ergodox_led_all_set(LED_BRIGHTNESS_HI);
}
// light up leds based on the layer
-uint32_t layer_state_set_user_local(uint32_t state) {
- ergodox_right_led_1_off();
- ergodox_right_led_2_off();
- ergodox_right_led_3_off();
- switch (biton32(state)) {
- case LR_SYSCTL:
- ergodox_right_led_3_on(); // blue
- break;
- case LR_KBCTL:
- ergodox_right_led_1_on(); // red
- break;
- case LR_SYMBOL:
- ergodox_right_led_2_on(); // green
- break;
- default: break;
- }
- return state;
+uint32_t layer_state_set_user_keymap(uint32_t state) {
+ ergodox_right_led_1_off();
+ ergodox_right_led_2_off();
+ ergodox_right_led_3_off();
+ switch (biton32(state)) {
+ case LR_SYSCTL:
+ ergodox_right_led_3_on(); // blue
+ break;
+ case LR_KBCTL:
+ ergodox_right_led_1_on(); // red
+ break;
+ case LR_SYMBOL:
+ ergodox_right_led_2_on(); // green
+ break;
+ default:
+ break;
+ }
+ return state;
}
// extra keys
// const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
- // switch (id) {
- // }
- // return MACRO_NONE;
+// switch (id) {
+// }
+// return MACRO_NONE;
// }
// tap dances
@@ -325,6 +336,6 @@ uint32_t layer_state_set_user_local(uint32_t state) {
// }
// 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 ),
+// [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 ),
// };
diff --git a/keyboards/georgi/keymaps/dennytom/README.md b/keyboards/georgi/keymaps/dennytom/README.md
new file mode 100644
index 000000000..14bc1d204
--- /dev/null
+++ b/keyboards/georgi/keymaps/dennytom/README.md
@@ -0,0 +1,11 @@
+# # Dennytom's Georgi Layout
+
+This keymap is using a custom chording engine. Head out to my (DennyTom) user space to find the source files and details.
+
+To make a real keymap from the JSON file, run
+
+```sh
+python3 parser.py keymap_def.json keymap.c
+```
+
+Likely will change with use. I enjoy the modifiers on the "home row". \ No newline at end of file
diff --git a/keyboards/georgi/keymaps/dennytom/keymap.c b/keyboards/georgi/keymaps/dennytom/keymap.c
new file mode 100644
index 000000000..2e0191774
--- /dev/null
+++ b/keyboards/georgi/keymaps/dennytom/keymap.c
@@ -0,0 +1,1208 @@
+#include QMK_KEYBOARD_H
+
+#define H_TOP1 ((HASH_TYPE) 1 << 0)
+#define H_TOP2 ((HASH_TYPE) 1 << 1)
+#define H_TOP3 ((HASH_TYPE) 1 << 2)
+#define H_TOP4 ((HASH_TYPE) 1 << 3)
+#define H_TOP5 ((HASH_TYPE) 1 << 4)
+#define H_TOP6 ((HASH_TYPE) 1 << 5)
+#define H_TOP7 ((HASH_TYPE) 1 << 6)
+#define H_TOP8 ((HASH_TYPE) 1 << 7)
+#define H_TOP9 ((HASH_TYPE) 1 << 8)
+#define H_TOP10 ((HASH_TYPE) 1 << 9)
+#define H_TOP11 ((HASH_TYPE) 1 << 10)
+#define H_TOP12 ((HASH_TYPE) 1 << 11)
+#define H_BOT1 ((HASH_TYPE) 1 << 12)
+#define H_BOT2 ((HASH_TYPE) 1 << 13)
+#define H_BOT3 ((HASH_TYPE) 1 << 14)
+#define H_BOT4 ((HASH_TYPE) 1 << 15)
+#define H_BOT5 ((HASH_TYPE) 1 << 16)
+#define H_BOT6 ((HASH_TYPE) 1 << 17)
+#define H_BOT7 ((HASH_TYPE) 1 << 18)
+#define H_BOT8 ((HASH_TYPE) 1 << 19)
+#define H_BOT9 ((HASH_TYPE) 1 << 20)
+#define H_BOT10 ((HASH_TYPE) 1 << 21)
+#define H_BOT11 ((HASH_TYPE) 1 << 22)
+#define H_BOT12 ((HASH_TYPE) 1 << 23)
+#define H_THU1 ((HASH_TYPE) 1 << 24)
+#define H_THU2 ((HASH_TYPE) 1 << 25)
+#define H_THU3 ((HASH_TYPE) 1 << 26)
+#define H_THU4 ((HASH_TYPE) 1 << 27)
+#define H_THU5 ((HASH_TYPE) 1 << 28)
+#define H_THU6 ((HASH_TYPE) 1 << 29)
+
+enum internal_keycodes {
+ TOP1 = SAFE_RANGE,
+ TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP10, TOP11, TOP12, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT10, BOT11, BOT12, THU1, THU2, THU3, THU4, THU5, THU6,
+ FIRST_INTERNAL_KEYCODE = TOP1,
+ LAST_INTERNAL_KEYCODE = THU6
+};
+
+enum pseudolayers {
+ ALWAYS_ON, QWERTY, NUM, FNC, NAV, MOUSE
+};
+
+#define CHORD_TIMEOUT 100
+#define DANCE_TIMEOUT 200
+#define LEADER_TIMEOUT 750
+#define TAP_TIMEOUT 50
+#define LONG_PRESS_MULTIPLIER 3
+#define DYNAMIC_MACRO_MAX_LENGTH 20
+#define COMMAND_MAX_LENGTH 5
+#define STRING_MAX_LENGTH 16
+#define LEADER_MAX_LENGTH 5
+#define HASH_TYPE uint32_t
+#define NUMBER_OF_KEYS 30
+#define DEFAULT_PSEUDOLAYER QWERTY
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_georgi(TOP1, TOP2, TOP3, TOP4, TOP5, TOP6, TOP7, TOP8, TOP9, TOP10, TOP11, TOP12, BOT1, BOT2, BOT3, BOT4, BOT5, BOT6, BOT7, BOT8, BOT9, BOT10, BOT11, BOT12, THU1, THU2, THU3, THU4, THU5, THU6),
+};
+size_t keymapsCount = 1;
+
+uint8_t keycodes_buffer_array[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+uint8_t command_buffer[] = {
+ 0, 0, 0, 0, 0
+};
+
+uint16_t leader_buffer[] = {
+ 0, 0, 0, 0, 0
+};
+
+uint8_t dynamic_macro_buffer[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+enum chord_states {
+ IDLE,
+ READY,
+ ACTIVATED,
+ DEACTIVATED,
+ PRESS_FROM_ACTIVE,
+ FINISHED_FROM_ACTIVE,
+ IDLE_IN_DANCE,
+ READY_IN_DANCE,
+ FINISHED,
+ LOCKED,
+ READY_LOCKED,
+ RESTART,
+ IN_ONE_SHOT
+};
+
+struct Chord {
+ uint32_t keycodes_hash;
+ uint8_t pseudolayer;
+ uint8_t* state;
+ uint8_t* counter;
+ uint16_t value1;
+ uint8_t value2;
+ void (*function) (const struct Chord*);
+};
+
+uint8_t current_pseudolayer = DEFAULT_PSEUDOLAYER;
+bool lock_next = false;
+uint16_t chord_timer = 0;
+uint16_t dance_timer = 0;
+bool autoshift_mode = true;
+uint8_t keycode_index = 0;
+uint8_t command_mode = 0;
+uint8_t command_ind = 0;
+bool in_leader_mode = false;
+uint8_t leader_ind = 0;
+uint16_t leader_timer = 0;
+uint8_t dynamic_macro_mode = false;
+uint8_t dynamic_macro_ind = 0;
+bool a_key_went_through = false;
+struct Chord* last_chord = NULL;
+
+bool handle_US_ANSI_shifted_keys(int16_t keycode, bool in) {
+ bool is_US_ANSI_shifted = true;
+
+ int16_t regular_keycode = KC_NO;
+ switch (keycode) {
+ case KC_TILDE:
+ regular_keycode = KC_GRAVE;
+ break;
+ case KC_EXCLAIM:
+ regular_keycode = KC_1;
+ break;
+ case KC_AT:
+ regular_keycode = KC_2;
+ break;
+ case KC_HASH:
+ regular_keycode = KC_3;
+ break;
+ case KC_DOLLAR:
+ regular_keycode = KC_4;
+ break;
+ case KC_PERCENT:
+ regular_keycode = KC_5;
+ break;
+ case KC_CIRCUMFLEX:
+ regular_keycode = KC_6;
+ break;
+ case KC_AMPERSAND:
+ regular_keycode = KC_7;
+ break;
+ case KC_ASTERISK:
+ regular_keycode = KC_8;
+ break;
+ case KC_LEFT_PAREN:
+ regular_keycode = KC_9;
+ break;
+ case KC_RIGHT_PAREN:
+ regular_keycode = KC_0;
+ break;
+ case KC_UNDERSCORE:
+ regular_keycode = KC_MINUS;
+ break;
+ case KC_PLUS:
+ regular_keycode = KC_EQUAL;
+ break;
+ case KC_LEFT_CURLY_BRACE:
+ regular_keycode = KC_LBRACKET;
+ break;
+ case KC_RIGHT_CURLY_BRACE:
+ regular_keycode = KC_RBRACKET;
+ break;
+ case KC_PIPE:
+ regular_keycode = KC_BSLASH;
+ break;
+ case KC_COLON:
+ regular_keycode = KC_SCOLON;
+ break;
+ case KC_DOUBLE_QUOTE:
+ regular_keycode = KC_QUOTE;
+ break;
+ case KC_LEFT_ANGLE_BRACKET:
+ regular_keycode = KC_COMMA;
+ break;
+ case KC_RIGHT_ANGLE_BRACKET:
+ regular_keycode = KC_DOT;
+ break;
+ case KC_QUESTION:
+ regular_keycode = KC_SLASH;
+ break;
+ default:
+ is_US_ANSI_shifted = false;
+ }
+ if (is_US_ANSI_shifted) {
+ if (in) {
+ register_code(KC_LSFT);
+ register_code(regular_keycode);
+ } else {
+ unregister_code(regular_keycode);
+ unregister_code(KC_LSFT);
+ }
+ }
+ return is_US_ANSI_shifted;
+}
+
+void key_in(int16_t keycode) {
+ if (command_mode == 1 && command_ind < COMMAND_MAX_LENGTH) {
+ command_buffer[command_ind] = keycode;
+ command_ind++;
+ a_key_went_through = true;
+ } else if (in_leader_mode && leader_ind < LEADER_MAX_LENGTH) {
+ leader_buffer[leader_ind] = keycode;
+ leader_ind++;
+ a_key_went_through = true;
+ } else if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = keycode;
+ dynamic_macro_ind++;
+ a_key_went_through = true;
+ } else {
+ if (!handle_US_ANSI_shifted_keys(keycode, true)) {
+ register_code(keycode);
+ }
+ send_keyboard_report();
+ a_key_went_through = true;
+ }
+}
+
+void key_out(int16_t keycode) {
+ if (command_mode == 0) {
+ if (!handle_US_ANSI_shifted_keys(keycode, false)) {
+ if (command_mode == 0 && in_leader_mode == false && dynamic_macro_mode == false) {
+ unregister_code(keycode);
+ }
+ }
+ send_keyboard_report();
+ }
+}
+
+void tap_key(int16_t keycode) {
+ key_in(keycode);
+ wait_ms(TAP_TIMEOUT);
+ key_out(keycode);
+}
+const char * const strings[] PROGMEM = {
+
+};
+void single_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value1);
+ break;
+ case DEACTIVATED:
+ key_out(self->value1);
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ key_out(self->value1);
+ break;
+ default:
+ break;
+ }
+}
+
+void key_layer_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value2;
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_mod_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value2);
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ key_out(self->value2);
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_key_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value2);
+ break;
+ case RESTART:
+ key_out(self->value2);
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance_impl(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ *self->counter = 0;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED_FROM_ACTIVE:
+ if (*self->counter == (LONG_PRESS_MULTIPLIER - 2)) {
+ key_in(KC_LSFT);
+ tap_key(self->value1);
+ key_out(KC_LSFT);
+ *self->state = IDLE;
+ // the skip to IDLE is usually just a lag optimization,
+ // in this case it has a logic function, on a short
+ // press (still longer than a tap) the key does not get shifted
+ } else {
+ *self->counter += 1;
+ *self->state = PRESS_FROM_ACTIVE;
+ dance_timer = timer_read();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance(const struct Chord* self) {
+ if (autoshift_mode) {
+ autoshift_dance_impl(self);
+ } else {
+ single_dance(self);
+ }
+}
+
+void autoshift_toggle(const struct Chord* self){
+ if (*self->state == ACTIVATED) {
+ autoshift_mode = !autoshift_mode;
+ *self->state = IDLE;
+ }
+}
+
+void temp_pseudolayer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value1;
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ current_pseudolayer = self->pseudolayer;
+ break;
+ default:
+ break;
+ }
+}
+
+void temp_pseudolayer_alt(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value1;
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->value2;
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ current_pseudolayer = self->value2;
+ break;
+ default:
+ break;
+ }
+}
+
+void perm_pseudolayer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ current_pseudolayer = self->value1;
+ *self->state = IDLE;
+ }
+}
+
+void switch_layer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ layer_move(self->value1);
+ *self->state = IDLE;
+ }
+}
+
+void lock(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ lock_next = true;
+ *self->state = IDLE;
+ }
+}
+
+void one_shot_key(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ key_in(self->value1);
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value1);
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ key_out(self->value1);
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void one_shot_layer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->value1;
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ current_pseudolayer = self->value1;
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ current_pseudolayer = self->pseudolayer;
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void command(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ command_mode++;
+ *self->state = IDLE;
+ }
+}
+
+bool identical(uint16_t* buffer1, uint16_t* buffer2) {
+ bool same = true;
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ same = same && (buffer1[i] == buffer2[i]);
+ }
+ return same;
+}
+
+void leader(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ in_leader_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_record(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ dynamic_macro_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_next(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = 0;
+ dynamic_macro_ind++;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_end(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode) {
+ dynamic_macro_mode = false;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_play(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ int ind_start = 0;
+ while (ind_start < DYNAMIC_MACRO_MAX_LENGTH) {
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ break;
+ }
+ register_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ wait_ms(TAP_TIMEOUT);
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ ind_start = i + 1;
+ break;
+ }
+ unregister_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ *self->state = IDLE;
+ }
+}
+
+void string_in(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ char buffer[STRING_MAX_LENGTH];
+ strcpy_P(buffer, (char*)pgm_read_word(&(strings[self->value1])));
+ send_string(buffer);
+ }
+}
+
+void clear(const struct Chord* self);
+
+void reset_keyboard_kb(void){
+#ifdef WATCHDOG_ENABLE
+ MCUSR = 0;
+ wdt_disable();
+ wdt_reset();
+#endif
+ reset_keyboard();
+}
+
+void reset(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ reset_keyboard_kb();
+ }
+}
+
+uint8_t state_0 = IDLE;
+const struct Chord chord_0 PROGMEM = {H_TOP1 + H_TOP12 + H_BOT1 + H_BOT12, ALWAYS_ON, &state_0, NULL, 0, 0, clear};
+uint8_t state_1 = IDLE;
+const struct Chord chord_1 PROGMEM = {H_TOP6 + H_TOP7 + H_BOT6 + H_BOT7, ALWAYS_ON, &state_1, NULL, 0, 0, command};
+uint8_t state_2 = IDLE;
+const struct Chord chord_2 PROGMEM = {H_TOP1, QWERTY, &state_2, NULL, KC_ESC, 0, single_dance};
+uint8_t state_3 = IDLE;
+const struct Chord chord_3 PROGMEM = {H_TOP2, QWERTY, &state_3, NULL, KC_Q, 0, single_dance};
+uint8_t state_4 = IDLE;
+const struct Chord chord_4 PROGMEM = {H_TOP3, QWERTY, &state_4, NULL, KC_W, 0, single_dance};
+uint8_t state_5 = IDLE;
+const struct Chord chord_5 PROGMEM = {H_TOP4, QWERTY, &state_5, NULL, KC_E, 0, single_dance};
+uint8_t state_6 = IDLE;
+const struct Chord chord_6 PROGMEM = {H_TOP5, QWERTY, &state_6, NULL, KC_R, 0, single_dance};
+uint8_t state_7 = IDLE;
+const struct Chord chord_7 PROGMEM = {H_TOP6, QWERTY, &state_7, NULL, KC_T, 0, single_dance};
+uint8_t state_8 = IDLE;
+const struct Chord chord_8 PROGMEM = {H_TOP7, QWERTY, &state_8, NULL, KC_Y, 0, single_dance};
+uint8_t state_9 = IDLE;
+const struct Chord chord_9 PROGMEM = {H_TOP8, QWERTY, &state_9, NULL, KC_U, 0, single_dance};
+uint8_t state_10 = IDLE;
+const struct Chord chord_10 PROGMEM = {H_TOP9, QWERTY, &state_10, NULL, KC_I, 0, single_dance};
+uint8_t state_11 = IDLE;
+const struct Chord chord_11 PROGMEM = {H_TOP10, QWERTY, &state_11, NULL, KC_O, 0, single_dance};
+uint8_t state_12 = IDLE;
+const struct Chord chord_12 PROGMEM = {H_TOP11, QWERTY, &state_12, NULL, KC_P, 0, single_dance};
+uint8_t state_13 = IDLE;
+const struct Chord chord_13 PROGMEM = {H_TOP12, QWERTY, &state_13, NULL, KC_BSLASH, 0, single_dance};
+uint8_t state_14 = IDLE;
+const struct Chord chord_14 PROGMEM = {H_TOP1 + H_BOT1, QWERTY, &state_14, NULL, KC_INS, 0, single_dance};
+uint8_t state_15 = IDLE;
+const struct Chord chord_15 PROGMEM = {H_TOP2 + H_BOT2, QWERTY, &state_15, NULL, KC_A, 0, single_dance};
+uint8_t state_16 = IDLE;
+uint8_t counter_16 = 0;
+const struct Chord chord_16 PROGMEM = {H_TOP3 + H_BOT3, QWERTY, &state_16, &counter_16, KC_S, KC_LALT, key_key_dance};
+uint8_t state_17 = IDLE;
+const struct Chord chord_17 PROGMEM = {H_TOP4 + H_BOT4, QWERTY, &state_17, NULL, KC_D, KC_LCTL, key_mod_dance};
+uint8_t state_18 = IDLE;
+const struct Chord chord_18 PROGMEM = {H_TOP5 + H_BOT5, QWERTY, &state_18, NULL, KC_F, KC_LSFT, key_mod_dance};
+uint8_t state_19 = IDLE;
+uint8_t counter_19 = 0;
+const struct Chord chord_19 PROGMEM = {H_TOP6 + H_BOT6, QWERTY, &state_19, &counter_19, KC_G, KC_LGUI, key_key_dance};
+uint8_t state_20 = IDLE;
+uint8_t counter_20 = 0;
+const struct Chord chord_20 PROGMEM = {H_TOP7 + H_BOT7, QWERTY, &state_20, &counter_20, KC_H, KC_RGUI, key_key_dance};
+uint8_t state_21 = IDLE;
+const struct Chord chord_21 PROGMEM = {H_TOP8 + H_BOT8, QWERTY, &state_21, NULL, KC_J, KC_RSFT, key_mod_dance};
+uint8_t state_22 = IDLE;
+const struct Chord chord_22 PROGMEM = {H_TOP9 + H_BOT9, QWERTY, &state_22, NULL, KC_K, KC_RCTL, key_mod_dance};
+uint8_t state_23 = IDLE;
+uint8_t counter_23 = 0;
+const struct Chord chord_23 PROGMEM = {H_TOP10 + H_BOT10, QWERTY, &state_23, &counter_23, KC_L, KC_RALT, key_key_dance};
+uint8_t state_24 = IDLE;
+const struct Chord chord_24 PROGMEM = {H_TOP11 + H_BOT11, QWERTY, &state_24, NULL, KC_SCOLON, 0, single_dance};
+uint8_t state_25 = IDLE;
+const struct Chord chord_25 PROGMEM = {H_BOT1, QWERTY, &state_25, NULL, KC_TAB, 0, single_dance};
+uint8_t state_26 = IDLE;
+const struct Chord chord_26 PROGMEM = {H_BOT2, QWERTY, &state_26, NULL, KC_Z, 0, single_dance};
+uint8_t state_27 = IDLE;
+const struct Chord chord_27 PROGMEM = {H_BOT3, QWERTY, &state_27, NULL, KC_X, 0, single_dance};
+uint8_t state_28 = IDLE;
+const struct Chord chord_28 PROGMEM = {H_BOT4, QWERTY, &state_28, NULL, KC_C, 0, single_dance};
+uint8_t state_29 = IDLE;
+const struct Chord chord_29 PROGMEM = {H_BOT5, QWERTY, &state_29, NULL, KC_V, 0, single_dance};
+uint8_t state_30 = IDLE;
+const struct Chord chord_30 PROGMEM = {H_BOT6, QWERTY, &state_30, NULL, KC_B, 0, single_dance};
+uint8_t state_31 = IDLE;
+const struct Chord chord_31 PROGMEM = {H_BOT7, QWERTY, &state_31, NULL, KC_N, 0, single_dance};
+uint8_t state_32 = IDLE;
+const struct Chord chord_32 PROGMEM = {H_BOT8, QWERTY, &state_32, NULL, KC_M, 0, single_dance};
+uint8_t state_33 = IDLE;
+const struct Chord chord_33 PROGMEM = {H_BOT9, QWERTY, &state_33, NULL, KC_COMMA, 0, single_dance};
+uint8_t state_34 = IDLE;
+const struct Chord chord_34 PROGMEM = {H_BOT10, QWERTY, &state_34, NULL, KC_DOT, 0, single_dance};
+uint8_t state_35 = IDLE;
+const struct Chord chord_35 PROGMEM = {H_BOT11, QWERTY, &state_35, NULL, KC_SLASH, 0, single_dance};
+uint8_t state_36 = IDLE;
+const struct Chord chord_36 PROGMEM = {H_BOT12, QWERTY, &state_36, NULL, KC_QUOTE, 0, single_dance};
+uint8_t state_37 = IDLE;
+const struct Chord chord_37 PROGMEM = {H_THU1, QWERTY, &state_37, NULL, KC_ENTER, 0, single_dance};
+uint8_t state_38 = IDLE;
+uint8_t counter_38 = 0;
+const struct Chord chord_38 PROGMEM = {H_THU2, QWERTY, &state_38, &counter_38, KC_SPC, NUM, key_layer_dance};
+uint8_t state_39 = IDLE;
+uint8_t counter_39 = 0;
+const struct Chord chord_39 PROGMEM = {H_THU3, QWERTY, &state_39, &counter_39, KC_BSPC, NAV, key_layer_dance};
+uint8_t state_40 = IDLE;
+const struct Chord chord_40 PROGMEM = {H_THU4, QWERTY, &state_40, NULL, KC_DEL, 0, single_dance};
+uint8_t state_41 = IDLE;
+uint8_t counter_41 = 0;
+const struct Chord chord_41 PROGMEM = {H_THU5, QWERTY, &state_41, &counter_41, KC_SPC, FNC, key_layer_dance};
+uint8_t state_42 = IDLE;
+const struct Chord chord_42 PROGMEM = {H_THU6, QWERTY, &state_42, NULL, KC_ENTER, 0, single_dance};
+uint8_t state_43 = IDLE;
+const struct Chord chord_43 PROGMEM = {H_THU2 + H_THU3, QWERTY, &state_43, NULL, MOUSE, 0, temp_pseudolayer};
+uint8_t state_44 = IDLE;
+const struct Chord chord_44 PROGMEM = {H_TOP1, NUM, &state_44, NULL, KC_GRAVE, 0, single_dance};
+uint8_t state_45 = IDLE;
+const struct Chord chord_45 PROGMEM = {H_TOP2, NUM, &state_45, NULL, KC_1, 0, single_dance};
+uint8_t state_46 = IDLE;
+const struct Chord chord_46 PROGMEM = {H_TOP3, NUM, &state_46, NULL, KC_2, 0, single_dance};
+uint8_t state_47 = IDLE;
+const struct Chord chord_47 PROGMEM = {H_TOP4, NUM, &state_47, NULL, KC_3, 0, single_dance};
+uint8_t state_48 = IDLE;
+const struct Chord chord_48 PROGMEM = {H_TOP5, NUM, &state_48, NULL, KC_4, 0, single_dance};
+uint8_t state_49 = IDLE;
+const struct Chord chord_49 PROGMEM = {H_TOP6, NUM, &state_49, NULL, KC_5, 0, single_dance};
+uint8_t state_50 = IDLE;
+const struct Chord chord_50 PROGMEM = {H_TOP7, NUM, &state_50, NULL, KC_6, 0, single_dance};
+uint8_t state_51 = IDLE;
+const struct Chord chord_51 PROGMEM = {H_TOP8, NUM, &state_51, NULL, KC_7, 0, single_dance};
+uint8_t state_52 = IDLE;
+const struct Chord chord_52 PROGMEM = {H_TOP9, NUM, &state_52, NULL, KC_8, 0, single_dance};
+uint8_t state_53 = IDLE;
+const struct Chord chord_53 PROGMEM = {H_TOP10, NUM, &state_53, NULL, KC_9, 0, single_dance};
+uint8_t state_54 = IDLE;
+const struct Chord chord_54 PROGMEM = {H_TOP11, NUM, &state_54, NULL, KC_0, 0, single_dance};
+uint8_t state_55 = IDLE;
+const struct Chord chord_55 PROGMEM = {H_TOP12, NUM, &state_55, NULL, KC_MINUS, 0, single_dance};
+uint8_t state_56 = IDLE;
+const struct Chord chord_56 PROGMEM = {H_TOP3 + H_BOT3, NUM, &state_56, NULL, KC_LALT, 0, single_dance};
+uint8_t state_57 = IDLE;
+const struct Chord chord_57 PROGMEM = {H_TOP4 + H_BOT4, NUM, &state_57, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_58 = IDLE;
+const struct Chord chord_58 PROGMEM = {H_TOP5 + H_BOT5, NUM, &state_58, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_59 = IDLE;
+const struct Chord chord_59 PROGMEM = {H_TOP6 + H_BOT6, NUM, &state_59, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_60 = IDLE;
+const struct Chord chord_60 PROGMEM = {H_TOP7 + H_BOT7, NUM, &state_60, NULL, KC_RGUI, 0, single_dance};
+uint8_t state_61 = IDLE;
+const struct Chord chord_61 PROGMEM = {H_TOP8 + H_BOT8, NUM, &state_61, NULL, KC_RSFT, 0, single_dance};
+uint8_t state_62 = IDLE;
+const struct Chord chord_62 PROGMEM = {H_TOP9 + H_BOT9, NUM, &state_62, NULL, KC_RCTL, 0, single_dance};
+uint8_t state_63 = IDLE;
+const struct Chord chord_63 PROGMEM = {H_TOP10 + H_BOT10, NUM, &state_63, NULL, KC_RALT, 0, single_dance};
+uint8_t state_64 = IDLE;
+const struct Chord chord_64 PROGMEM = {H_BOT12, NUM, &state_64, NULL, KC_EQUAL, 0, single_dance};
+uint8_t state_65 = IDLE;
+const struct Chord chord_65 PROGMEM = {H_TOP2, FNC, &state_65, NULL, KC_F1, 0, single_dance};
+uint8_t state_66 = IDLE;
+const struct Chord chord_66 PROGMEM = {H_TOP3, FNC, &state_66, NULL, KC_F2, 0, single_dance};
+uint8_t state_67 = IDLE;
+const struct Chord chord_67 PROGMEM = {H_TOP4, FNC, &state_67, NULL, KC_F3, 0, single_dance};
+uint8_t state_68 = IDLE;
+const struct Chord chord_68 PROGMEM = {H_TOP5, FNC, &state_68, NULL, KC_F4, 0, single_dance};
+uint8_t state_69 = IDLE;
+const struct Chord chord_69 PROGMEM = {H_TOP6, FNC, &state_69, NULL, KC_F5, 0, single_dance};
+uint8_t state_70 = IDLE;
+const struct Chord chord_70 PROGMEM = {H_TOP7, FNC, &state_70, NULL, KC_F6, 0, single_dance};
+uint8_t state_71 = IDLE;
+const struct Chord chord_71 PROGMEM = {H_TOP8, FNC, &state_71, NULL, KC_F7, 0, single_dance};
+uint8_t state_72 = IDLE;
+const struct Chord chord_72 PROGMEM = {H_TOP9, FNC, &state_72, NULL, KC_F8, 0, single_dance};
+uint8_t state_73 = IDLE;
+const struct Chord chord_73 PROGMEM = {H_TOP10, FNC, &state_73, NULL, KC_F9, 0, single_dance};
+uint8_t state_74 = IDLE;
+const struct Chord chord_74 PROGMEM = {H_TOP11, FNC, &state_74, NULL, KC_F10, 0, single_dance};
+uint8_t state_75 = IDLE;
+const struct Chord chord_75 PROGMEM = {H_TOP12, FNC, &state_75, NULL, KC_F11, 0, single_dance};
+uint8_t state_76 = IDLE;
+const struct Chord chord_76 PROGMEM = {H_TOP3 + H_BOT3, FNC, &state_76, NULL, KC_LALT, 0, single_dance};
+uint8_t state_77 = IDLE;
+const struct Chord chord_77 PROGMEM = {H_TOP4 + H_BOT4, FNC, &state_77, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_78 = IDLE;
+const struct Chord chord_78 PROGMEM = {H_TOP5 + H_BOT5, FNC, &state_78, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_79 = IDLE;
+const struct Chord chord_79 PROGMEM = {H_TOP6 + H_BOT6, FNC, &state_79, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_80 = IDLE;
+const struct Chord chord_80 PROGMEM = {H_TOP7 + H_BOT7, FNC, &state_80, NULL, KC_RGUI, 0, single_dance};
+uint8_t state_81 = IDLE;
+const struct Chord chord_81 PROGMEM = {H_TOP8 + H_BOT8, FNC, &state_81, NULL, KC_RSFT, 0, single_dance};
+uint8_t state_82 = IDLE;
+const struct Chord chord_82 PROGMEM = {H_TOP9 + H_BOT9, FNC, &state_82, NULL, KC_RCTL, 0, single_dance};
+uint8_t state_83 = IDLE;
+const struct Chord chord_83 PROGMEM = {H_TOP10 + H_BOT10, FNC, &state_83, NULL, KC_RALT, 0, single_dance};
+uint8_t state_84 = IDLE;
+const struct Chord chord_84 PROGMEM = {H_BOT12, FNC, &state_84, NULL, KC_F12, 0, single_dance};
+uint8_t state_85 = IDLE;
+const struct Chord chord_85 PROGMEM = {H_TOP8, NAV, &state_85, NULL, KC_HOME, 0, single_dance};
+uint8_t state_86 = IDLE;
+const struct Chord chord_86 PROGMEM = {H_TOP9, NAV, &state_86, NULL, KC_UP, 0, single_dance};
+uint8_t state_87 = IDLE;
+const struct Chord chord_87 PROGMEM = {H_TOP10, NAV, &state_87, NULL, KC_END, 0, single_dance};
+uint8_t state_88 = IDLE;
+const struct Chord chord_88 PROGMEM = {H_TOP11, NAV, &state_88, NULL, KC_PGUP, 0, single_dance};
+uint8_t state_89 = IDLE;
+const struct Chord chord_89 PROGMEM = {H_TOP3 + H_BOT3, NAV, &state_89, NULL, KC_LALT, 0, single_dance};
+uint8_t state_90 = IDLE;
+const struct Chord chord_90 PROGMEM = {H_TOP4 + H_BOT4, NAV, &state_90, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_91 = IDLE;
+const struct Chord chord_91 PROGMEM = {H_TOP5 + H_BOT5, NAV, &state_91, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_92 = IDLE;
+const struct Chord chord_92 PROGMEM = {H_TOP6 + H_BOT6, NAV, &state_92, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_93 = IDLE;
+const struct Chord chord_93 PROGMEM = {H_BOT8, NAV, &state_93, NULL, KC_LEFT, 0, single_dance};
+uint8_t state_94 = IDLE;
+const struct Chord chord_94 PROGMEM = {H_BOT9, NAV, &state_94, NULL, KC_DOWN, 0, single_dance};
+uint8_t state_95 = IDLE;
+const struct Chord chord_95 PROGMEM = {H_BOT10, NAV, &state_95, NULL, KC_RIGHT, 0, single_dance};
+uint8_t state_96 = IDLE;
+const struct Chord chord_96 PROGMEM = {H_BOT11, NAV, &state_96, NULL, KC_PGDN, 0, single_dance};
+uint8_t state_97 = IDLE;
+const struct Chord chord_97 PROGMEM = {H_TOP8, MOUSE, &state_97, NULL, KC_BTN1, 0, single_dance};
+uint8_t state_98 = IDLE;
+const struct Chord chord_98 PROGMEM = {H_TOP9, MOUSE, &state_98, NULL, KC_MS_U, 0, single_dance};
+uint8_t state_99 = IDLE;
+const struct Chord chord_99 PROGMEM = {H_TOP10, MOUSE, &state_99, NULL, KC_BTN2, 0, single_dance};
+uint8_t state_100 = IDLE;
+const struct Chord chord_100 PROGMEM = {H_TOP11, MOUSE, &state_100, NULL, KC_WH_U, 0, single_dance};
+uint8_t state_101 = IDLE;
+const struct Chord chord_101 PROGMEM = {H_TOP3 + H_BOT3, MOUSE, &state_101, NULL, KC_LALT, 0, single_dance};
+uint8_t state_102 = IDLE;
+const struct Chord chord_102 PROGMEM = {H_TOP4 + H_BOT4, MOUSE, &state_102, NULL, KC_LCTL, 0, single_dance};
+uint8_t state_103 = IDLE;
+const struct Chord chord_103 PROGMEM = {H_TOP5 + H_BOT5, MOUSE, &state_103, NULL, KC_LSFT, 0, single_dance};
+uint8_t state_104 = IDLE;
+const struct Chord chord_104 PROGMEM = {H_TOP6 + H_BOT6, MOUSE, &state_104, NULL, KC_LGUI, 0, single_dance};
+uint8_t state_105 = IDLE;
+const struct Chord chord_105 PROGMEM = {H_BOT8, MOUSE, &state_105, NULL, KC_MS_L, 0, single_dance};
+uint8_t state_106 = IDLE;
+const struct Chord chord_106 PROGMEM = {H_BOT9, MOUSE, &state_106, NULL, KC_MS_D, 0, single_dance};
+uint8_t state_107 = IDLE;
+const struct Chord chord_107 PROGMEM = {H_BOT10, MOUSE, &state_107, NULL, KC_MS_R, 0, single_dance};
+uint8_t state_108 = IDLE;
+const struct Chord chord_108 PROGMEM = {H_BOT11, MOUSE, &state_108, NULL, KC_WH_D, 0, single_dance};
+
+const struct Chord* const list_of_chords[] PROGMEM = {
+ &chord_0, &chord_1, &chord_2, &chord_3, &chord_4, &chord_5, &chord_6, &chord_7, &chord_8, &chord_9, &chord_10, &chord_11, &chord_12, &chord_13, &chord_14, &chord_15, &chord_16, &chord_17, &chord_18, &chord_19, &chord_20, &chord_21, &chord_22, &chord_23, &chord_24, &chord_25, &chord_26, &chord_27, &chord_28, &chord_29, &chord_30, &chord_31, &chord_32, &chord_33, &chord_34, &chord_35, &chord_36, &chord_37, &chord_38, &chord_39, &chord_40, &chord_41, &chord_42, &chord_43, &chord_44, &chord_45, &chord_46, &chord_47, &chord_48, &chord_49, &chord_50, &chord_51, &chord_52, &chord_53, &chord_54, &chord_55, &chord_56, &chord_57, &chord_58, &chord_59, &chord_60, &chord_61, &chord_62, &chord_63, &chord_64, &chord_65, &chord_66, &chord_67, &chord_68, &chord_69, &chord_70, &chord_71, &chord_72, &chord_73, &chord_74, &chord_75, &chord_76, &chord_77, &chord_78, &chord_79, &chord_80, &chord_81, &chord_82, &chord_83, &chord_84, &chord_85, &chord_86, &chord_87, &chord_88, &chord_89, &chord_90, &chord_91, &chord_92, &chord_93, &chord_94, &chord_95, &chord_96, &chord_97, &chord_98, &chord_99, &chord_100, &chord_101, &chord_102, &chord_103, &chord_104, &chord_105, &chord_106, &chord_107, &chord_108
+};
+
+const uint16_t** const leader_triggers PROGMEM = NULL;
+void (*leader_functions[]) (void) = {};
+
+#define NUMBER_OF_CHORDS 109
+#define NUMBER_OF_LEADER_COMBOS 0
+
+bool are_hashed_keycodes_in_sound(HASH_TYPE keycodes_hash, HASH_TYPE sound) {
+ return (keycodes_hash & sound) == keycodes_hash;
+}
+
+uint8_t keycode_to_index(uint16_t keycode) {
+ return keycode - FIRST_INTERNAL_KEYCODE;
+}
+
+void sound_keycode_array(uint16_t keycode) {
+ uint8_t index = keycode_to_index(keycode);
+ keycode_index++;
+ keycodes_buffer_array[index] = keycode_index;
+}
+
+void silence_keycode_hash_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ if (index_in_hash) {
+ uint8_t current_val = keycodes_buffer_array[i];
+ keycodes_buffer_array[i] = 0;
+ for (int j = 0; j < NUMBER_OF_KEYS; j++) {
+ if (keycodes_buffer_array[j] > current_val) {
+ keycodes_buffer_array[j]--;
+ }
+ }
+ keycode_index--;
+ }
+ }
+}
+
+bool are_hashed_keycodes_in_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ bool index_in_array = (bool) keycodes_buffer_array[i];
+ if (index_in_hash && !index_in_array) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void kill_one_shots(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == IN_ONE_SHOT) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ }
+}
+
+void process_finished_dances(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == ACTIVATED) {
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ } else if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = FINISHED;
+ chord->function(chord);
+ if (*chord->state == FINISHED) {
+ *chord->state = RESTART;
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ } else if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = FINISHED_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ }
+ }
+}
+
+uint8_t keycodes_buffer_array_min(uint8_t* first_keycode_index) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ if (keycodes_buffer_array[i] == 1) {
+ if (first_keycode_index != NULL) {
+ *first_keycode_index = (uint8_t) i;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void remove_subchords(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (!(*chord->state == READY || *chord->state == READY_IN_DANCE || *chord->state == READY_LOCKED)) {
+ continue;
+ }
+
+ struct Chord chord_storage_2;
+ struct Chord* chord_ptr_2;
+ struct Chord* chord_2;
+ for (int j = 0; j < NUMBER_OF_CHORDS; j++) {
+ if (i == j) {continue;}
+
+ chord_ptr_2 = (struct Chord*) pgm_read_word (&list_of_chords[j]);
+ memcpy_P(&chord_storage_2, chord_ptr_2, sizeof(struct Chord));
+ chord_2 = &chord_storage_2;
+
+ if (are_hashed_keycodes_in_sound(chord_2->keycodes_hash, chord->keycodes_hash)) {
+ if (*chord_2->state == READY) {
+ *chord_2->state = IDLE;
+ }
+ if (*chord_2->state == READY_IN_DANCE) {
+ *chord_2->state = IDLE_IN_DANCE;
+ }
+ if (*chord_2->state == READY_LOCKED) {
+ *chord_2->state = LOCKED;
+ }
+ }
+ }
+ }
+}
+
+void process_ready_chords(void) {
+ uint8_t first_keycode_index = 0;
+ while (keycodes_buffer_array_min(&first_keycode_index)) {
+ // find ready chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ // if the chord does not contain the first keycode
+ bool contains_first_keycode = ((uint32_t) 1 << first_keycode_index) & chord->keycodes_hash;
+ if (!contains_first_keycode) {
+ continue;
+ }
+
+ if (!are_hashed_keycodes_in_array(chord->keycodes_hash)){
+ continue;
+ }
+
+ if (*chord->state == LOCKED) {
+ *chord->state = READY_LOCKED;
+ continue;
+ }
+
+ if (!(chord->pseudolayer == current_pseudolayer || chord->pseudolayer == ALWAYS_ON)) {
+ continue;
+ }
+
+ if (*chord->state == IDLE) {
+ *chord->state = READY;
+ continue;
+ }
+
+ if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = READY_IN_DANCE;
+ }
+ }
+
+ // remove subchords
+ remove_subchords();
+
+ // execute logic
+ // this should be only one chord
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == READY_LOCKED) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ break;
+ }
+
+ if (*chord->state == READY || *chord->state == READY_IN_DANCE) {
+ if (last_chord && last_chord != chord) {
+ process_finished_dances();
+ }
+
+ bool lock_next_prev_state = lock_next;
+
+ *chord->state = ACTIVATED;
+ chord->function(chord);
+ dance_timer = timer_read();
+
+ if (lock_next && lock_next == lock_next_prev_state) {
+ lock_next = false;
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = LOCKED;
+ }
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ }
+ break;
+ }
+ }
+
+ // silence notes
+ silence_keycode_hash_array(chord->keycodes_hash);
+ }
+}
+
+void deactivate_active_chords(uint16_t keycode) {
+ HASH_TYPE hash = (HASH_TYPE)1 << (keycode - SAFE_RANGE);
+ bool broken;
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ broken = are_hashed_keycodes_in_sound(hash, chord->keycodes_hash);
+ if (!broken) {
+ continue;
+ }
+
+ switch (*chord->state) {
+ case ACTIVATED:
+ *chord->state = DEACTIVATED;
+ chord->function(chord);
+
+ if (*chord->state == DEACTIVATED) {
+ dance_timer = timer_read();
+ *chord->state = IDLE_IN_DANCE;
+ }
+ if (*chord->state != IN_ONE_SHOT) {
+ kill_one_shots();
+ }
+ break;
+ case PRESS_FROM_ACTIVE:
+ case FINISHED_FROM_ACTIVE:
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ kill_one_shots();
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+void process_command(void) {
+ command_mode = 0;
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ register_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ wait_ms(TAP_TIMEOUT);
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ unregister_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ command_buffer[i] = 0;
+ }
+ command_ind = 0;
+}
+
+void process_leader(void) {
+ in_leader_mode = false;
+ for (int i = 0; i < NUMBER_OF_LEADER_COMBOS; i++) {
+ uint16_t trigger[LEADER_MAX_LENGTH];
+ memcpy_P(trigger, leader_triggers[i], LEADER_MAX_LENGTH * sizeof(uint16_t));
+
+ if (identical(leader_buffer, trigger)) {
+ (*leader_functions[i])();
+ break;
+ }
+ }
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ leader_buffer[i] = 0;
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if (keycode < FIRST_INTERNAL_KEYCODE || keycode > LAST_INTERNAL_KEYCODE) {
+ return true;
+ }
+
+ if (record->event.pressed) {
+ sound_keycode_array(keycode);
+ } else {
+ process_ready_chords();
+ deactivate_active_chords(keycode);
+ }
+ chord_timer = timer_read();
+ leader_timer = timer_read();
+
+ return false;
+}
+
+void matrix_scan_user(void) {
+ bool chord_timer_expired = timer_elapsed(chord_timer) > CHORD_TIMEOUT;
+ if (chord_timer_expired && keycodes_buffer_array_min(NULL)) {
+ process_ready_chords();
+ }
+
+ bool dance_timer_expired = timer_elapsed(dance_timer) > DANCE_TIMEOUT;
+ if (dance_timer_expired) { // would love to have && in_dance but not sure how
+ process_finished_dances();
+ }
+
+ bool in_command_mode = command_mode == 2;
+ if (in_command_mode) {
+ process_command();
+ }
+
+ bool leader_timer_expired = timer_elapsed(leader_timer) > LEADER_TIMEOUT;
+ if (leader_timer_expired && in_leader_mode) {
+ process_leader();
+ }
+
+}
+
+void clear(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ // kill all chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ *chord->state = IDLE;
+
+ if (chord->counter) {
+ *chord->counter = 0;
+ }
+ }
+
+ // clear keyboard
+ clear_keyboard();
+ send_keyboard_report();
+
+ // switch to default pseudolayer
+ current_pseudolayer = DEFAULT_PSEUDOLAYER;
+
+ // clear all keyboard states
+ lock_next = false;
+ autoshift_mode = true;
+ command_mode = 0;
+ in_leader_mode = false;
+ leader_ind = 0;
+ dynamic_macro_mode = false;
+ a_key_went_through = false;
+
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ }
+} \ No newline at end of file
diff --git a/keyboards/georgi/keymaps/dennytom/keymap_def.json b/keyboards/georgi/keymaps/dennytom/keymap_def.json
new file mode 100644
index 000000000..232ccafad
--- /dev/null
+++ b/keyboards/georgi/keymaps/dennytom/keymap_def.json
@@ -0,0 +1,153 @@
+{
+ "keys": [
+ "TOP1", "TOP2", "TOP3", "TOP4", "TOP5", "TOP6", "TOP7", "TOP8", "TOP9", "TOP10", "TOP11", "TOP12",
+ "BOT1", "BOT2", "BOT3", "BOT4", "BOT5", "BOT6", "BOT7", "BOT8", "BOT9", "BOT10", "BOT11", "BOT12",
+ "THU1", "THU2", "THU3", "THU4", "THU5", "THU6"
+ ],
+ "parameters": {
+ "layout_function_name": "LAYOUT_georgi",
+ "chord_timeout": 100,
+ "dance_timeout": 200,
+ "leader_timeout": 750,
+ "tap_timeout": 50,
+ "command_max_length": 5,
+ "leader_max_length": 5,
+ "dynamic_macro_max_length": 20,
+ "string_max_length": 16,
+ "long_press_multiplier": 3,
+ "default_pseudolayer": "QWERTY"
+ },
+ "layers": [
+ {
+ "type": "auto"
+ }
+ ],
+ "chord_sets": [
+ {
+ "name": "rows",
+ "chords":
+ [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP5"], ["TOP6"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP10"], ["TOP11"], ["TOP12"],
+ ["TOP1", "BOT1"], ["TOP2", "BOT2"], ["TOP3", "BOT3"], ["TOP4", "BOT4"], ["TOP5", "BOT5"], ["TOP6", "BOT6"], ["TOP7", "BOT7"], ["TOP8", "BOT8"], ["TOP9", "BOT9"], ["TOP10", "BOT10"], ["TOP11", "BOT11"], ["TOP12", "BOT12"],
+ ["BOT1"], ["BOT2"], ["BOT3"], ["BOT4"], ["BOT5"], ["BOT6"], ["BOT7"], ["BOT8"], ["BOT9"], ["BOT10"], ["BOT11"], ["BOT12"],
+ ["THU1"], ["THU2"], ["THU3"], ["THU4"], ["THU5"], ["THU6"]
+ ]
+ }
+ ],
+ "pseudolayers": [
+ {
+ "name": "ALWAYS_ON",
+ "chords": [
+ {
+ "type": "visual",
+ "chord": [
+ "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X",
+ "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X",
+ " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "CLEAR_KB"
+ },
+ {
+ "type": "visual",
+ "chord": [
+ " ", " ", " ", " ", " ", "X", "X", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", "X", "X", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "CMD"
+ }
+ ]
+ },
+ {
+ "name": "QWERTY",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "ESC", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\\",
+ "INS", "A", "KK(S, LALT)", "KM(D, LCTL)", "KM(F, LSFT)", "KK(G, LGUI)", "KK(H, RGUI)", "KM(J, RSFT)", "KM(K, RCTL)", "KK(L, RALT)", ";", " ",
+ "TAB", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "'",
+ "","","","","",""
+ ]
+ },
+ {
+ "type": "visual_array",
+ "keys": ["THU1", "THU2", "THU3", "THU4", "THU5", "THU6"],
+ "dictionary": [
+ ["X", " ", " ", " ", " ", " ", "ENTER"],
+ [" ", "X", " ", " ", " ", " ", "KL(SPC, NUM)"],
+ [" ", " ", "X", " ", " ", " ", "KL(BSPC, NAV)"],
+ [" ", " ", " ", "X", " ", " ", "DEL"],
+ [" ", " ", " ", " ", "X", " ", "KL(SPC, FNC)"],
+ [" ", " ", " ", " ", " ", "X", "ENTER"],
+ [" ", "X", "X", " ", " ", " ", "MO(MOUSE)"]
+ ]
+ }
+ ]
+ },
+ {
+ "name": "NUM",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-",
+ " ", " ", "LALT", "LCTL", "LSFT", "LGUI", "RGUI", "RSFT", "RCTL", "RALT", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", "[", "]", "=",
+ " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ },
+ {
+ "name": "FNC",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11",
+ " ", " ", "LALT", "LCTL", "LSFT", "LGUI", "RGUI", "RSFT", "RCTL", "RALT", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "F12",
+ " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ },
+ {
+ "name": "NAV",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ", " ", " ", "HOME", "UP", "END", "PGUP", " ",
+ " ", " ", "LALT", "LCTL", "LSFT", "LGUI", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", "LEFT", "DOWN", "RIGHT", "PGDN", " ",
+ " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ },
+ {
+ "name": "MOUSE",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ " ", " ", " ", " ", " ", " ", " ", "BTN1", "MS_U", "BTN2", "WH_U", " ",
+ " ", " ", "LALT", "LCTL", "LSFT", "LGUI", " ", " ", " ", " ", " ", " ",
+ " ", " ", " ", " ", " ", " ", " ", "MS_L", "MS_D", "MS_R", "WH_D", " ",
+ " ", " ", " ", " ", " ", " "
+ ]
+ }
+ ]
+ }
+ ],
+ "leader_sequences": [],
+ "extra_code": "",
+ "extra_dependencies": []
+} \ No newline at end of file
diff --git a/keyboards/georgi/keymaps/dennytom/rules.mk b/keyboards/georgi/keymaps/dennytom/rules.mk
new file mode 100644
index 000000000..1155f72c0
--- /dev/null
+++ b/keyboards/georgi/keymaps/dennytom/rules.mk
@@ -0,0 +1,8 @@
+MOUSEKEY_ENABLE = yes
+EXTRAKEY_ENABLE = yes
+CONSOLE_ENABLE = no
+# COMMAND_ENABLE = no
+NKRO_ENABLE = yes
+
+TMPVAR := $(SRC)
+SRC = $(filter-out sten.c, $(TMPVAR)) \ No newline at end of file
diff --git a/keyboards/gergo/keymaps/gotham/config.h b/keyboards/gergo/keymaps/gotham/config.h
new file mode 100644
index 000000000..6393d46f1
--- /dev/null
+++ b/keyboards/gergo/keymaps/gotham/config.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/keyboards/gergo/keymaps/gotham/keymap.c b/keyboards/gergo/keymaps/gotham/keymap.c
new file mode 100644
index 000000000..ff6df266f
--- /dev/null
+++ b/keyboards/gergo/keymaps/gotham/keymap.c
@@ -0,0 +1,155 @@
+/* Good on you for modifying your layout! if you don't have
+ * time to read the QMK docs, a list of keycodes can be found at
+ *
+ * https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md
+ *
+ * There's also a template for adding new layers at the bottom of this file!
+ */
+
+#include QMK_KEYBOARD_H
+
+enum layers {
+ BASE, // default layer
+ SYMB, // symbols
+ NUMB, // number/navigation
+ MOUS, // mouse navigation
+};
+
+#define KC_ANGL LSFT(KC_COMM)
+#define KC_ANGR LSFT(KC_DOT)
+
+// Blank template at the bottom
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ,-------------------------------------------. ,-------------------------------------------.
+ * | ESC | Q | W | E | R | T | | Y | U | I | O | P | \ | |
+ * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
+ * | LShift | A | S | D | F | G | | | VolUp| H | J | K | L | ; : |RSft/' "|
+ * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
+ * | LCtrl | Z | X | C | V | B | | | VolDn| N | M | , < | . > | / ? |RCtl/- _|
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * .----------. .----------. .-----------. .------.
+ * | LAlt | |SYMB/Space| | NUMB/Bksp | | MOUS |
+ * '----------' '----------' `-----------' '------'
+ * ,-------. ,-------.
+ * | | |VolMute|
+ * ,------|-------| |-------|------.
+ * | NUMB | | | | SYMB |
+ * | Tab | LGui | | = | Enter|
+ * | | | | | |
+ * `--------------' `--------------'
+ */
+[BASE] = LAYOUT_gergo(
+ KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
+ KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, XXXXXXX, KC_VOLU, KC_H, KC_J, KC_K, KC_L, KC_SCLN, MT(MOD_RSFT, KC_QUOT),
+ KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, XXXXXXX, XXXXXXX, KC_MUTE, KC_VOLD, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MT(MOD_RCTL, KC_MINS),
+ KC_LALT, LT(SYMB, KC_SPC), LT(NUMB, KC_TAB), KC_LGUI, KC_EQL, LT(SYMB, KC_ENT), LT(NUMB, KC_BSPC), MO(MOUS)
+ ),
+/* Keymap 1: Symbols layer
+ *
+ * ,-------------------------------------------. ,-------------------------------------------.
+ * | | # | $ | { | } | | | | < | > | | | | |
+ * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
+ * | | ! | @ | ( | ) | ` | | | | - | & | + | * | ; | ' " |
+ * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
+ * | | % | ^ | [ | ] | ~ | | | | _ | | | , | . | / ? | - _ |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * .----------. .----------. .-----. .------.
+ * | LAlt | |SYMB/Space| | Del | | MOUS |
+ * '----------' '----------' `-----' '------'
+ * ,-------. ,-------.
+ * | | | |
+ * ,------|-------| |-------|------.
+ * | NUMB | | | | SYMB |
+ * | Tab | LGui | | = | Enter|
+ * | | | | | |
+ * `--------------' `--------------'
+ */
+[SYMB] = LAYOUT_gergo(
+ _______, KC_HASH, KC_DLR, KC_LCBR, KC_RCBR, XXXXXXX, XXXXXXX, KC_ANGL, KC_ANGR, XXXXXXX, XXXXXXX, KC_PIPE,
+ _______, KC_EXLM, KC_AT, KC_LPRN, KC_RPRN, KC_GRV, XXXXXXX, XXXXXXX, KC_MINS, KC_AMPR, KC_PLUS, KC_ASTR, KC_SCLN, KC_QUOT,
+ _______, KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_TILD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_UNDS, KC_PIPE, KC_COMM, KC_DOT, KC_SLSH, KC_MINS,
+ _______, _______, _______, _______, _______, _______, KC_DEL, _______
+ ),
+/* Keymap 2: Pad/Function layer
+ *
+ * ,-------------------------------------------. ,-------------------------------------------.
+ * | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
+ * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
+ * | | F1 | F2 | F3 | F4 | F5 | F6 | | | PgUp | LEFT | UP | RIGHT| | |
+ * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 | | |PgDown| HOME | DOWN | END | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * .----------. .----------. .-----------. .------.
+ * | LAlt | |SYMB/Space| | NUMB/Bksp | | MOUS |
+ * '----------' '----------' `-----------' '------'
+ * ,-------. ,-------.
+ * | | | |
+ * ,------|-------| |-------|------.
+ * | NUMB | | | | SYMB |
+ * | Tab | LGui | | = | Enter|
+ * | | | | | |
+ * `--------------' `--------------'
+ */
+[NUMB] = LAYOUT_gergo(
+ _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, XXXXXXX,
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_PGUP, KC_LEFT, KC_UP, KC_RIGHT, XXXXXXX, XXXXXXX,
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, KC_PGDN, KC_HOME, KC_DOWN, KC_END, XXXXXXX, XXXXXXX,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+/* Keymap 3: Mouse layer
+ *
+ * ,-------------------------------------------. ,-------------------------------------------.
+ * | | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
+ * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
+ * | | F1 | F2 | F3 | F4 | F5 | F6 | | | | M_L | M_U | M_R | M_Clk| |
+ * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 | | | | L_Clk| M_D | R_Clk| | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * .----------. .----------. .-----------. .------.
+ * | LAlt | |SYMB/Space| | NUMB/Bksp | | MOUS |
+ * '----------' '----------' `-----------' '------'
+ * ,-------. ,-------.
+ * | | | |
+ * ,------|-------| |-------|------.
+ * | NUMB | | | | SYMB |
+ * | Tab | LGui | | = | Enter|
+ * | | | | | |
+ * `--------------' `--------------'
+ */
+[MOUS] = LAYOUT_gergo(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_MS_L, KC_MS_U, KC_MS_R, KC_BTN3, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_BTN1, KC_MS_D, KC_BTN2, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+};
+
+/* Keymap template
+ *
+ * ,-------------------------------------------. ,-------------------------------------------.
+ * | | | | | | | | | | | | | |
+ * |--------+------+------+------+------+------|------. .------|------+------+------+------+------+--------|
+ * | | | | | | | | | | | | | | | |
+ * |--------+------+------+------+------+------|------| |------|------+------+------+------+------+--------|
+ * | | | | | | | | | | | | | | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * .------. .------. .------. .-----.
+ * | | | | | | | |
+ * '------' '------' `------. '-----'
+ * ,-------. ,-------.
+ * | | | |
+ * ,------|-------| |-------|------.
+ * | | | | | |
+ * | | | | | |
+ * | | | | | |
+ * `--------------' `--------------'
+[SYMB] = LAYOUT_gergo(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ )
+ */
diff --git a/keyboards/gergo/keymaps/gotham/readme.md b/keyboards/gergo/keymaps/gotham/readme.md
new file mode 100644
index 000000000..2b1c5ab1d
--- /dev/null
+++ b/keyboards/gergo/keymaps/gotham/readme.md
@@ -0,0 +1,8 @@
+This is a modified version of the default keymap for Gergo with some changes.
+
+## Changes:
+ - Rehaul thumb keys. For my hand size, the L and R thumbs rest on space and backspace, and one finger outward, are tab and enter.
+ - = has its own dedicated key to facilitate typing "<space>=<space>", which is a very common trigram in programming.
+ - Change navigation into a T-shaped cluster and add Home and End keys. T-shaped, because it's similar to arrow key cluster and most keys are on the home row, while sharing the number layer.
+ - Separated mouse navigation into a separate layer (in favor of T-shaped arrows, which require 2 rows).
+ - Difficult-to-reach key positions are mostly unused.
diff --git a/keyboards/gergo/keymaps/gotham/rules.mk b/keyboards/gergo/keymaps/gotham/rules.mk
new file mode 100644
index 000000000..351c52558
--- /dev/null
+++ b/keyboards/gergo/keymaps/gotham/rules.mk
@@ -0,0 +1,37 @@
+#----------------------------------------------------------------------------
+# make gergo:germ:dfu
+# Make sure you have dfu-programmer installed!
+#----------------------------------------------------------------------------
+# Firmware options
+BALLER = no # Enable to ball out
+BALLSTEP = 20 # Multiple in px to move, multiplied by layer number
+SCROLLSTEP = 1 # Lines to scroll with ball
+MOUSEKEY_ENABLE = yes # Mouse keys, needed for baller
+
+#Debug options
+VERBOSE = yes
+DEBUG_MATRIX_SCAN_RATE = no
+DEBUG_BALLER = no
+DEBUG_MATRIX = yes
+
+# A bunch of stuff that you shouldn't touch unless you
+# know what you're doing.
+#
+# No touchy, capiche?
+SRC += matrix.c i2c_master.c
+ifneq ($(strip $(BALLSTEP)),)
+ OPT_DEFS += -DTRKSTEP=$(strip $(BALLSTEP))
+endif
+ifneq ($(strip $(SCROLLSTEP)),)
+ OPT_DEFS += -DSCROLLSTEP=$(strip $(SCROLLSTEP))
+endif
+ifeq ($(strip $(BALLER)), yes)
+ POINTING_DEVICE_ENABLE = yes
+ OPT_DEFS += -DBALLER
+endif
+ifeq ($(strip $(DEBUG_BALLER)), yes)
+ OPT_DEFS += -DDEBUG_BALLER
+endif
+ifeq ($(strip $(DEBUG_MATRIX)), yes)
+ OPT_DEFS += -DDEBUG_MATRIX
+endif
diff --git a/keyboards/gray_studio/space65/keymaps/keithlo/keymap.c b/keyboards/gray_studio/space65/keymaps/keithlo/keymap.c
new file mode 100644
index 000000000..9efc3fd84
--- /dev/null
+++ b/keyboards/gray_studio/space65/keymaps/keithlo/keymap.c
@@ -0,0 +1,63 @@
+/* Copyright 2019 MechMerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ /* Qwerty
+ * ,------------------------------------------------------------------------------------------------.
+ * | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BSPC | DEL |
+ * |------------------------------------------------------------------------------------------------+
+ * | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | \ | INS |
+ * |------------------------------------------------------------------------------------------------+
+ * | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | Enter | PGUP |
+ * |------------------------------------------------------------------------------------------------+
+ * | Shift | Z | X | C | V | B | N | M | , | . | ?/ | Shift | Up | PGDN |
+ * |------------------------------------------------------------------------------------------------+
+ * | Ctrl | Alt | Cmd | Space | Fn | Cmd | Alt | Fn | | Left | Down |Right |
+ * `----------------------------------------------------------------------' '--------------------'
+ */
+
+[0] = LAYOUT( \
+ 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_BSPC, KC_BSPC, KC_DEL, \
+ 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_INS, \
+ 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_PGUP, \
+ 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_UP, KC_PGDN, \
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, MO(1), KC_RGUI, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT \
+ ),
+
+ /* Fn Layer
+ * ,------------------------------------------------------------------------------------------------.
+ * | | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | Vol- | Vol+ | Mute | Mute |
+ * |------------------------------------------------------------------------------------------------+
+ * | |RGB T|RGB M| Hue-| Hue+| Sat-| Sat+| Val-| Val+| | | | | | |
+ * |------------------------------------------------------------------------------------------------+
+ * | | RGBP | RGPG | RGPK | | | Left| Down| Up |Right| | | Play/Pause | |
+ * |------------------------------------------------------------------------------------------------+
+ * | | | | | | | | | | Scr- | Scr+ | | PgUp | |
+ * |------------------------------------------------------------------------------------------------+
+ * | | | | | | | | | | Home | PgDn | End |
+ * `---------------------------------------------------------------------' '--------------------'
+ */
+
+[1] = LAYOUT( \
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_VOLD, KC_VOLU, KC_MUTE, KC_MUTE, KC_MUTE, \
+ KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, RGB_SPD, RGB_SPI, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, RGB_M_P, RGB_M_G, RGB_M_K, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, KC_TRNS, KC_TRNS, KC_MPLY, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BRID, KC_BRIU, KC_TRNS, KC_TRNS, KC_PGUP, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_END \
+ ),
+};
diff --git a/keyboards/gray_studio/space65/keymaps/keithlo/readme.md b/keyboards/gray_studio/space65/keymaps/keithlo/readme.md
new file mode 100644
index 000000000..d8673643e
--- /dev/null
+++ b/keyboards/gray_studio/space65/keymaps/keithlo/readme.md
@@ -0,0 +1,107 @@
+## Space65 layout (with split space row -- no pun intended)
+
+This layout is optimized for vim users on MacOS.
+The split space row == least travel possible (I've found). Coming from an Alice this is the only way I can find myself going back to a non-ergonomic 6X% board
+
+###### Settings:
+
+* The `ALT` and `CMD` keys are swapped to replicate the Mac layout
+* vim-style arrow key bindings H J K L in Fn layer
+
+###### Flashing:
+
+* v1 PCB: in order to toggle BootLoader from a factory PCB you must hold down ESC + Modifier MO(1) before you plug the board in
+* otherwise you just hold ESC before you plug the board in
+* Next, to make the .hex file and subsequently flash the board run:
+
+```$ make gray_studio/space65:keithlo:flash # be in the qmk_firmware directory to do this ```
+* more info at the bottom if you're getting errors
+
+
+### Qwerty
+```
+,------------------------------------------------------------------------------------------------.
+| ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BSPC | DEL |
+|------------------------------------------------------------------------------------------------+
+| TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | \ | INS |
+|------------------------------------------------------------------------------------------------+
+| CAPS | A | S | D | F | G | H | J | K | L | ; | ' | Enter | PGUP |
+|------------------------------------------------------------------------------------------------+
+| Shift | Z | X | C | V | B | N | M | , | . | ?/ | Shift | Up | PGDN |
+|------------------------------------------------------------------------------------------------+
+| Ctrl | Alt | Cmd | Space | Fn | Cmd | Alt | Fn | | Left | Down |Right |
+`----------------------------------------------------------------------' '--------------------'
+```
+
+### Fn Layer
+```
+,------------------------------------------------------------------------------------------------.
+| | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | Vol- | Vol+ | Mute | Mute |
+|------------------------------------------------------------------------------------------------+
+| |RGB T|RGB M| Hue-| Hue+| Sat-| Sat+| Val-| Val+| | | | | | |
+|------------------------------------------------------------------------------------------------+
+| | RGBP | RGPG | RGPK | | | Left| Down| Up |Right| | | Play/Pause | |
+|------------------------------------------------------------------------------------------------+
+| | | | | | | | | | Scr- | Scr+ | | PgUp | |
+|------------------------------------------------------------------------------------------------+
+| | | | | | | | | | Home | PgDn | End |
+`---------------------------------------------------------------------' '--------------------'
+
+
+Fn Layer Mapping chars -> RGB commands
+|------------------------------------------------------------------------------------------------+
+| |RGB T|RGB M| Hue-| Hue+| Sat-| Sat+| Val-| Val+| | | | | | |
+|------------------------------------------------------------------------------------------------+
+| | Q | W | E | R | T | Y | U | I | | | | | | |
+|------------------------------------------------------------------------------------------------+
+
+|------------------------------------------------------------------------------------------------+
+| | RGBP | RGPG | RGPK | | | Left| Down| Up |Right| | | Play/Pause | |
+|------------------------------------------------------------------------------------------------+
+| | A | S | D | | | H | J | K | L | | | Enter | |
+|------------------------------------------------------------------------------------------------+
+```
+
+
+###### Flashing (debugging)
+* Make sure you are holding ESC + MO(1) when you plug board in
+* Release ESC + MO(1) if you are stuck in the ```dfu-programmer: no device present.
+ERROR: Bootloader not found. Trying again in 5s.``` loop seen below
+
+* You should see a screen like this when you make and flash
+```
+qmk_firmware git:(master)$ make gray_studio/space65:keithlo:flash
+QMK Firmware 0.8.107
+Making gray_studio/space65 with keymap keithlo and target flash
+
+avr-gcc (GCC) 8.3.0
+Copyright (C) 2018 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.
+
+Size before:
+ text data bss dec hex filename
+ 0 21836 0 21836 554c .build/gray_studio_space65_keithlo.hex
+
+Copying gray_studio_space65_keithlo.hex to qmk_firmware folder [OK]
+Checking file size of gray_studio_space65_keithlo.hex [OK]
+ * The firmware size is fine - 21836/28672 (76%, 6836 bytes free)
+dfu-programmer: no device present.
+ERROR: Bootloader not found. Trying again in 5s.
+dfu-programmer: no device present.
+ERROR: Bootloader not found. Trying again in 5s.
+Bootloader Version: 0x00 (0)
+Erasing flash... Success
+Checking memory from 0x0 to 0x6FFF... Empty.
+Checking memory from 0x0 to 0x557F... Empty.
+0% 100% Programming 0x5580 bytes...
+[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
+0% 100% Reading 0x7000 bytes...
+[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
+Validating... Success
+0x5580 bytes written into 0x7000 bytes memory (76.34%).
+qmk_firmware git:(master)$
+```
+
+
+shoutout @billiams for the base ascii art template
diff --git a/keyboards/handwired/bdn9_ble/bdn9_ble.c b/keyboards/handwired/bdn9_ble/bdn9_ble.c
new file mode 100644
index 000000000..75fe7fff7
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/bdn9_ble.c
@@ -0,0 +1 @@
+#include "bdn9_ble.h"
diff --git a/keyboards/handwired/bdn9_ble/bdn9_ble.h b/keyboards/handwired/bdn9_ble/bdn9_ble.h
new file mode 100644
index 000000000..8a4511326
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/bdn9_ble.h
@@ -0,0 +1,37 @@
+/* Copyright 2019 Danny Nguyen <danny@keeb.io>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+/* This a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT( \
+ KA1, KA2, KA3, \
+ KB1, KB2, KB3, \
+ KC1, KC2, KC3 \
+) \
+{ \
+ { KA1, KA2, KA3 }, \
+ { KB1, KB2, KB3 }, \
+ { KC1, KC2, KC3 } \
+}
diff --git a/keyboards/handwired/bdn9_ble/config.h b/keyboards/handwired/bdn9_ble/config.h
new file mode 100644
index 000000000..8db9253dd
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/config.h
@@ -0,0 +1,52 @@
+/*
+Copyright 2019 Danny Nguyen <danny@keeb.io>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCB10
+#define PRODUCT_ID 0x1134
+#define DEVICE_VER 0x0100
+#define MANUFACTURER KeyPCB/Keebio
+#define PRODUCT BDN9-BLE
+#define DESCRIPTION 3x3 Bluetooth Macropad
+
+/* key matrix size */
+#define MATRIX_ROWS 3
+#define MATRIX_COLS 3
+
+/* Keyboard Matrix Assignments */
+#define DIRECT_PINS { \
+ { D1, D0, C6 }, \
+ { D7, B5, B6 }, \
+ { B7, D6, F7 } \
+}
+
+#define BACKLIGHT_PIN F6
+// #define BACKLIGHT_BREATHING
+#define BACKLIGHT_LEVELS 5
+#define BACKLIGHT_ON_STATE 1
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 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
diff --git a/keyboards/handwired/bdn9_ble/info.json b/keyboards/handwired/bdn9_ble/info.json
new file mode 100644
index 000000000..49bf62719
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/info.json
@@ -0,0 +1,22 @@
+{
+ "keyboard_name": "KeyPCB/Keeb.io BDN9-BLE",
+ "url": "",
+ "maintainer": "merlin04",
+ "width": 3,
+ "height": 3,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"x":0, "y":0},
+ {"x":1, "y":0},
+ {"x":2, "y":0},
+ {"x":0, "y":1},
+ {"x":1, "y":1},
+ {"x":2, "y":1},
+ {"x":0, "y":2},
+ {"x":1, "y":2},
+ {"x":2, "y":2}
+ ]
+ }
+ }
+}
diff --git a/keyboards/handwired/bdn9_ble/keymaps/default/keymap.c b/keyboards/handwired/bdn9_ble/keymaps/default/keymap.c
new file mode 100644
index 000000000..406842146
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/keymaps/default/keymap.c
@@ -0,0 +1,49 @@
+/* Copyright 2019 Danny Nguyen <danny@keeb.io>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+
+// Enable test mode, which sets the keys to letters A-I.
+//#define TESTMODE
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ #ifndef TESTMODE
+ // MEH - hold down ctrl, alt, shift, and press key
+ [0] = LAYOUT(
+ MEH(KC_1), MEH(KC_2), MEH(KC_3),
+ MEH(KC_4), MEH(KC_5), MEH(KC_6),
+ MEH(KC_7), MEH(KC_8), LT(1, MEH(KC_9))
+ ),
+ #else
+ [0] = LAYOUT(
+ KC_A, KC_B, KC_C,
+ KC_D, KC_E, KC_F,
+ KC_G, KC_H, KC_I
+ ),
+ #endif
+ /*
+ * ------------------------------------------------------------------------
+ * | | Automatic BLE output detection | Reset |
+ * | Backlight Step | Use USB port for output | |
+ * | Backlight Tgl | Use Bluetooth for output | (currently pressed) |
+ * ------------------------------------------------------------------------
+ */
+ [1] = LAYOUT(
+ _______, OUT_AUTO, RESET,
+ BL_STEP, OUT_USB, _______,
+ BL_TOGG, OUT_BT, _______
+ )
+};
diff --git a/keyboards/handwired/bdn9_ble/readme.md b/keyboards/handwired/bdn9_ble/readme.md
new file mode 100644
index 000000000..eaeab59ad
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/readme.md
@@ -0,0 +1,14 @@
+# BDN9-BLE
+
+![BDN9](https://cdn.shopify.com/s/files/1/1851/5125/products/image_bd8d9423-950e-4aad-bea5-665d896f879a_530x@2x.jpg?v=1547909493)
+
+A handwired modified version of the Keebio BDN9 macropad to support BLE through the Adafruit Feather 32u4 Bluefruit LE.
+
+* Keyboard Maintainer: [merlin04/KeyPCB](https://github.com/merlin04)
+* Hardware Supported: Adafruit Feather 32u4 Bluefruit LE
+
+Make example for this keyboard (after setting up your build environment):
+
+ make handwired/bdn9_ble:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/handwired/bdn9_ble/rules.mk b/keyboards/handwired/bdn9_ble/rules.mk
new file mode 100644
index 000000000..4fabf1c89
--- /dev/null
+++ b/keyboards/handwired/bdn9_ble/rules.mk
@@ -0,0 +1,37 @@
+# MCU name
+MCU = atmega32u4
+
+# Processor frequency
+F_CPU = 8000000
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = caterina
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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 = yes # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH = AdafruitBLE # Enable Bluetooth
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+ENCODER_ENABLE = no
diff --git a/keyboards/handwired/fc200rt_qmk/config.h b/keyboards/handwired/fc200rt_qmk/config.h
new file mode 100644
index 000000000..fa070494a
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/config.h
@@ -0,0 +1,136 @@
+/*
+Copyright 2020 NaCly
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xBEEF
+#define PRODUCT_ID 0xFFFF
+#define DEVICE_VER 0x0001
+#define MANUFACTURER NaCly
+#define PRODUCT fc200rt_qmk
+#define DESCRIPTION Leopold FC200RT QMK enbabled with Teensy 2.0
+
+/* key matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 16
+
+
+#define MATRIX_ROW_PINS { B0, B1, B2, B3, E6, B7, D0, D1 }
+#define MATRIX_COL_PINS { D2, D3, C6, C7, D5, D4, D6, D7, B4, B5, B6, F7, F6, F5, F4, F1 }
+#define UNUSED_PINS
+
+/* COL2ROW, ROW2COL*/
+#define DIODE_DIRECTION ROW2COL
+
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* 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
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+// #define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * 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 */
+/* defined by default; to change, uncomment and set to the combination you want */
+// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
+
+/* 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_HELP H
+//#define MAGIC_KEY_HELP_ALT 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 0
+//#define MAGIC_KEY_LAYER0_ALT GRAVE
+//#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 B
+//#define MAGIC_KEY_BOOTLOADER_ALT ESC
+//#define MAGIC_KEY_LOCK CAPS
+//#define MAGIC_KEY_EEPROM E
+//#define MAGIC_KEY_EEPROM_CLEAR BSPACE
+//#define MAGIC_KEY_NKRO N
+//#define MAGIC_KEY_SLEEP_LED Z
+
+#ifndef LINK_TIME_OPTIMIZATION_ENABLE
+ #define NO_ACTION_MACRO
+ #define NO_ACTION_FUNCTION
+#endif
diff --git a/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.c b/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.c
new file mode 100644
index 000000000..3e38e5e2f
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.c
@@ -0,0 +1,17 @@
+/* Copyright 2020 NaCly
+ *
+ * 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 "fc200rt_qmk.h"
diff --git a/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.h b/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.h
new file mode 100644
index 000000000..f9abbf383
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/fc200rt_qmk.h
@@ -0,0 +1,46 @@
+/* Copyright 2020 NaCly
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT( \
+ k31, k62, k63, k13, k33, k70, k36, k17, k67, k6A, k7A, k3A, k5A, k79, k09, k00, \
+ k61, k71, k72, k73, k74, k64, k65, k75, k76, k77, k78, k68, k66, k1A, k6C, k6E, k6D, \
+ k11, k01, k02, k03, k04, k14, k15, k05, k06, k07, k08, k18, k16, k2A, k6B, k7E, k7D, \
+ k12, k21, k22, k23, k24, k34, k35, k25, k26, k27, k28, k38, k4A, \
+ k1F, k41, k42, k43, k44, k54, k55, k45, k46, k47, k58, k2F, k3E, \
+ k60, k10, k39, k3B, k59, k29, k57, k40, k5E, k5B, k5C \
+) \
+{ \
+ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { k10, k11, k12, k13, k14, k15, k16, k17, k18, KC_NO, k1A, KC_NO, KC_NO, KC_NO, KC_NO, k1F }, \
+ { KC_NO, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, KC_NO, KC_NO, KC_NO, KC_NO, k2F }, \
+ { KC_NO, k31, KC_NO, k33, k34, k35, k36, KC_NO, k38, k39, k3A, k3B, KC_NO, KC_NO, k3E, KC_NO }, \
+ { k40, k41, k42, k43, k44, k45, k46, k47, KC_NO, KC_NO, k4A, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, k54, k55, KC_NO, k57, k58, k59, k5A, k5B, k5C, KC_NO, k5E, KC_NO }, \
+ { k60, k61, k62, k63, k64, k65, k66, k67, k68, KC_NO, k6A, k6B, k6C, k6D, k6E, KC_NO }, \
+ { k70, k71, k72, k73, k74, k75, k76, k77, k78, k79, k7A, KC_NO, KC_NO, k7D, k7E, KC_NO }, \
+}
diff --git a/keyboards/handwired/fc200rt_qmk/info.json b/keyboards/handwired/fc200rt_qmk/info.json
new file mode 100644
index 000000000..2a8bf3dd9
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/info.json
@@ -0,0 +1,12 @@
+{
+ "keyboard_name": "fc200rt_qmk",
+ "url": "",
+ "maintainer": "qmk",
+ "width": 18.25,
+ "height": 6.5,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"F1", "x":2, "y":0}, {"label":"F2", "x":3, "y":0}, {"label":"F3", "x":4, "y":0}, {"label":"F4", "x":5, "y":0}, {"label":"F5", "x":6.5, "y":0}, {"label":"F6", "x":7.5, "y":0}, {"label":"F7", "x":8.5, "y":0}, {"label":"F8", "x":9.5, "y":0}, {"label":"F9", "x":11, "y":0}, {"label":"F10", "x":12, "y":0}, {"label":"F11", "x":13, "y":0}, {"label":"F12", "x":14, "y":0}, {"label":"PrtSc", "x":15.25, "y":0}, {"label":"Scroll Lock", "x":16.25, "y":0}, {"label":"Pause", "x":17.25, "y":0}, {"label":"~", "x":0, "y":1.5}, {"label":"!", "x":1, "y":1.5}, {"label":"@", "x":2, "y":1.5}, {"label":"#", "x":3, "y":1.5}, {"label":"$", "x":4, "y":1.5}, {"label":"%", "x":5, "y":1.5}, {"label":"^", "x":6, "y":1.5}, {"label":"&", "x":7, "y":1.5}, {"label":"*", "x":8, "y":1.5}, {"label":"(", "x":9, "y":1.5}, {"label":")", "x":10, "y":1.5}, {"label":"_", "x":11, "y":1.5}, {"label":"+", "x":12, "y":1.5}, {"label":"Backspace", "x":13, "y":1.5, "w":2}, {"label":"Insert", "x":15.25, "y":1.5}, {"label":"Home", "x":16.25, "y":1.5}, {"label":"PgUp", "x":17.25, "y":1.5}, {"label":"Tab", "x":0, "y":2.5, "w":1.5}, {"label":"Q", "x":1.5, "y":2.5}, {"label":"W", "x":2.5, "y":2.5}, {"label":"E", "x":3.5, "y":2.5}, {"label":"R", "x":4.5, "y":2.5}, {"label":"T", "x":5.5, "y":2.5}, {"label":"Y", "x":6.5, "y":2.5}, {"label":"U", "x":7.5, "y":2.5}, {"label":"I", "x":8.5, "y":2.5}, {"label":"O", "x":9.5, "y":2.5}, {"label":"P", "x":10.5, "y":2.5}, {"label":"{", "x":11.5, "y":2.5}, {"label":"}", "x":12.5, "y":2.5}, {"label":"|", "x":13.5, "y":2.5, "w":1.5}, {"label":"Delete", "x":15.25, "y":2.5}, {"label":"End", "x":16.25, "y":2.5}, {"label":"PgDn", "x":17.25, "y":2.5}, {"label":"Caps Lock", "x":0, "y":3.5, "w":1.75}, {"label":"A", "x":1.75, "y":3.5}, {"label":"S", "x":2.75, "y":3.5}, {"label":"D", "x":3.75, "y":3.5}, {"label":"F", "x":4.75, "y":3.5}, {"label":"G", "x":5.75, "y":3.5}, {"label":"H", "x":6.75, "y":3.5}, {"label":"J", "x":7.75, "y":3.5}, {"label":"K", "x":8.75, "y":3.5}, {"label":"L", "x":9.75, "y":3.5}, {"label":":", "x":10.75, "y":3.5}, {"label":"\"", "x":11.75, "y":3.5}, {"label":"Enter", "x":12.75, "y":3.5, "w":2.25}, {"label":"Shift", "x":0, "y":4.5, "w":2.25}, {"label":"Z", "x":2.25, "y":4.5}, {"label":"X", "x":3.25, "y":4.5}, {"label":"C", "x":4.25, "y":4.5}, {"label":"V", "x":5.25, "y":4.5}, {"label":"B", "x":6.25, "y":4.5}, {"label":"N", "x":7.25, "y":4.5}, {"label":"M", "x":8.25, "y":4.5}, {"label":"<", "x":9.25, "y":4.5}, {"label":">", "x":10.25, "y":4.5}, {"label":"?", "x":11.25, "y":4.5}, {"label":"Shift", "x":12.25, "y":4.5, "w":2.75}, {"label":"\u2191", "x":16.25, "y":4.5}, {"label":"Ctrl", "x":0, "y":5.5, "w":1.25}, {"label":"Win", "x":1.25, "y":5.5, "w":1.25}, {"label":"Alt", "x":2.5, "y":5.5, "w":1.25}, {"x":3.75, "y":5.5, "w":6.25}, {"label":"Alt", "x":10, "y":5.5, "w":1.25}, {"label":"Win", "x":11.25, "y":5.5, "w":1.25}, {"label":"Menu", "x":12.5, "y":5.5, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":5.5, "w":1.25}, {"label":"\u2190", "x":15.25, "y":5.5}, {"label":"\u2193", "x":16.25, "y":5.5}, {"label":"\u2192", "x":17.25, "y":5.5}]
+ }
+ }
+} \ No newline at end of file
diff --git a/keyboards/handwired/fc200rt_qmk/keymaps/default/keymap.c b/keyboards/handwired/fc200rt_qmk/keymaps/default/keymap.c
new file mode 100644
index 000000000..eb72c08d6
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/keymaps/default/keymap.c
@@ -0,0 +1,28 @@
+/* Copyright 2019 NaCly
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ 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_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_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_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ )
+
+}; \ No newline at end of file
diff --git a/keyboards/handwired/fc200rt_qmk/readme.md b/keyboards/handwired/fc200rt_qmk/readme.md
new file mode 100644
index 000000000..649022780
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/readme.md
@@ -0,0 +1,35 @@
+# fc200rt_qmk
+
+![fc200rt_qmk](https://i.imgur.com/UWKdIcZ.jpg)
+![fc200rt_qmk](https://i.imgur.com/0d8U8NE.jpg)
+A Leopold FC200RT rewired with Teensy 2.0
+
+Uses original row and column matrix, so you can wire the teensy 2.0 to the corrosposnding column and row numbers and flash this firmware to the teensy.
+
+Pinout of Leopold's matrix:
+
+| | c0 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 |
+|----|------|-----|------|----|----|----|------|-----|------|------|------|------|------|------|------|------|
+| r0 | PAUS | Q | W | E | R | U | I | O | P | SLCK | | | | | | |
+| r1 | LGUI | TAB | CAPS | F3 | T | Y | RBRC | F7 | LBRC | | BSPC | | | | | LSFT |
+| r2 | | A | | D | F | J | K | L | SCLN | RGUI | BSLS | | | | | RSFT |
+| r3 | | ESC | X | F4 | G | H | F6 | | QUOT | LALT | F11 | SPC | | | UP | |
+| r4 | | Z | | C | V | M | COMM | DOT | | | ENT | | | | | |
+| r5 | | | | | B | N | | APP | SLSH | RALT | F12 | DOWN | RGHT | | LEFT | |
+| r6 | LCTL | GRV | F1 | F2 | 5 | 6 | EQL | F8 | MINS | | F9 | DEL | INS | PGUP | HOME | |
+| r7 | F5 | 1 | 2 | 3 | 4 | 7 | 8 | 9 | 0 | PSCR | F10 | | | PGDN | END | |
+| | | | | | | | | | | | | | | | | |
+
+Choose any key from the corrosponding row and column and solder it to the pin on the Teensy listed in the firmware config.h
+
+_NOTE: Some of the keys had mislabled columns and rows, so make sure the columns are all connected without diodes to one another, and that the rows are soldered after the diode_
+
+* Keyboard Maintainer: [NaCly](https://github.com/Na-Cly)
+* Hardware Supported: The PCBs, controllers supported
+* Hardware Availability: Leopold FC200RT + Teensy 2.0
+
+Make example for this keyboard (after setting up your build environment):
+
+ make handwired/fc200rt_qmk:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/handwired/fc200rt_qmk/rules.mk b/keyboards/handwired/fc200rt_qmk/rules.mk
new file mode 100644
index 000000000..8ef9dbd6c
--- /dev/null
+++ b/keyboards/handwired/fc200rt_qmk/rules.mk
@@ -0,0 +1,32 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = halfkay
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
diff --git a/keyboards/handwired/jotpad16/config.h b/keyboards/handwired/jotpad16/config.h
index 075f9649c..dc6bb7959 100644
--- a/keyboards/handwired/jotpad16/config.h
+++ b/keyboards/handwired/jotpad16/config.h
@@ -16,13 +16,14 @@
/* pro_micro pin-out */
#define MATRIX_ROW_PINS { B6, B2, D2, D3 }
-#define MATRIX_COL_PINS { B5, B4, B3, B1 }
+#define MATRIX_COL_PINS { E6, D7, B3, B1 }
#define UNUSED_PINS
/* leds */
-#define QMK_LED E6
-#define BACKLIGHT_LEVELS 3
-#define BACKLIGHT_PIN D7
+#define JOTPAD16_LEDS
+#define JOTPAD16_LED1 B5
+#define JOTPAD16_LED2 B4
+#define QMK_LED B5
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
diff --git a/keyboards/handwired/jotpad16/jotpad16.c b/keyboards/handwired/jotpad16/jotpad16.c
index 512234b91..2f112a610 100644
--- a/keyboards/handwired/jotpad16/jotpad16.c
+++ b/keyboards/handwired/jotpad16/jotpad16.c
@@ -4,3 +4,10 @@ void matrix_init_kb(void) {
matrix_init_user();
}
+
+void keyboard_pre_init_kb() {
+ setPinOutput(JOTPAD16_LED1);
+ setPinOutput(JOTPAD16_LED2);
+
+ keyboard_pre_init_user();
+}
diff --git a/keyboards/handwired/jotpad16/readme.md b/keyboards/handwired/jotpad16/readme.md
index 3d971a515..c8773cf18 100644
--- a/keyboards/handwired/jotpad16/readme.md
+++ b/keyboards/handwired/jotpad16/readme.md
@@ -1,7 +1,5 @@
# JotPad16
-![JotPad16](https://i.imgur.com/RwmqWuS.jpg)
-
A ortholinear keypad (4x4) made by jotix.
Keyboard Maintainer: [jotix](https://github.com/jotix)
@@ -16,13 +14,13 @@ Hardware Supported: Arduino Pro Micro
| columns | 0 | 1 | 2 | 3 |
|-------------|----|----|----|----|
-| arduino pin | 9 | 8 | 14 | 15 |
-| qmk pin | B5 | B4 | B3 | C3 |
+| arduino pin | 7 | 6 | 14 | 15 |
+| qmk pin | E6 | D7 | B3 | C3 |
-| | QMK led | Backlight |
-|-------------|-----------|-----------|
-| Arduino pin | 7 | 6 |
-| qmk pin | E6 | D7 |
+| | LED1 | LED2 |
+|-------------|------|------|
+| Arduino pin | 9 | 8 |
+| QMK pin | B5 | B4 |
### Compiling the Firmware
@@ -32,8 +30,12 @@ Make example for this keyboard (after setting up your build environment):
### The Default Keymap
-![Default Keymap](https://i.imgur.com/VJZcFRN.jpg)
+| 7 | 8 | 9 | - |
+|---|---|---|---|
+| 4 | 5 | 6 | + |
+|---|---|---|---|
+| 1 | 2 | 3 |ent|
+|---|---|---|---|
+| 0 | . | / | * |
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
-
-
diff --git a/keyboards/handwired/jotpad16/rules.mk b/keyboards/handwired/jotpad16/rules.mk
index 0c9370f1c..79c32c5c3 100644
--- a/keyboards/handwired/jotpad16/rules.mk
+++ b/keyboards/handwired/jotpad16/rules.mk
@@ -22,7 +22,7 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # 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
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
diff --git a/keyboards/handwired/obuwunkunubi/spaget/config.h b/keyboards/handwired/obuwunkunubi/spaget/config.h
new file mode 100644
index 000000000..79c5d2bf1
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/config.h
@@ -0,0 +1,74 @@
+/*
+Copyright 2020 obuwunkunubi
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x1337
+#define PRODUCT_ID 0x6969
+#define DEVICE_VER 0x0001
+#define MANUFACTURER obuwunkunubi
+#define PRODUCT spaget
+#define DESCRIPTION numpad with 2 encoders and a screen
+
+/* key matrix size */
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 4
+
+// ROWS: Top to bottom, COLS: Left to right
+
+#define MATRIX_ROW_PINS { D4, C6, D7, E6, B4, B5 }
+#define MATRIX_COL_PINS { B1, B3, B2, 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 DEBOUNCE 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
+
+/* Define encoder pins */
+#define ENCODERS_PAD_A { F5, F7 } // 1a, 2a
+#define ENCODERS_PAD_B { F4, F6 } // 1b, 2b
+
+/*
+ * 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
diff --git a/keyboards/handwired/obuwunkunubi/spaget/info.json b/keyboards/handwired/obuwunkunubi/spaget/info.json
new file mode 100644
index 000000000..4228c9c64
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/info.json
@@ -0,0 +1,36 @@
+{
+ "keyboard_name": "spaget",
+ "url": "",
+ "maintainer": "obuwunkunubi",
+ "width": 4,
+ "height": 7.5,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"x":0, "y":0},
+ {"x":3, "y":0},
+ {"x":0, "y":1.5},
+ {"x":1, "y":1.5},
+ {"x":2, "y":1.5},
+ {"x":3, "y":1.5},
+ {"x":0, "y":2.5},
+ {"x":1, "y":2.5},
+ {"x":2, "y":2.5},
+ {"x":3, "y":2.5},
+ {"x":0, "y":3.5},
+ {"x":1, "y":3.5},
+ {"x":2, "y":3.5},
+ {"x":0, "y":4.5},
+ {"x":1, "y":4.5},
+ {"x":2, "y":4.5},
+ {"x":3, "y":3.5, "h":2},
+ {"x":0, "y":5.5},
+ {"x":1, "y":5.5},
+ {"x":2, "y":5.5},
+ {"x":0, "y":6.5, "w":2},
+ {"x":2, "y":6.5},
+ {"x":3, "y":5.5, "h":2}
+ ]
+ }
+ }
+}
diff --git a/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/keymap.c b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/keymap.c
new file mode 100644
index 000000000..1854894e5
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/keymap.c
@@ -0,0 +1,435 @@
+/* Copyright 2020 obuwunkunubi
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include QMK_KEYBOARD_H
+
+// Defines for shortcut macros
+#define KC_CAD LALT(LCTL(KC_DEL)) // CTRL + ALT + DEL
+#define KC_CPY LCTL(KC_C) // Copy
+#define KC_PST LCTL(KC_V) // Paste
+#define KC_AF4 LALT(KC_F4) // ALT + F4
+
+enum custom_keycodes {
+ SELWN = SAFE_RANGE,
+ SELWP,
+ EM1,
+ EM2,
+ EM3,
+ EM4,
+ EM5,
+ EM6,
+ EM7,
+ EM8,
+ EM9,
+ MAKE1,
+ MAKE2,
+ MAIL1,
+ MAIL2,
+ OBUWUN,
+ DIR
+};
+
+enum layer_names {
+ BASE,
+ ONE,
+ TWO
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ /* Keymap BASE: Base Layer
+ *
+ * ,---. ,---.
+ * |NUM| |PLY|
+ * `---' `---'
+ * ,---------------.
+ * |CAL| UP|PRE|NXT|
+ * |---------------|
+ * | = | / | * | - |
+ * |---------------|
+ * | 7 | 8 | 9 | |
+ * |------------ + |
+ * | 4 | 5 | 6 | |
+ * |---------------|
+ * | 1 | 2 | 3 | |
+ * |------------ENT|
+ * | 0 | . | |
+ * `---------------'
+ */
+ [BASE] = LAYOUT( \
+ KC_NLCK, KC_MPLY, \
+ KC_CALC, TO(ONE), KC_MPRV, KC_MNXT, \
+ KC_EQL, KC_PSLS, KC_PAST, KC_MINS, \
+ KC_P7, KC_P8, KC_P9, \
+ KC_P4, KC_P5, KC_P6, KC_PPLS, \
+ KC_P1, KC_P2, KC_P3, \
+ KC_P0, KC_PDOT, KC_PENT \
+ ),
+
+ /* Keymap ONE: Util Layer
+ *
+ * ,---. ,---.
+ * |RST| |CAD|
+ * `---' `---'
+ * ,---------------.
+ * |BAS|TWO|MK1|MK2|
+ * |---------------|
+ * |DIR|@1 |@2 |OBU|
+ * |---------------|
+ * |SWP|AF4|SWN| |
+ * |------------PSC|
+ * |CPY| U |PST| |
+ * |---------------|
+ * | L | D | R | |
+ * |------------ NO|
+ * | NO | NO| |
+ * `---------------'
+ */
+ [ONE] = LAYOUT( \
+ RESET, KC_CAD, \
+ TO(BASE), TO(TWO), MAKE1, MAKE2, \
+ DIR, MAIL1, MAIL2, OBUWUN, \
+ SELWP, KC_AF4, SELWN, \
+ KC_CPY, KC_UP, KC_PST, KC_PSCR, \
+ KC_LEFT, KC_DOWN, KC_RGHT, \
+ KC_P0, KC_PDOT, KC_PENT \
+ ),
+
+ /* Keymap TWO: Emoji Layer
+ *
+ * ,---. ,---.
+ * | NO| | NO|
+ * `---' `---'
+ * ,---------------.
+ * |ONE|BAS| [ | ] |
+ * |---------------|
+ * |F13|F14|F15|F16|
+ * |---------------|
+ * |EM7|EM8|EM9| |
+ * |------------ NO|
+ * |EM4|EM5|EM6| |
+ * |---------------|
+ * |EM1|EM2|EM3| |
+ * |------------ NO|
+ * | NO | NO| |
+ * `---------------'
+ */
+ [TWO] = LAYOUT( \
+ KC_NO, KC_NO, \
+ TO(ONE), TO(BASE), KC_LBRC, KC_RBRC, \
+ KC_F13, KC_F14, KC_F15, KC_F16, \
+ EM7, EM8, EM9, \
+ EM4, EM5, EM6, KC_NO, \
+ EM1, EM2, EM3, \
+ KC_NO, KC_NO, KC_NO \
+ ),
+
+};
+
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+
+ case SELWN: // select and copy next word
+ if (record->event.pressed) {
+ // when keycode SELWN is pressed
+
+ tap_code16(C(S(KC_RGHT)));
+ tap_code16(KC_CPY);
+ return false; break;
+
+ } else {
+ // when keycode SELWN is released
+ }
+ break;
+
+ case SELWP: // select and copy previous word
+ if (record->event.pressed) {
+ // when keycode SELWP is pressed
+
+ tap_code16(C(S(KC_LEFT)));
+ tap_code16(KC_CPY);
+ return false; break;
+
+ } else {
+ // when keycode SELWP is released
+ }
+ break;
+
+ case MAKE1:
+ if (record->event.pressed) {
+ // when keycode MAKE1 is pressed
+
+ send_string("make handwired/obuwunkunubi/spaget:default:avrdude");
+
+ } else {
+ // when keycode MAKE1 is released
+ }
+ break;
+
+ case MAKE2:
+ if (record->event.pressed) {
+ // when keycode MAKE2 is pressed
+
+ send_string("make preonic/rev3:obuwunkunubi:dfu-util");
+
+ } else {
+ // when keycode MAKE2 is released
+ }
+ break;
+
+ case DIR:
+ if (record->event.pressed) {
+ // when keycode DIR is pressed
+
+ send_string("cd /d/Keyboards/qmk/qmk_firmware/");
+
+ } else {
+ // when keycode DIR is released
+ }
+ break;
+
+ case OBUWUN:
+ if (record->event.pressed) {
+ // when keycode OBUWUN is pressed
+
+ send_string("obuwunkunubi");
+
+ } else {
+ // when keycode OBUWUN is released
+ }
+ break;
+
+ case MAIL1:
+ if (record->event.pressed) {
+ // when keycode MAIL1 is pressed
+
+ send_string("marko.bakan7");
+
+ } else {
+ // when keycode MAIL1 is released
+ }
+ break;
+
+ case MAIL2:
+ if (record->event.pressed) {
+ // when keycode MAIL2 is pressed
+
+ send_string("bakan.marko7");
+
+ } else {
+ // when keycode MAIL2 is released
+ }
+ break;
+
+ case EM1:
+ if (record->event.pressed) {
+ // when keycode EM1 is pressed
+
+ send_unicode_string("ʕ•ᴥ•ʔ");
+
+ } else {
+ // when keycode EM1 is released
+ }
+ break;
+
+ case EM2:
+ if (record->event.pressed) {
+ // when keycode EM2 is pressed
+
+ send_unicode_string("༼ つ ◕_◕ ༽つ");
+
+ } else {
+ // when keycode EM2 is released
+ }
+ break;
+
+ case EM3:
+ if (record->event.pressed) {
+ // when keycode EM3 is pressed
+
+ send_unicode_string("( ⌐■_■)");
+
+ } else {
+ // when keycode EM3 is released
+ }
+ break;
+
+ case EM4:
+ if (record->event.pressed) {
+ // when keycode EM4 is pressed
+
+ send_unicode_string("(╯°□°)╯彡 ┻━┻");
+
+ } else {
+ // when keycode EM4 is released
+ }
+ break;
+
+ case EM5:
+ if (record->event.pressed) {
+ // when keycode EM5 is pressed
+
+ send_unicode_string("ಠ_ಠ");
+
+ } else {
+ // when keycode EM5 is released
+ }
+ break;
+
+ case EM6:
+ if (record->event.pressed) {
+ // when keycode EM6 is pressed
+
+ send_unicode_string("( ͡° ͜ʖ ͡°)");
+
+ } else {
+ // when keycode EM6 is released
+ }
+ break;
+
+ case EM7:
+ if (record->event.pressed) {
+ // when keycode EM7 is pressed
+
+ send_unicode_string("(☞゚ヮ゚)☞");
+
+ } else {
+ // when keycode EM7 is released
+ }
+ break;
+
+ case EM8:
+ if (record->event.pressed) {
+ // when keycode EM8 is pressed
+
+ send_unicode_string("(^‿^)");
+
+ } else {
+ // when keycode EM8 is released
+ }
+ break;
+
+ case EM9:
+ if (record->event.pressed) {
+ // when keycode EM9 is pressed
+
+ send_unicode_string("¯\\_(ツ)_/¯");
+
+ } else {
+ // when keycode EM9 is released
+ }
+ break;
+
+ }
+ return true;
+};
+
+// Unicode input mode set to Windows using WinCompose
+void matrix_init_user(void) {
+ set_unicode_input_mode(UC_WINC);
+};
+#ifdef OLED_DRIVER_ENABLE
+void oled_task_user(void) {
+ oled_write_P(PSTR(" spaget v1\n\n"), false);
+
+ // Host Keyboard Layer Status
+ oled_write_P(PSTR("Layer: "), false);
+
+ switch (get_highest_layer(layer_state)) {
+ case BASE:
+ oled_write_P(PSTR("Base\n"), false);
+ break;
+ case ONE:
+ oled_write_P(PSTR("Util\n"), false);
+ break;
+ case TWO:
+ oled_write_P(PSTR("Emoji\n"), false);
+ break;
+ default:
+ oled_write_ln_P(PSTR("Undefined"), false);
+ }
+
+ // Host Keyboard LED Status
+ led_t led_state = host_keyboard_led_state();
+ oled_write_P(PSTR("Lock: "), false);
+ oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
+ oled_write_P(led_state.caps_lock ? PSTR("CAPS ") : PSTR(" "), false);
+ oled_write_P(led_state.scroll_lock ? PSTR("SCROLL ") : PSTR(" "), false);
+}
+#endif
+
+void encoder_update_user(uint8_t index, bool clockwise) {
+ if(IS_LAYER_ON(BASE)) {
+ if (index == 0) { /* First encoder */
+ if (clockwise) {
+ tap_code(KC_PGDN);
+ } else {
+ tap_code(KC_PGUP);
+ }
+ } else if (index == 1) { /* Second encoder */
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ }
+ }
+ else if(IS_LAYER_ON(ONE)) {
+ if (index == 0) { /* First encoder */
+ if (clockwise) {
+ tap_code(KC_WH_R);
+ } else {
+ tap_code(KC_WH_L);
+ }
+ } else if (index == 1) { /* Second encoder */
+ if (clockwise) {
+ tap_code(KC_WH_D);
+ } else {
+ tap_code(KC_WH_U);
+ }
+ }
+ }
+ else if(IS_LAYER_ON(TWO)) {
+ if (index == 0) { /* First encoder */
+ if (clockwise) {
+ tap_code(KC_DEL);
+ } else {
+ tap_code(KC_BSPC);
+ }
+ } else if (index == 1) { /* Second encoder */
+ if (clockwise) {
+ tap_code(KC_DOWN);
+ } else {
+ tap_code(KC_UP);
+ }
+ }
+ }
+ else {
+ if (index == 0) { /* First encoder */
+ if (clockwise) {
+ tap_code(KC_PGDN);
+ } else {
+ tap_code(KC_PGUP);
+ }
+ } else if (index == 1) { /* Second encoder */
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ }
+ }
+}
diff --git a/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/readme.md b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/readme.md
new file mode 100644
index 000000000..9a453e1f6
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/readme.md
@@ -0,0 +1 @@
+# default spaget layout
diff --git a/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/rules.mk b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/rules.mk
new file mode 100644
index 000000000..916b1154b
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/keymaps/default/rules.mk
@@ -0,0 +1 @@
+# Build Overrides
diff --git a/keyboards/handwired/obuwunkunubi/spaget/readme.md b/keyboards/handwired/obuwunkunubi/spaget/readme.md
new file mode 100644
index 000000000..253870a43
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/readme.md
@@ -0,0 +1,14 @@
+# spaget
+
+![spaget](https://i.imgur.com/ktlhskZ.jpg)
+
+A hand wired numpad style QMK macropad, with a 128x32 OLED screen and two rotary encoders. Powered by an Arduino Pro Micro.
+
+* Keyboard Maintainer: [obuwunkunubi](https://github.com/obuwunkunubi)
+* Hardware Supported: spaget v1
+
+Make example for this keyboard (after setting up your build environment):
+
+ make handwired/obuwunkunubi/spaget:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/handwired/obuwunkunubi/spaget/rules.mk b/keyboards/handwired/obuwunkunubi/spaget/rules.mk
new file mode 100644
index 000000000..8be738f3e
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/rules.mk
@@ -0,0 +1,34 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = caterina
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+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
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+MIDI_ENABLE = no # MIDI controls
+AUDIO_ENABLE = no
+UNICODE_ENABLE = yes # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+AUDIO_ENABLE = no # Audio output on port C6
+
+OLED_DRIVER_ENABLE = yes # Enable OLED display support
+ENCODER_ENABLE = yes # Enable encoder support
+
diff --git a/keyboards/handwired/obuwunkunubi/spaget/spaget.c b/keyboards/handwired/obuwunkunubi/spaget/spaget.c
new file mode 100644
index 000000000..aeb0dc543
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/spaget.c
@@ -0,0 +1,16 @@
+/* Copyright 2020 obuwunkunubi
+ *
+ * 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 "spaget.h"
diff --git a/keyboards/handwired/obuwunkunubi/spaget/spaget.h b/keyboards/handwired/obuwunkunubi/spaget/spaget.h
new file mode 100644
index 000000000..7d4b9e9df
--- /dev/null
+++ b/keyboards/handwired/obuwunkunubi/spaget/spaget.h
@@ -0,0 +1,47 @@
+/* Copyright 2020 obuwunkunubi
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+/* This a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+
+// readability
+#define XXX KC_NO
+
+#define LAYOUT( \
+ K23, K43, \
+ K00, K01, K02, K03, \
+ K10, K11, K12, K13, \
+ K20, K21, K22, \
+ K30, K31, K32, K33, \
+ K40, K41, K42, \
+ K51, K52, K53 \
+) { \
+ { K00, K01, K02, K03 }, \
+ { K10, K11, K12, K13 }, \
+ { K20, K21, K22, K23 }, \
+ { K30, K31, K32, K33 }, \
+ { K40, K41, K42, K43 }, \
+ { XXX, K51, K52, K53 } \
+}
diff --git a/keyboards/handwired/slash/rules.mk b/keyboards/handwired/slash/rules.mk
index 4aba5bdeb..092115db1 100644
--- a/keyboards/handwired/slash/rules.mk
+++ b/keyboards/handwired/slash/rules.mk
@@ -5,6 +5,13 @@ MCU = atmega32u4
F_CPU = 8000000
# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
BOOTLOADER = caterina
# Build Options
diff --git a/keyboards/helix/rev2/keymaps/default/keymap.c b/keyboards/helix/rev2/keymaps/default/keymap.c
index 78e3424fd..c575287ee 100644
--- a/keyboards/helix/rev2/keymaps/default/keymap.c
+++ b/keyboards/helix/rev2/keymaps/default/keymap.c
@@ -536,9 +536,9 @@ static void render_logo(struct CharacterMatrix *matrix) {
}
static void render_rgbled_status(bool full, struct CharacterMatrix *matrix) {
-#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_ANIMATIONS)
+#ifdef RGBLIGHT_ENABLE
char buf[30];
- if(rgblight_config.enable) {
+ if (RGBLIGHT_MODES > 1 && rgblight_config.enable) {
if (full) {
snprintf(buf, sizeof(buf), " LED %2d: %d,%d,%d ",
rgblight_config.mode,
diff --git a/keyboards/helix/rev2/keymaps/five_rows/keymap.c b/keyboards/helix/rev2/keymaps/five_rows/keymap.c
index eb73881c6..fcc5c4bbe 100644
--- a/keyboards/helix/rev2/keymaps/five_rows/keymap.c
+++ b/keyboards/helix/rev2/keymaps/five_rows/keymap.c
@@ -496,9 +496,9 @@ static void render_logo(struct CharacterMatrix *matrix) {
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,
0};
matrix_write(matrix, logo);
-#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_ANIMATIONS)
+#ifdef RGBLIGHT_ENABLE
char buf[30];
- if(rgblight_config.enable) {
+ if (RGBLIGHT_MODES > 1 && rgblight_config.enable) {
snprintf(buf, sizeof(buf), " LED %2d: %d,%d,%d ",
rgblight_config.mode,
rgblight_config.hue/RGBLIGHT_HUE_STEP,
diff --git a/keyboards/hineybush/physix/info.json b/keyboards/hineybush/physix/info.json
index 089fcdb26..80319d476 100644
--- a/keyboards/hineybush/physix/info.json
+++ b/keyboards/hineybush/physix/info.json
@@ -6,16 +6,296 @@
"height": 5.25,
"layouts": {
"LAYOUT_all": {
- "layout": [{"label":"Delete", "x":18.75, "y":0}, {"label":"Esc", "x":0.75, "y":0.25}, {"label":"!", "x":1.75, "y":0.25}, {"label":"@", "x":2.75, "y":0.25}, {"label":"#", "x":4, "y":0.25}, {"label":"$", "x":5, "y":0.25}, {"label":"%", "x":6, "y":0.25}, {"label":"^", "x":7, "y":0.25}, {"label":"&", "x":10, "y":0.25}, {"label":"*", "x":11, "y":0.25}, {"label":"(", "x":12, "y":0.25}, {"label":")", "x":13, "y":0.25}, {"label":"_", "x":14.25, "y":0.25}, {"label":"+", "x":15.25, "y":0.25}, {"label":"~", "x":16.25, "y":0.25}, {"label":"Back", "x":17.25, "y":0.25}, {"label":"PgUp", "x":19, "y":1}, {"label":"Tab", "x":0.5, "y":1.25, "w":1.5}, {"label":"Q", "x":2, "y":1.25}, {"label":"W", "x":3.5, "y":1.25}, {"label":"E", "x":4.5, "y":1.25}, {"label":"R", "x":5.5, "y":1.25}, {"label":"T", "x":6.5, "y":1.25}, {"label":"Y", "x":9.5, "y":1.25}, {"label":"U", "x":10.5, "y":1.25}, {"label":"I", "x":11.5, "y":1.25}, {"label":"O", "x":12.5, "y":1.25}, {"label":"P", "x":14, "y":1.25}, {"label":"{", "x":15, "y":1.25}, {"label":"}", "x":16, "y":1.25}, {"label":"|", "x":17, "y":1.25, "w":1.5}, {"label":"PgDn", "x":19.25, "y":2}, {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75}, {"label":"A", "x":2, "y":2.25}, {"label":"S", "x":3.75, "y":2.25}, {"label":"D", "x":4.75, "y":2.25}, {"label":"F", "x":5.75, "y":2.25}, {"label":"G", "x":6.75, "y":2.25}, {"label":"H", "x":9.75, "y":2.25}, {"label":"J", "x":10.75, "y":2.25}, {"label":"K", "x":11.75, "y":2.25}, {"label":"L", "x":12.75, "y":2.25}, {"label":":", "x":14.5, "y":2.25}, {"label":"\"", "x":15.5, "y":2.25}, {"label":"Enter", "x":16.5, "y":2.25, "w":2.25}, {"label":"Shift", "x":0, "y":3.25, "w":2.25}, {"label":"Z", "x":2.25, "y":3.25}, {"label":"X", "x":4.25, "y":3.25}, {"label":"C", "x":5.25, "y":3.25}, {"label":"V", "x":6.25, "y":3.25}, {"label":"B", "x":7.25, "y":3.25}, {"label":"B", "x":9.25, "y":3.25}, {"label":"N", "x":10.25, "y":3.25}, {"label":"M", "x":11.25, "y":3.25}, {"label":"<", "x":12.25, "y":3.25}, {"label":">", "x":14, "y":3.25}, {"label":"?", "x":15, "y":3.25}, {"label":"Shift", "x":16, "y":3.25, "w":1.75}, {"label":"\u2191", "x":17.75, "y":3.25}, {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5}, {"label":"Alt", "x":4, "y":4.25, "w":1.25}, {"label":"Space", "x":5.25, "y":4.25, "w":2.25}, {"label":"Layer 2", "x":7.5, "y":4.25}, {"label":"Space", "x":9, "y":4.25, "w":2}, {"x":11, "y":4.25}, {"label":"Right Alt", "x":12, "y":4.25}, {"label":"Win", "x":15.25, "y":4.25, "w":1.5}, {"label":"\u2190", "x":16.75, "y":4.25}, {"label":"\u2193", "x":17.75, "y":4.25}, {"label":"\u2192", "x":18.75, "y":4.25}]
+ "layout": [
+ {"label":"Esc", "x":0.75, "y":0.25},
+ {"label":"!", "x":1.75, "y":0.25},
+ {"label":"@", "x":2.75, "y":0.25},
+ {"label":"#", "x":4, "y":0.25},
+ {"label":"$", "x":5, "y":0.25},
+ {"label":"%", "x":6, "y":0.25},
+ {"label":"^", "x":7, "y":0.25},
+ {"label":"&", "x":10, "y":0.25},
+ {"label":"*", "x":11, "y":0.25},
+ {"label":"(", "x":12, "y":0.25},
+ {"label":")", "x":13, "y":0.25},
+ {"label":"_", "x":14.25, "y":0.25},
+ {"label":"+", "x":15.25, "y":0.25},
+ {"label":"~", "x":16.25, "y":0.25},
+ {"label":"Back", "x":17.25, "y":0.25},
+ {"label":"Delete", "x":18.75, "y":0},
+ {"label":"Tab", "x":0.5, "y":1.25, "w":1.5},
+ {"label":"Q", "x":2, "y":1.25},
+ {"label":"W", "x":3.5, "y":1.25},
+ {"label":"E", "x":4.5, "y":1.25},
+ {"label":"R", "x":5.5, "y":1.25},
+ {"label":"T", "x":6.5, "y":1.25},
+ {"label":"Y", "x":9.5, "y":1.25},
+ {"label":"U", "x":10.5, "y":1.25},
+ {"label":"I", "x":11.5, "y":1.25},
+ {"label":"O", "x":12.5, "y":1.25},
+ {"label":"P", "x":14, "y":1.25},
+ {"label":"{", "x":15, "y":1.25},
+ {"label":"}", "x":16, "y":1.25},
+ {"label":"|", "x":17, "y":1.25, "w":1.5},
+ {"label":"PgUp", "x":19, "y":1},
+ {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75},
+ {"label":"A", "x":2, "y":2.25},
+ {"label":"S", "x":3.75, "y":2.25},
+ {"label":"D", "x":4.75, "y":2.25},
+ {"label":"F", "x":5.75, "y":2.25},
+ {"label":"G", "x":6.75, "y":2.25},
+ {"label":"H", "x":9.75, "y":2.25},
+ {"label":"J", "x":10.75, "y":2.25},
+ {"label":"K", "x":11.75, "y":2.25},
+ {"label":"L", "x":12.75, "y":2.25},
+ {"label":":", "x":14.5, "y":2.25},
+ {"label":"\"", "x":15.5, "y":2.25},
+ {"label":"Enter", "x":16.5, "y":2.25, "w":2.25},
+ {"label":"PgDn", "x":19.25, "y":2},
+ {"label":"Shift", "x":0, "y":3.25, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3.25},
+ {"label":"X", "x":4.25, "y":3.25},
+ {"label":"C", "x":5.25, "y":3.25},
+ {"label":"V", "x":6.25, "y":3.25},
+ {"label":"B", "x":7.25, "y":3.25},
+ {"label":"B", "x":9.25, "y":3.25},
+ {"label":"N", "x":10.25, "y":3.25},
+ {"label":"M", "x":11.25, "y":3.25},
+ {"label":"<", "x":12.25, "y":3.25},
+ {"label":">", "x":14, "y":3.25},
+ {"label":"?", "x":15, "y":3.25},
+ {"label":"Shift", "x":16, "y":3.25, "w":1.75},
+ {"label":"\u2191", "x":17.75, "y":3.25},
+ {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5},
+ {"label":"Alt", "x":4, "y":4.25, "w":1.25},
+ {"label":"Space", "x":5.25, "y":4.25, "w":2.25},
+ {"label":"Layer 2", "x":7.5, "y":4.25},
+ {"label":"Space", "x":9, "y":4.25, "w":2},
+ {"x":11, "y":4.25},
+ {"label":"Right Alt", "x":12, "y":4.25},
+ {"label":"Win", "x":15.25, "y":4.25, "w":1.5},
+ {"label":"\u2190", "x":16.75, "y":4.25},
+ {"label":"\u2193", "x":17.75, "y":4.25},
+ {"label":"\u2192", "x":18.75, "y":4.25}
+ ]
},
"LAYOUT_split_bksp_275_rspace": {
- "layout": [{"label":"Delete", "x":18.75, "y":0}, {"label":"Esc", "x":0.75, "y":0.25}, {"label":"!", "x":1.75, "y":0.25}, {"label":"@", "x":2.75, "y":0.25}, {"label":"#", "x":4, "y":0.25}, {"label":"$", "x":5, "y":0.25}, {"label":"%", "x":6, "y":0.25}, {"label":"^", "x":7, "y":0.25}, {"label":"&", "x":10, "y":0.25}, {"label":"*", "x":11, "y":0.25}, {"label":"(", "x":12, "y":0.25}, {"label":")", "x":13, "y":0.25}, {"label":"_", "x":14.25, "y":0.25}, {"label":"+", "x":15.25, "y":0.25}, {"label":"~", "x":16.25, "y":0.25}, {"label":"Back", "x":17.25, "y":0.25}, {"label":"PgUp", "x":19, "y":1}, {"label":"Tab", "x":0.5, "y":1.25, "w":1.5}, {"label":"Q", "x":2, "y":1.25}, {"label":"W", "x":3.5, "y":1.25}, {"label":"E", "x":4.5, "y":1.25}, {"label":"R", "x":5.5, "y":1.25}, {"label":"T", "x":6.5, "y":1.25}, {"label":"Y", "x":9.5, "y":1.25}, {"label":"U", "x":10.5, "y":1.25}, {"label":"I", "x":11.5, "y":1.25}, {"label":"O", "x":12.5, "y":1.25}, {"label":"P", "x":14, "y":1.25}, {"label":"{", "x":15, "y":1.25}, {"label":"}", "x":16, "y":1.25}, {"label":"|", "x":17, "y":1.25, "w":1.5}, {"label":"PgDn", "x":19.25, "y":2}, {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75}, {"label":"A", "x":2, "y":2.25}, {"label":"S", "x":3.75, "y":2.25}, {"label":"D", "x":4.75, "y":2.25}, {"label":"F", "x":5.75, "y":2.25}, {"label":"G", "x":6.75, "y":2.25}, {"label":"H", "x":9.75, "y":2.25}, {"label":"J", "x":10.75, "y":2.25}, {"label":"K", "x":11.75, "y":2.25}, {"label":"L", "x":12.75, "y":2.25}, {"label":":", "x":14.5, "y":2.25}, {"label":"\"", "x":15.5, "y":2.25}, {"label":"Enter", "x":16.5, "y":2.25, "w":2.25}, {"label":"Shift", "x":0, "y":3.25, "w":2.25}, {"label":"Z", "x":2.25, "y":3.25}, {"label":"X", "x":4.25, "y":3.25}, {"label":"C", "x":5.25, "y":3.25}, {"label":"V", "x":6.25, "y":3.25}, {"label":"B", "x":7.25, "y":3.25}, {"label":"B", "x":9.25, "y":3.25}, {"label":"N", "x":10.25, "y":3.25}, {"label":"M", "x":11.25, "y":3.25}, {"label":"<", "x":12.25, "y":3.25}, {"label":">", "x":14, "y":3.25}, {"label":"?", "x":15, "y":3.25}, {"label":"Shift", "x":16, "y":3.25, "w":1.75}, {"label":"\u2191", "x":17.75, "y":3.25}, {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5}, {"label":"Alt", "x":4, "y":4.25, "w":1.25}, {"label":"Space", "x":5.25, "y":4.25, "w":2.25}, {"label":"Layer 2", "x":7.5, "y":4.25}, {"label":"Space", "x":9, "y":4.25, "w":2.75}, {"label":"Right Alt", "x":11.75, "y":4.25, "w":1.25}, {"label":"Win", "x":15.25, "y":4.25, "w":1.5}, {"label":"\u2190", "x":16.75, "y":4.25}, {"label":"\u2193", "x":17.75, "y":4.25}, {"label":"\u2192", "x":18.75, "y":4.25}]
+ "layout": [
+ {"label":"Esc", "x":0.75, "y":0.25},
+ {"label":"!", "x":1.75, "y":0.25},
+ {"label":"@", "x":2.75, "y":0.25},
+ {"label":"#", "x":4, "y":0.25},
+ {"label":"$", "x":5, "y":0.25},
+ {"label":"%", "x":6, "y":0.25},
+ {"label":"^", "x":7, "y":0.25},
+ {"label":"&", "x":10, "y":0.25},
+ {"label":"*", "x":11, "y":0.25},
+ {"label":"(", "x":12, "y":0.25},
+ {"label":")", "x":13, "y":0.25},
+ {"label":"_", "x":14.25, "y":0.25},
+ {"label":"+", "x":15.25, "y":0.25},
+ {"label":"~", "x":16.25, "y":0.25},
+ {"label":"Back", "x":17.25, "y":0.25},
+ {"label":"Delete", "x":18.75, "y":0},
+ {"label":"Tab", "x":0.5, "y":1.25, "w":1.5},
+ {"label":"Q", "x":2, "y":1.25},
+ {"label":"W", "x":3.5, "y":1.25},
+ {"label":"E", "x":4.5, "y":1.25},
+ {"label":"R", "x":5.5, "y":1.25},
+ {"label":"T", "x":6.5, "y":1.25},
+ {"label":"Y", "x":9.5, "y":1.25},
+ {"label":"U", "x":10.5, "y":1.25},
+ {"label":"I", "x":11.5, "y":1.25},
+ {"label":"O", "x":12.5, "y":1.25},
+ {"label":"P", "x":14, "y":1.25},
+ {"label":"{", "x":15, "y":1.25},
+ {"label":"}", "x":16, "y":1.25},
+ {"label":"|", "x":17, "y":1.25, "w":1.5},
+ {"label":"PgUp", "x":19, "y":1},
+ {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75},
+ {"label":"A", "x":2, "y":2.25},
+ {"label":"S", "x":3.75, "y":2.25},
+ {"label":"D", "x":4.75, "y":2.25},
+ {"label":"F", "x":5.75, "y":2.25},
+ {"label":"G", "x":6.75, "y":2.25},
+ {"label":"H", "x":9.75, "y":2.25},
+ {"label":"J", "x":10.75, "y":2.25},
+ {"label":"K", "x":11.75, "y":2.25},
+ {"label":"L", "x":12.75, "y":2.25},
+ {"label":":", "x":14.5, "y":2.25},
+ {"label":"\"", "x":15.5, "y":2.25},
+ {"label":"Enter", "x":16.5, "y":2.25, "w":2.25},
+ {"label":"PgDn", "x":19.25, "y":2},
+ {"label":"Shift", "x":0, "y":3.25, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3.25},
+ {"label":"X", "x":4.25, "y":3.25},
+ {"label":"C", "x":5.25, "y":3.25},
+ {"label":"V", "x":6.25, "y":3.25},
+ {"label":"B", "x":7.25, "y":3.25},
+ {"label":"B", "x":9.25, "y":3.25},
+ {"label":"N", "x":10.25, "y":3.25},
+ {"label":"M", "x":11.25, "y":3.25},
+ {"label":"<", "x":12.25, "y":3.25},
+ {"label":">", "x":14, "y":3.25},
+ {"label":"?", "x":15, "y":3.25},
+ {"label":"Shift", "x":16, "y":3.25, "w":1.75},
+ {"label":"\u2191", "x":17.75, "y":3.25},
+ {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5},
+ {"label":"Alt", "x":4, "y":4.25, "w":1.25},
+ {"label":"Space", "x":5.25, "y":4.25, "w":2.25},
+ {"label":"Layer 2", "x":7.5, "y":4.25},
+ {"label":"Space", "x":9, "y":4.25, "w":2.75},
+ {"label":"Right Alt", "x":11.75, "y":4.25, "w":1.25},
+ {"label":"Win", "x":15.25, "y":4.25, "w":1.5},
+ {"label":"\u2190", "x":16.75, "y":4.25},
+ {"label":"\u2193", "x":17.75, "y":4.25},
+ {"label":"\u2192", "x":18.75, "y":4.25}
+ ]
},
"LAYOUT_full_bksp_275_rspace": {
- "layout": [{"label":"Delete", "x":18.75, "y":0}, {"label":"Esc", "x":0.75, "y":0.25}, {"label":"!", "x":1.75, "y":0.25}, {"label":"@", "x":2.75, "y":0.25}, {"label":"#", "x":4, "y":0.25}, {"label":"$", "x":5, "y":0.25}, {"label":"%", "x":6, "y":0.25}, {"label":"^", "x":7, "y":0.25}, {"label":"&", "x":10, "y":0.25}, {"label":"*", "x":11, "y":0.25}, {"label":"(", "x":12, "y":0.25}, {"label":")", "x":13, "y":0.25}, {"label":"_", "x":14.25, "y":0.25}, {"label":"+", "x":15.25, "y":0.25}, {"label":"Back", "x":16.25, "y":0.25, "w":2}, {"label":"PgUp", "x":19, "y":1}, {"label":"Tab", "x":0.5, "y":1.25, "w":1.5}, {"label":"Q", "x":2, "y":1.25}, {"label":"W", "x":3.5, "y":1.25}, {"label":"E", "x":4.5, "y":1.25}, {"label":"R", "x":5.5, "y":1.25}, {"label":"T", "x":6.5, "y":1.25}, {"label":"Y", "x":9.5, "y":1.25}, {"label":"U", "x":10.5, "y":1.25}, {"label":"I", "x":11.5, "y":1.25}, {"label":"O", "x":12.5, "y":1.25}, {"label":"P", "x":14, "y":1.25}, {"label":"{", "x":15, "y":1.25}, {"label":"}", "x":16, "y":1.25}, {"label":"|", "x":17, "y":1.25, "w":1.5}, {"label":"PgDn", "x":19.25, "y":2}, {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75}, {"label":"A", "x":2, "y":2.25}, {"label":"S", "x":3.75, "y":2.25}, {"label":"D", "x":4.75, "y":2.25}, {"label":"F", "x":5.75, "y":2.25}, {"label":"G", "x":6.75, "y":2.25}, {"label":"H", "x":9.75, "y":2.25}, {"label":"J", "x":10.75, "y":2.25}, {"label":"K", "x":11.75, "y":2.25}, {"label":"L", "x":12.75, "y":2.25}, {"label":":", "x":14.5, "y":2.25}, {"label":"\"", "x":15.5, "y":2.25}, {"label":"Enter", "x":16.5, "y":2.25, "w":2.25}, {"label":"Shift", "x":0, "y":3.25, "w":2.25}, {"label":"Z", "x":2.25, "y":3.25}, {"label":"X", "x":4.25, "y":3.25}, {"label":"C", "x":5.25, "y":3.25}, {"label":"V", "x":6.25, "y":3.25}, {"label":"B", "x":7.25, "y":3.25}, {"label":"B", "x":9.25, "y":3.25}, {"label":"N", "x":10.25, "y":3.25}, {"label":"M", "x":11.25, "y":3.25}, {"label":"<", "x":12.25, "y":3.25}, {"label":">", "x":14, "y":3.25}, {"label":"?", "x":15, "y":3.25}, {"label":"Shift", "x":16, "y":3.25, "w":1.75}, {"label":"\u2191", "x":17.75, "y":3.25}, {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5}, {"label":"Alt", "x":4, "y":4.25, "w":1.25}, {"label":"Space", "x":5.25, "y":4.25, "w":2.25}, {"label":"Layer 2", "x":7.5, "y":4.25}, {"label":"Space", "x":9, "y":4.25, "w":2.75}, {"label":"Right Alt", "x":11.75, "y":4.25, "w":1.25}, {"label":"Win", "x":15.25, "y":4.25, "w":1.5}, {"label":"\u2190", "x":16.75, "y":4.25}, {"label":"\u2193", "x":17.75, "y":4.25}, {"label":"\u2192", "x":18.75, "y":4.25}]
+ "layout": [
+ {"label":"Esc", "x":0.75, "y":0.25},
+ {"label":"!", "x":1.75, "y":0.25},
+ {"label":"@", "x":2.75, "y":0.25},
+ {"label":"#", "x":4, "y":0.25},
+ {"label":"$", "x":5, "y":0.25},
+ {"label":"%", "x":6, "y":0.25},
+ {"label":"^", "x":7, "y":0.25},
+ {"label":"&", "x":10, "y":0.25},
+ {"label":"*", "x":11, "y":0.25},
+ {"label":"(", "x":12, "y":0.25},
+ {"label":")", "x":13, "y":0.25},
+ {"label":"_", "x":14.25, "y":0.25},
+ {"label":"+", "x":15.25, "y":0.25},
+ {"label":"Back", "x":16.25, "y":0.25, "w":2},
+ {"label":"Delete", "x":18.75, "y":0},
+ {"label":"Tab", "x":0.5, "y":1.25, "w":1.5},
+ {"label":"Q", "x":2, "y":1.25},
+ {"label":"W", "x":3.5, "y":1.25},
+ {"label":"E", "x":4.5, "y":1.25},
+ {"label":"R", "x":5.5, "y":1.25},
+ {"label":"T", "x":6.5, "y":1.25},
+ {"label":"Y", "x":9.5, "y":1.25},
+ {"label":"U", "x":10.5, "y":1.25},
+ {"label":"I", "x":11.5, "y":1.25},
+ {"label":"O", "x":12.5, "y":1.25},
+ {"label":"P", "x":14, "y":1.25},
+ {"label":"{", "x":15, "y":1.25},
+ {"label":"}", "x":16, "y":1.25},
+ {"label":"|", "x":17, "y":1.25, "w":1.5},
+ {"label":"PgUp", "x":19, "y":1},
+ {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75},
+ {"label":"A", "x":2, "y":2.25},
+ {"label":"S", "x":3.75, "y":2.25},
+ {"label":"D", "x":4.75, "y":2.25},
+ {"label":"F", "x":5.75, "y":2.25},
+ {"label":"G", "x":6.75, "y":2.25},
+ {"label":"H", "x":9.75, "y":2.25},
+ {"label":"J", "x":10.75, "y":2.25},
+ {"label":"K", "x":11.75, "y":2.25},
+ {"label":"L", "x":12.75, "y":2.25},
+ {"label":":", "x":14.5, "y":2.25},
+ {"label":"\"", "x":15.5, "y":2.25},
+ {"label":"Enter", "x":16.5, "y":2.25, "w":2.25},
+ {"label":"PgDn", "x":19.25, "y":2},
+ {"label":"Shift", "x":0, "y":3.25, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3.25},
+ {"label":"X", "x":4.25, "y":3.25},
+ {"label":"C", "x":5.25, "y":3.25},
+ {"label":"V", "x":6.25, "y":3.25},
+ {"label":"B", "x":7.25, "y":3.25},
+ {"label":"B", "x":9.25, "y":3.25},
+ {"label":"N", "x":10.25, "y":3.25},
+ {"label":"M", "x":11.25, "y":3.25},
+ {"label":"<", "x":12.25, "y":3.25},
+ {"label":">", "x":14, "y":3.25},
+ {"label":"?", "x":15, "y":3.25},
+ {"label":"Shift", "x":16, "y":3.25, "w":1.75},
+ {"label":"\u2191", "x":17.75, "y":3.25},
+ {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5},
+ {"label":"Alt", "x":4, "y":4.25, "w":1.25},
+ {"label":"Space", "x":5.25, "y":4.25, "w":2.25},
+ {"label":"Layer 2", "x":7.5, "y":4.25},
+ {"label":"Space", "x":9, "y":4.25, "w":2.75},
+ {"label":"Right Alt", "x":11.75, "y":4.25, "w":1.25},
+ {"label":"Win", "x":15.25, "y":4.25, "w":1.5},
+ {"label":"\u2190", "x":16.75, "y":4.25},
+ {"label":"\u2193", "x":17.75, "y":4.25},
+ {"label":"\u2192", "x":18.75, "y":4.25}
+ ]
},
"LAYOUT_full_bksp_200_rspace": {
- "layout": [{"label":"Delete", "x":18.75, "y":0}, {"label":"Esc", "x":0.75, "y":0.25}, {"label":"!", "x":1.75, "y":0.25}, {"label":"@", "x":2.75, "y":0.25}, {"label":"#", "x":4, "y":0.25}, {"label":"$", "x":5, "y":0.25}, {"label":"%", "x":6, "y":0.25}, {"label":"^", "x":7, "y":0.25}, {"label":"&", "x":10, "y":0.25}, {"label":"*", "x":11, "y":0.25}, {"label":"(", "x":12, "y":0.25}, {"label":")", "x":13, "y":0.25}, {"label":"_", "x":14.25, "y":0.25}, {"label":"+", "x":15.25, "y":0.25}, {"label":"Back", "x":16.25, "y":0.25, "w":2}, {"label":"PgUp", "x":19, "y":1}, {"label":"Tab", "x":0.5, "y":1.25, "w":1.5}, {"label":"Q", "x":2, "y":1.25}, {"label":"W", "x":3.5, "y":1.25}, {"label":"E", "x":4.5, "y":1.25}, {"label":"R", "x":5.5, "y":1.25}, {"label":"T", "x":6.5, "y":1.25}, {"label":"Y", "x":9.5, "y":1.25}, {"label":"U", "x":10.5, "y":1.25}, {"label":"I", "x":11.5, "y":1.25}, {"label":"O", "x":12.5, "y":1.25}, {"label":"P", "x":14, "y":1.25}, {"label":"{", "x":15, "y":1.25}, {"label":"}", "x":16, "y":1.25}, {"label":"|", "x":17, "y":1.25, "w":1.5}, {"label":"PgDn", "x":19.25, "y":2}, {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75}, {"label":"A", "x":2, "y":2.25}, {"label":"S", "x":3.75, "y":2.25}, {"label":"D", "x":4.75, "y":2.25}, {"label":"F", "x":5.75, "y":2.25}, {"label":"G", "x":6.75, "y":2.25}, {"label":"H", "x":9.75, "y":2.25}, {"label":"J", "x":10.75, "y":2.25}, {"label":"K", "x":11.75, "y":2.25}, {"label":"L", "x":12.75, "y":2.25}, {"label":":", "x":14.5, "y":2.25}, {"label":"\"", "x":15.5, "y":2.25}, {"label":"Enter", "x":16.5, "y":2.25, "w":2.25}, {"label":"Shift", "x":0, "y":3.25, "w":2.25}, {"label":"Z", "x":2.25, "y":3.25}, {"label":"X", "x":4.25, "y":3.25}, {"label":"C", "x":5.25, "y":3.25}, {"label":"V", "x":6.25, "y":3.25}, {"label":"B", "x":7.25, "y":3.25}, {"label":"B", "x":9.25, "y":3.25}, {"label":"N", "x":10.25, "y":3.25}, {"label":"M", "x":11.25, "y":3.25}, {"label":"<", "x":12.25, "y":3.25}, {"label":">", "x":14, "y":3.25}, {"label":"?", "x":15, "y":3.25}, {"label":"Shift", "x":16, "y":3.25, "w":1.75}, {"label":"\u2191", "x":17.75, "y":3.25}, {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5}, {"label":"Alt", "x":4, "y":4.25, "w":1.25}, {"label":"Space", "x":5.25, "y":4.25, "w":2.25}, {"label":"Layer 2", "x":7.5, "y":4.25}, {"label":"Space", "x":9, "y":4.25, "w":2}, {"x":11, "y":4.25}, {"label":"Right Alt", "x":12, "y":4.25}, {"label":"Win", "x":15.25, "y":4.25, "w":1.5}, {"label":"\u2190", "x":16.75, "y":4.25}, {"label":"\u2193", "x":17.75, "y":4.25}, {"label":"\u2192", "x":18.75, "y":4.25}]
+ "layout": [
+ {"label":"Esc", "x":0.75, "y":0.25},
+ {"label":"!", "x":1.75, "y":0.25},
+ {"label":"@", "x":2.75, "y":0.25},
+ {"label":"#", "x":4, "y":0.25},
+ {"label":"$", "x":5, "y":0.25},
+ {"label":"%", "x":6, "y":0.25},
+ {"label":"^", "x":7, "y":0.25},
+ {"label":"&", "x":10, "y":0.25},
+ {"label":"*", "x":11, "y":0.25},
+ {"label":"(", "x":12, "y":0.25},
+ {"label":")", "x":13, "y":0.25},
+ {"label":"_", "x":14.25, "y":0.25},
+ {"label":"+", "x":15.25, "y":0.25},
+ {"label":"Back", "x":16.25, "y":0.25, "w":2},
+ {"label":"Delete", "x":18.75, "y":0},
+ {"label":"Tab", "x":0.5, "y":1.25, "w":1.5},
+ {"label":"Q", "x":2, "y":1.25},
+ {"label":"W", "x":3.5, "y":1.25},
+ {"label":"E", "x":4.5, "y":1.25},
+ {"label":"R", "x":5.5, "y":1.25},
+ {"label":"T", "x":6.5, "y":1.25},
+ {"label":"Y", "x":9.5, "y":1.25},
+ {"label":"U", "x":10.5, "y":1.25},
+ {"label":"I", "x":11.5, "y":1.25},
+ {"label":"O", "x":12.5, "y":1.25},
+ {"label":"P", "x":14, "y":1.25},
+ {"label":"{", "x":15, "y":1.25},
+ {"label":"}", "x":16, "y":1.25},
+ {"label":"|", "x":17, "y":1.25, "w":1.5},
+ {"label":"PgUp", "x":19, "y":1},
+ {"label":"Caps Lock", "x":0.25, "y":2.25, "w":1.75},
+ {"label":"A", "x":2, "y":2.25},
+ {"label":"S", "x":3.75, "y":2.25},
+ {"label":"D", "x":4.75, "y":2.25},
+ {"label":"F", "x":5.75, "y":2.25},
+ {"label":"G", "x":6.75, "y":2.25},
+ {"label":"H", "x":9.75, "y":2.25},
+ {"label":"J", "x":10.75, "y":2.25},
+ {"label":"K", "x":11.75, "y":2.25},
+ {"label":"L", "x":12.75, "y":2.25},
+ {"label":":", "x":14.5, "y":2.25},
+ {"label":"\"", "x":15.5, "y":2.25},
+ {"label":"Enter", "x":16.5, "y":2.25, "w":2.25},
+ {"label":"PgDn", "x":19.25, "y":2},
+ {"label":"Shift", "x":0, "y":3.25, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3.25},
+ {"label":"X", "x":4.25, "y":3.25},
+ {"label":"C", "x":5.25, "y":3.25},
+ {"label":"V", "x":6.25, "y":3.25},
+ {"label":"B", "x":7.25, "y":3.25},
+ {"label":"B", "x":9.25, "y":3.25},
+ {"label":"N", "x":10.25, "y":3.25},
+ {"label":"M", "x":11.25, "y":3.25},
+ {"label":"<", "x":12.25, "y":3.25},
+ {"label":">", "x":14, "y":3.25},
+ {"label":"?", "x":15, "y":3.25},
+ {"label":"Shift", "x":16, "y":3.25, "w":1.75},
+ {"label":"\u2191", "x":17.75, "y":3.25},
+ {"label":"Ctrl", "x":0.25, "y":4.25, "w":1.5},
+ {"label":"Alt", "x":4, "y":4.25, "w":1.25},
+ {"label":"Space", "x":5.25, "y":4.25, "w":2.25},
+ {"label":"Layer 2", "x":7.5, "y":4.25},
+ {"label":"Space", "x":9, "y":4.25, "w":2},
+ {"x":11, "y":4.25},
+ {"label":"Right Alt", "x":12, "y":4.25},
+ {"label":"Win", "x":15.25, "y":4.25, "w":1.5},
+ {"label":"\u2190", "x":16.75, "y":4.25},
+ {"label":"\u2193", "x":17.75, "y":4.25},
+ {"label":"\u2192", "x":18.75, "y":4.25}
+ ]
}
}
}
diff --git a/keyboards/id80/config.h b/keyboards/id80/config.h
new file mode 100644
index 000000000..12ee5400c
--- /dev/null
+++ b/keyboards/id80/config.h
@@ -0,0 +1,88 @@
+/*
+Copyright 2020 Sergey Vlasov <sigprof@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/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x6964 /* "id" */
+#define PRODUCT_ID 0x0080
+#define DEVICE_VER 0x0001
+#define MANUFACTURER IDOBAO
+#define PRODUCT ID80
+#define DESCRIPTION A 75% hotswap keyboard
+
+/* key matrix size */
+#define MATRIX_ROWS 11
+#define MATRIX_COLS 9
+
+/*
+ * 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)
+ *
+ * The matrix description in the vendor-supplied JSON file for kbfirmware.com
+ * had 12 rows:
+ * { B7, B3, B2, B1, B0, E6, F0, F1, F4, F5, F6, F7 }
+ * However, the row 6 was completely empty, and the pin F0 was not actually
+ * routed anywhere on the PCB, therefore this row was removed to save some
+ * resources (the EEPROM space for dynamic keymaps is especially scarce).
+ */
+#define MATRIX_ROW_PINS { B7, B3, B2, B1, B0, E6, F1, F4, F5, F6, F7 }
+#define MATRIX_COL_PINS { D0, D1, D2, D3, D5, D4, D6, D7, B4 }
+
+#define DIODE_DIRECTION ROW2COL
+
+#define BACKLIGHT_PIN B6
+// #define BACKLIGHT_BREATHING
+#define BACKLIGHT_LEVELS 3
+
+#define CAPS_LOCK_LED_PIN C7
+
+#define RGB_DI_PIN E2
+#ifdef RGB_DI_PIN
+ #define RGBLED_NUM 20 /* 16 underglow LEDs, 4 top LEDs */
+ #define RGBLIGHT_HUE_STEP 8
+ #define RGBLIGHT_SAT_STEP 8
+ #define RGBLIGHT_VAL_STEP 8
+ #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
+ #define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+/*== all animations enable ==*/
+ #define RGBLIGHT_ANIMATIONS
+// /*== or choose animations ==*/
+// #define RGBLIGHT_EFFECT_BREATHING
+// #define RGBLIGHT_EFFECT_RAINBOW_MOOD
+// #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+// #define RGBLIGHT_EFFECT_SNAKE
+// #define RGBLIGHT_EFFECT_KNIGHT
+// #define RGBLIGHT_EFFECT_CHRISTMAS
+// #define RGBLIGHT_EFFECT_STATIC_GRADIENT
+// #define RGBLIGHT_EFFECT_RGB_TEST
+// #define RGBLIGHT_EFFECT_ALTERNATING
+#endif
+
+/* Bootmagic Lite key configuration: use the Esc key */
+#define BOOTMAGIC_LITE_ROW 5
+#define BOOTMAGIC_LITE_COLUMN 0
+
+// partially generated by KBFirmware JSON to QMK Parser
+// https://noroadsleft.github.io/kbf_qmk_converter/
diff --git a/keyboards/id80/id80.c b/keyboards/id80/id80.c
new file mode 100644
index 000000000..5e5dbc312
--- /dev/null
+++ b/keyboards/id80/id80.c
@@ -0,0 +1,36 @@
+/* Copyright 2020 Sergey Vlasov <sigprof@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 "id80.h"
+
+void matrix_init_kb(void) {
+ led_init_ports();
+ matrix_init_user();
+}
+
+void led_init_ports(void) {
+ setPinOutput(CAPS_LOCK_LED_PIN);
+}
+
+bool led_update_kb(led_t led_state) {
+ bool res = led_update_user(led_state);
+ if (res) {
+ writePin(CAPS_LOCK_LED_PIN, !led_state.caps_lock);
+ }
+ return res;
+}
+
+// partially generated by KBFirmware JSON to QMK Parser
+// https://noroadsleft.github.io/kbf_qmk_converter/
diff --git a/keyboards/id80/id80.h b/keyboards/id80/id80.h
new file mode 100644
index 000000000..2f2cab71b
--- /dev/null
+++ b/keyboards/id80/id80.h
@@ -0,0 +1,42 @@
+/* Copyright 2020 Sergey Vlasov <sigprof@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/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT( \
+ K50, K51, K52, K53, K54, K55, K56, K57, K58, KA7, KA5, KA4, KA3, KA6, KA2, \
+ K40, K41, K42, K43, K44, K45, K46, K47, K48, K98, K97, K95, K94, K96, K92, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K88, K87, K85, K84, K83, K82, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K78, K77, K75, K74, \
+ K10, K12, K13, K14, K15, K16, K17, K18, K68, K67, K65, K64, K63, \
+ K00, K01, K02, K06, K08, K07, K05, K04, K03 \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08 }, \
+ { K10, KC_NO, K12, K13, K14, K15, K16, K17, K18 }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28 }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38 }, \
+ { K40, K41, K42, K43, K44, K45, K46, K47, K48 }, \
+ { K50, K51, K52, K53, K54, K55, K56, K57, K58 }, \
+ { KC_NO, KC_NO, KC_NO, K63, K64, K65, KC_NO, K67, K68 }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, K74, K75, KC_NO, K77, K78 }, \
+ { KC_NO, KC_NO, K82, K83, K84, K85, KC_NO, K87, K88 }, \
+ { KC_NO, KC_NO, K92, KC_NO, K94, K95, K96, K97, K98 }, \
+ { KC_NO, KC_NO, KA2, KA3, KA4, KA5, KA6, KA7, KC_NO }, \
+}
+
+// generated by KBFirmware JSON to QMK Parser
+// https://noroadsleft.github.io/kbf_qmk_converter/
diff --git a/keyboards/id80/info.json b/keyboards/id80/info.json
new file mode 100644
index 000000000..986d967a1
--- /dev/null
+++ b/keyboards/id80/info.json
@@ -0,0 +1,13 @@
+{
+ "keyboard_name": "ID80",
+ "url": "",
+ "maintainer": "qmk",
+ "width": 16.25,
+ "height": 6.5,
+ "layouts": {
+ "LAYOUT": {
+ "key_count": 80,
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"F1", "x":1.25, "y":0}, {"label":"F2", "x":2.25, "y":0}, {"label":"F3", "x":3.25, "y":0}, {"label":"F4", "x":4.25, "y":0}, {"label":"F5", "x":5.5, "y":0}, {"label":"F6", "x":6.5, "y":0}, {"label":"F7", "x":7.5, "y":0}, {"label":"F8", "x":8.5, "y":0}, {"label":"F9", "x":9.75, "y":0}, {"label":"F10", "x":10.75, "y":0}, {"label":"F11", "x":11.75, "y":0}, {"label":"F12", "x":12.75, "y":0}, {"label":"Fn", "x":14, "y":0}, {"label":"Insert", "x":15.25, "y":0}, {"label":"`", "x":0, "y":1.25}, {"label":"1", "x":1, "y":1.25}, {"label":"2", "x":2, "y":1.25}, {"label":"3", "x":3, "y":1.25}, {"label":"4", "x":4, "y":1.25}, {"label":"5", "x":5, "y":1.25}, {"label":"6", "x":6, "y":1.25}, {"label":"7", "x":7, "y":1.25}, {"label":"8", "x":8, "y":1.25}, {"label":"9", "x":9, "y":1.25}, {"label":"0", "x":10, "y":1.25}, {"label":"-", "x":11, "y":1.25}, {"label":"=", "x":12, "y":1.25}, {"label":"Backspace", "x":13, "y":1.25, "w":2}, {"label":"Home", "x":15.25, "y":1.25}, {"label":"Tab", "x":0, "y":2.25, "w":1.5}, {"label":"Q", "x":1.5, "y":2.25}, {"label":"W", "x":2.5, "y":2.25}, {"label":"E", "x":3.5, "y":2.25}, {"label":"R", "x":4.5, "y":2.25}, {"label":"T", "x":5.5, "y":2.25}, {"label":"Y", "x":6.5, "y":2.25}, {"label":"U", "x":7.5, "y":2.25}, {"label":"I", "x":8.5, "y":2.25}, {"label":"O", "x":9.5, "y":2.25}, {"label":"P", "x":10.5, "y":2.25}, {"label":"[", "x":11.5, "y":2.25}, {"label":"]", "x":12.5, "y":2.25}, {"label":"\\", "x":13.5, "y":2.25, "w":1.5}, {"label":"Delete", "x":15.25, "y":2.25}, {"label":"Caps Lock", "x":0, "y":3.25, "w":1.75}, {"label":"A", "x":1.75, "y":3.25}, {"label":"S", "x":2.75, "y":3.25}, {"label":"D", "x":3.75, "y":3.25}, {"label":"F", "x":4.75, "y":3.25}, {"label":"G", "x":5.75, "y":3.25}, {"label":"H", "x":6.75, "y":3.25}, {"label":"J", "x":7.75, "y":3.25}, {"label":"K", "x":8.75, "y":3.25}, {"label":"L", "x":9.75, "y":3.25}, {"label":";", "x":10.75, "y":3.25}, {"label":"'", "x":11.75, "y":3.25}, {"label":"Enter", "x":12.75, "y":3.25, "w":2.25}, {"label":"Shift", "x":0, "y":4.25, "w":2.25}, {"label":"Z", "x":2.25, "y":4.25}, {"label":"X", "x":3.25, "y":4.25}, {"label":"C", "x":4.25, "y":4.25}, {"label":"V", "x":5.25, "y":4.25}, {"label":"B", "x":6.25, "y":4.25}, {"label":"N", "x":7.25, "y":4.25}, {"label":"M", "x":8.25, "y":4.25}, {"label":",", "x":9.25, "y":4.25}, {"label":".", "x":10.25, "y":4.25}, {"label":"/", "x":11.25, "y":4.25}, {"label":"Shift", "x":12.25, "y":4.25, "w":1.75}, {"label":"\u2191", "x":14.25, "y":4.5}, {"label":"Ctrl", "x":0, "y":5.25, "w":1.25}, {"label":"Win", "x":1.25, "y":5.25, "w":1.25}, {"label":"Alt", "x":2.5, "y":5.25, "w":1.25}, {"x":3.75, "y":5.25, "w":6.25}, {"label":"Alt", "x":10, "y":5.25, "w":1.5}, {"label":"Ctrl", "x":11.5, "y":5.25, "w":1.5}, {"label":"\u2190", "x":13.25, "y":5.5}, {"label":"\u2193", "x":14.25, "y":5.5}, {"label":"\u2192", "x":15.25, "y":5.5}]
+ }
+ }
+}
diff --git a/keyboards/id80/keymaps/default/keymap.c b/keyboards/id80/keymaps/default/keymap.c
new file mode 100644
index 000000000..696fb303e
--- /dev/null
+++ b/keyboards/id80/keymaps/default/keymap.c
@@ -0,0 +1,35 @@
+/* Copyright 2020 Sergey Vlasov <sigprof@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 QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ 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, MO(1), KC_INS,
+ 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_HOME,
+ 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_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_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_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+ [1] = LAYOUT(
+ RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, BL_DEC, BL_TOGG, BL_INC, NK_TOGG, _______, _______, _______, _______, _______, BL_INC,
+ _______, _______, _______, _______, _______, _______, BL_TOGG, BL_DEC, BL_STEP
+ ),
+};
diff --git a/keyboards/id80/keymaps/default/readme.md b/keyboards/id80/keymaps/default/readme.md
new file mode 100644
index 000000000..8ae9f656c
--- /dev/null
+++ b/keyboards/id80/keymaps/default/readme.md
@@ -0,0 +1 @@
+# The default keymap for id80
diff --git a/keyboards/id80/readme.md b/keyboards/id80/readme.md
new file mode 100644
index 000000000..3d2b934c3
--- /dev/null
+++ b/keyboards/id80/readme.md
@@ -0,0 +1,15 @@
+# IDOBAO ID80
+
+![ID80](https://ae01.alicdn.com/kf/H0f617c6129c24cfaa26a8c9e8e54851aj.jpg)
+
+A 75% hotswap keyboard from IDOBAO.
+
+* Keyboard Maintainer: [Sergey Vlasov](https://github.com/sigprof)
+* Hardware Supported: IDOBAO ID80
+* Hardware Availability: [AliExpress](https://www.aliexpress.com/item/4000590804514.html), [Drop](https://drop.com/buy/idobao-id80-75-hot-swappable-mechanical-keyboard-kit?mode=guest_open)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make id80:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/id80/rules.mk b/keyboards/id80/rules.mk
new file mode 100644
index 000000000..37aa91156
--- /dev/null
+++ b/keyboards/id80/rules.mk
@@ -0,0 +1,36 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = atmel-dfu
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = no # 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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+
+# partially generated by KBFirmware JSON to QMK Parser
+# https://noroadsleft.github.io/kbf_qmk_converter/
diff --git a/keyboards/jisplit89/info.json b/keyboards/jisplit89/info.json
index 5d029f6c2..9e4f176aa 100644
--- a/keyboards/jisplit89/info.json
+++ b/keyboards/jisplit89/info.json
@@ -51,6 +51,7 @@
{"label":"P", "x":11.5, "y":2.25},
{"label":"`", "x":12.5, "y":2.25},
{"label":"{", "x":13.5, "y":2.25},
+ {"label":"Return", "x":14.75, "y":2.25, "w":1.25, "h":2},
{"label":"Home", "x":16, "y":2.25},
{"label":"Caps", "x":0, "y":3.25, "w":1.75},
{"label":"A", "x":1.75, "y":3.25},
@@ -65,7 +66,6 @@
{"label":"+", "x":11.75, "y":3.25},
{"label":"*", "x":12.75, "y":3.25},
{"label":"}", "x":13.75, "y":3.25},
- {"label":"Return", "x":14.75, "y":2.25, "w":1.25, "h":2},
{"label":"End", "x":16, "y":3.25},
{"label":"Shift", "x":0, "y":4.25, "w":2},
{"label":"Z", "x":2, "y":4.25},
diff --git a/keyboards/kbdfans/kbd67/mkiirgb/v2/config.h b/keyboards/kbdfans/kbd67/mkiirgb/v2/config.h
index f1be48510..afe5e51a2 100644
--- a/keyboards/kbdfans/kbd67/mkiirgb/v2/config.h
+++ b/keyboards/kbdfans/kbd67/mkiirgb/v2/config.h
@@ -19,6 +19,7 @@
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED true // turn off effects when suspended
#define RGB_MATRIX_KEYPRESSES
+#define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_ALL
#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#define DISABLE_RGB_MATRIX_BAND_SAT
#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
@@ -35,10 +36,9 @@
#define DISABLE_RGB_MATRIX_SOLID_SPLASH
#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#define DISABLE_RGB_MATRIX_DIGITAL_RAIN
-#define DISABLE_RGB_MATRIX_CYCLE_ALL
#define DISABLE_RGB_MATRIX_RAINDROPS
#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
-#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 160
+#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 255
#define DRIVER_ADDR_1 0b1110100
#define DRIVER_ADDR_2 0b1110111
#define DRIVER_COUNT 2
diff --git a/keyboards/kbdfans/kbd67/rev1/keymaps/default/keymap.c b/keyboards/kbdfans/kbd67/rev1/keymaps/default/keymap.c
index 13a8a420d..9e0065ff2 100644
--- a/keyboards/kbdfans/kbd67/rev1/keymaps/default/keymap.c
+++ b/keyboards/kbdfans/kbd67/rev1/keymaps/default/keymap.c
@@ -28,7 +28,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |----------------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |PgUp|
* |----------------------------------------------------------------|
- * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '|Return |PgDn|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |PgDn|
* |----------------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | Up|End |
* |----------------------------------------------------------------|
@@ -38,7 +38,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_65_ansi(
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_BSPC, KC_HOME, \
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_PGUP, \
- 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_PGDN, \
+ 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_PGDN, \
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_END, \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
@@ -46,7 +46,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* ,----------------------------------------------------------------.
* |~ `|F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del |Ins |
* |----------------------------------------------------------------|
- * |Caps | |Up | | | | | |PSc|SLk|Pau|Up | | | |
+ * | | |Up | | | | | |PSc|SLk|Pau|Up | | | |
* |----------------------------------------------------------------|
* | |Lef|Dow|Rig| | | | |Hom|PUp|Lef|Rig| | |
* |----------------------------------------------------------------|
@@ -57,7 +57,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[1] = LAYOUT_65_ansi(
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_DEL,KC_INS, \
- KC_CAPS,_______, KC_UP,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK,KC_PAUS, KC_UP,_______, _______,_______, \
+ _______,_______, KC_UP,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK,KC_PAUS, KC_UP,_______, _______,_______, \
_______,KC_LEFT,KC_DOWN,KC_RGHT,_______,_______,_______,_______,KC_HOME,KC_PGUP,KC_LEFT,KC_RGHT, _______,_______, \
_______,_______,_______,_______,_______,_______,_______,_______, KC_END,KC_PGDN,KC_DOWN, _______,KC_PGUP,_______, \
_______, _______, _______, _______, _______,_______,_______,KC_HOME,KC_PGDN, KC_END),
diff --git a/keyboards/kbdfans/kbd67/rev2/config.h b/keyboards/kbdfans/kbd67/rev2/config.h
index 931f5714b..4e1352c41 100644
--- a/keyboards/kbdfans/kbd67/rev2/config.h
+++ b/keyboards/kbdfans/kbd67/rev2/config.h
@@ -20,9 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x6060
-#define DEVICE_VER 0x0001
+#define VENDOR_ID 0x4B42
+#define PRODUCT_ID 0x6067
+#define DEVICE_VER 0x0002
#define MANUFACTURER KBDFans
#define PRODUCT KBD67v2
#define DESCRIPTION 65% Keyboard
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/default/keymap.c b/keyboards/kbdfans/kbd67/rev2/keymaps/default/keymap.c
index 13a8a420d..9e0065ff2 100644
--- a/keyboards/kbdfans/kbd67/rev2/keymaps/default/keymap.c
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/default/keymap.c
@@ -28,7 +28,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |----------------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |PgUp|
* |----------------------------------------------------------------|
- * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '|Return |PgDn|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |PgDn|
* |----------------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | Up|End |
* |----------------------------------------------------------------|
@@ -38,7 +38,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_65_ansi(
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_BSPC, KC_HOME, \
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_PGUP, \
- 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_PGDN, \
+ 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_PGDN, \
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_END, \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
@@ -46,7 +46,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* ,----------------------------------------------------------------.
* |~ `|F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del |Ins |
* |----------------------------------------------------------------|
- * |Caps | |Up | | | | | |PSc|SLk|Pau|Up | | | |
+ * | | |Up | | | | | |PSc|SLk|Pau|Up | | | |
* |----------------------------------------------------------------|
* | |Lef|Dow|Rig| | | | |Hom|PUp|Lef|Rig| | |
* |----------------------------------------------------------------|
@@ -57,7 +57,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[1] = LAYOUT_65_ansi(
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_DEL,KC_INS, \
- KC_CAPS,_______, KC_UP,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK,KC_PAUS, KC_UP,_______, _______,_______, \
+ _______,_______, KC_UP,_______,_______,_______,_______,_______,KC_PSCR,KC_SLCK,KC_PAUS, KC_UP,_______, _______,_______, \
_______,KC_LEFT,KC_DOWN,KC_RGHT,_______,_______,_______,_______,KC_HOME,KC_PGUP,KC_LEFT,KC_RGHT, _______,_______, \
_______,_______,_______,_______,_______,_______,_______,_______, KC_END,KC_PGDN,KC_DOWN, _______,KC_PGUP,_______, \
_______, _______, _______, _______, _______,_______,_______,KC_HOME,KC_PGDN, KC_END),
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/keymap.c b/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/keymap.c
new file mode 100644
index 000000000..625b768e6
--- /dev/null
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/keymap.c
@@ -0,0 +1,58 @@
+/* Copyright 2018 jscatena88
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap (Base Layer) Default Layer
+ * ,----------------------------------------------------------------.
+ * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp | `~ |
+ * |----------------------------------------------------------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |Del |
+ * |----------------------------------------------------------------|
+ * |Ctrl | A| S| D| F| G| H| J| K| L| ;| '|Return |PgUp|
+ * |----------------------------------------------------------------|
+ * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | Up|PgDn|
+ * |----------------------------------------------------------------|
+ * |Ctrl|Win |Alt | Space |Alt| FN|Ctrl|Lef|Dow|Rig |
+ * `----------------------------------------------------------------'
+ */
+[0] = LAYOUT_65_ansi(
+ 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_BSPC, 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_BSLS, KC_DEL,
+ 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_PGUP,
+ 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_PGDN,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ /* Keymap Fn Layer
+ * ,----------------------------------------------------------------.
+ * |~ `|F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del |Ins |
+ * |----------------------------------------------------------------|
+ * |Caps | |Up | | | | | |PSc|SLk|Pau|Up | | | |
+ * |----------------------------------------------------------------|
+ * | |Lef|Dow|Rig| | | | |Hom|PUp|Lef|Rig| | |
+ * |----------------------------------------------------------------|
+ * | | | | | | | | |End|PDn|Dow| |PUp| |
+ * |----------------------------------------------------------------|
+ * | | | | | | | |Hom|PDn|End |
+ * `----------------------------------------------------------------'
+ */
+
+[1] = LAYOUT_65_ansi(
+ 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_VOLU,
+ KC_CAPS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS, KC_VOLD,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, KC_MUTE,
+ KC_TRNS, RGB_TOG, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_PGUP, KC_MPLY,
+ LCTL(KC_LALT), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_END),
+};
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/readme.md b/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/readme.md
new file mode 100644
index 000000000..21b28de90
--- /dev/null
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/jscatena88/readme.md
@@ -0,0 +1,4 @@
+# Jscatena88's KBD67 Layout
+![Layout Visual](https://i.imgur.com/7IsPDjR.png)
+
+This modifies the far right column on layer 1, adds RGB control to the second layer, and creates a CTRL+ALT button on the second layer for switching between Linux TTYs (this is the key labelled LCTL(LC_L), it is actually LCTL(KC_LALT) but the visualization software didn't support that) \ No newline at end of file
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/via/config.h b/keyboards/kbdfans/kbd67/rev2/keymaps/via/config.h
new file mode 100644
index 000000000..579212d4a
--- /dev/null
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/via/config.h
@@ -0,0 +1 @@
+#define DYNAMIC_KEYMAP_LAYER_COUNT 2
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/via/keymap.c b/keyboards/kbdfans/kbd67/rev2/keymaps/via/keymap.c
new file mode 100644
index 000000000..e2f3a664b
--- /dev/null
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/via/keymap.c
@@ -0,0 +1,45 @@
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap (Base Layer) Default Layer
+ * ,----------------------------------------------------------------.
+ * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |Home|
+ * |----------------------------------------------------------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |PgUp|
+ * |----------------------------------------------------------------|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |PgDn|
+ * |----------------------------------------------------------------|
+ * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | Up|End |
+ * |----------------------------------------------------------------|
+ * |Ctrl|Win |Alt | Space |Alt| FN|Ctrl|Lef|Dow|Rig |
+ * `----------------------------------------------------------------'
+ */
+[0] = LAYOUT_65_ansi(
+ 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_BSPC, KC_HOME,
+ 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_PGUP,
+ 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_PGDN,
+ 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_END,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+),
+
+ /* Keymap Fn Layer
+ * ,----------------------------------------------------------------.
+ * |~ `|F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del |Ins |
+ * |----------------------------------------------------------------|
+ * | | |Up | | | | | |PSc|SLk|Pau|Up | | | |
+ * |----------------------------------------------------------------|
+ * | |Lef|Dow|Rig| | | | |Hom|PUp|Lef|Rig| | |
+ * |----------------------------------------------------------------|
+ * | | | | | | | | |End|PDn|Dow| |PUp| |
+ * |----------------------------------------------------------------|
+ * | | | | | | | |Hom|PDn|End |
+ * `----------------------------------------------------------------'
+ */
+[1] = LAYOUT_65_ansi(
+ 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_DEL, KC_INS,
+ _______, _______, KC_UP, _______, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, _______, _______, _______,
+ _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_END, KC_PGDN, KC_DOWN, _______, KC_PGUP, _______,
+ _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+)
+};
diff --git a/keyboards/kbdfans/kbd67/rev2/keymaps/via/rules.mk b/keyboards/kbdfans/kbd67/rev2/keymaps/via/rules.mk
new file mode 100644
index 000000000..36b7ba9cb
--- /dev/null
+++ b/keyboards/kbdfans/kbd67/rev2/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
diff --git a/keyboards/kbdfans/kbd6x/config.h b/keyboards/kbdfans/kbd6x/config.h
index 61d086fbd..32a625f71 100644
--- a/keyboards/kbdfans/kbd6x/config.h
+++ b/keyboards/kbdfans/kbd6x/config.h
@@ -20,12 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x0000
+#define VENDOR_ID 0x4B42
+#define PRODUCT_ID 0x3658
#define DEVICE_VER 0x0001
#define MANUFACTURER You
#define PRODUCT kbd6x
-#define DESCRIPTION A custom keyboard
+#define DESCRIPTION Dual USB-C Tsangan Hot Swap PCB
/* key matrix size */
#define MATRIX_ROWS 5
diff --git a/keyboards/kbdfans/kbd6x/keymaps/konstantin/keymap.c b/keyboards/kbdfans/kbd6x/keymaps/konstantin/keymap.c
index d00232205..46cc0a113 100644
--- a/keyboards/kbdfans/kbd6x/keymaps/konstantin/keymap.c
+++ b/keyboards/kbdfans/kbd6x/keymaps/konstantin/keymap.c
@@ -14,8 +14,23 @@ void eeconfig_init_keymap(void) {
rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
}
+bool indicator_light = false;
+
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
+ case RGB_TOG ... RGB_SPD:
+ // Disable RGB controls when Fn/Caps indicator lights are on
+ if (indicator_light) {
+ return false;
+ }
+ // Shift+Toggle = reset RGB
+ if (record->event.pressed && keycode == RGB_TOG && get_mods() & MOD_MASK_SHIFT) {
+ eeconfig_init_keymap();
+ return false;
+ }
+ break;
+
+ // Combined RCtrl and layer
case RCTRL:
if (record->event.pressed) {
register_code(KC_RCTRL);
@@ -33,17 +48,20 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
static inline void fn_light(void) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
rgblight_sethsv_noeeprom(modern_dolch_red.h, modern_dolch_red.s, rgblight_get_val());
+ indicator_light = true;
}
static inline void caps_light(void) {
rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
rgblight_sethsv_noeeprom(modern_dolch_cyan.h, modern_dolch_cyan.s, rgblight_get_val());
+ indicator_light = true;
}
static inline void restore_light(void) {
rgblight_config_t saved = { .raw = eeconfig_read_rgblight() };
rgblight_sethsv_noeeprom(saved.hue, saved.sat, saved.val);
rgblight_mode_noeeprom(saved.mode);
+ indicator_light = false;
}
static void check_light_layer(uint32_t state) {
diff --git a/keyboards/kbdfans/kbd6x/keymaps/konstantin/rules.mk b/keyboards/kbdfans/kbd6x/keymaps/konstantin/rules.mk
index 64428383c..c75488af6 100644
--- a/keyboards/kbdfans/kbd6x/keymaps/konstantin/rules.mk
+++ b/keyboards/kbdfans/kbd6x/keymaps/konstantin/rules.mk
@@ -3,6 +3,7 @@ BOOTMAGIC_ENABLE = no
COMMAND_ENABLE = yes
CONSOLE_ENABLE = no
EXTRAKEY_ENABLE = yes
+GRAVE_ESC_ENABLE = no
MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
RGBLIGHT_ENABLE = yes
diff --git a/keyboards/kbdfans/kbd6x/keymaps/via/keymap.c b/keyboards/kbdfans/kbd6x/keymaps/via/keymap.c
new file mode 100644
index 000000000..07883b0a5
--- /dev/null
+++ b/keyboards/kbdfans/kbd6x/keymaps/via/keymap.c
@@ -0,0 +1,50 @@
+/* Copyright 2020 mixedfeelings
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ 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_DEL,
+ 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_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(1),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_RALT, KC_RGUI, KC_RCTL
+ ),
+
+ [1] = LAYOUT(
+ 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_INS, KC_GRV,
+ KC_TRNS, 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_EJCT, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RIGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDOWN, KC_DOWN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, MO(2), KC_STOP, KC_TRNS, KC_TRNS
+ ),
+
+ [2] = LAYOUT(
+ 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, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_TOGG, BL_INC, BL_STEP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+
+ [3] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+};
diff --git a/keyboards/kbdfans/kbd6x/keymaps/via/readme.md b/keyboards/kbdfans/kbd6x/keymaps/via/readme.md
new file mode 100644
index 000000000..9e125443e
--- /dev/null
+++ b/keyboards/kbdfans/kbd6x/keymaps/via/readme.md
@@ -0,0 +1,7 @@
+# VIA keymap for KBDFans KBD6x.
+
+Predefined Layers:
+- 0 - Default KBD6x keymap
+- 1 - A modified version of the classic HHKB function layer
+- 2 - Lighting control and RESET
+- 3 - Blank \ No newline at end of file
diff --git a/keyboards/kbdfans/kbd6x/keymaps/via/rules.mk b/keyboards/kbdfans/kbd6x/keymaps/via/rules.mk
new file mode 100644
index 000000000..36b7ba9cb
--- /dev/null
+++ b/keyboards/kbdfans/kbd6x/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
diff --git a/keyboards/kbdfans/kbd8x_mk2/readme.md b/keyboards/kbdfans/kbd8x_mk2/readme.md
index 3655ac1c7..fbd650460 100644
--- a/keyboards/kbdfans/kbd8x_mk2/readme.md
+++ b/keyboards/kbdfans/kbd8x_mk2/readme.md
@@ -6,7 +6,7 @@ A fairly typical TKL
Keyboard Maintainer: [ai03](https://github.com/ai03-2725) / [KBDfans](https://kbdfans.cn/)
Hardware Supported: KBD8X MKII PCB/case
-Hardware Availability: [KBDfans](https://kbdfans.cn/collections/new-arrival/products/coming-soon-kbd8x-mkii-custom-mechanical-keyboard-kit)
+Hardware Availability: [KBDfans](https://kbdfans.com/collections/90-kbd19x/products/gb-kbd8x-mkii-pcb)
Make example for this keyboard (after setting up your build environment):
diff --git a/keyboards/kc60/config.h b/keyboards/kc60/config.h
index 7e9cdaa08..7c6e695a4 100644
--- a/keyboards/kc60/config.h
+++ b/keyboards/kc60/config.h
@@ -15,18 +15,17 @@ 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
+#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x6060
+#define VENDOR_ID 0x530A
+#define PRODUCT_ID 0x6FFC
#define DEVICE_VER 0x0001
-#define MANUFACTURER You
-#define PRODUCT kc60v2
-#define DESCRIPTION A custom keyboard
+#define MANUFACTURER NPKC
+#define PRODUCT KC60
+#define DESCRIPTION QMK Firmware: KC60
/* key matrix size */
#define MATRIX_ROWS 5
@@ -41,19 +40,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
-*/
-
-// Possible pins for columns include: F1 F0 E6 D7 D6 D4 C7 C6 B7 B5 B4 B3 B1 B0
-// Pins for rows include: D0 D1 F6 F7 D5
-// KC60 Version 2
+ */
#define MATRIX_ROW_PINS { D0, D1, F6, F7, D5 }
#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B7, D4, B1, B0, B5, B4, D7, D6, B3 }
#define UNUSED_PINS
+/* COL2ROW, ROW2COL*/
+#define DIODE_DIRECTION COL2ROW
+
#define BACKLIGHT_PIN B6
+#define BACKLIGHT_BREATHING
+#define BACKLIGHT_LEVELS 5
-/* COL2ROW or ROW2COL */
-#define DIODE_DIRECTION COL2ROW
+#ifdef RGBLIGHT_ENABLE
+# define RGB_DI_PIN F5
+# define RGBLED_NUM 16 // Number of LEDs. Change this to match your use case.
+# define RGBLIGHT_HUE_STEP 8
+# define RGBLIGHT_SAT_STEP 8
+# define RGBLIGHT_VAL_STEP 8
+# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
+# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+/*== all animations enable ==*/
+# define RGBLIGHT_ANIMATIONS
+/*== or choose animations ==*/
+// # define RGBLIGHT_EFFECT_BREATHING
+// # define RGBLIGHT_EFFECT_RAINBOW_MOOD
+// # define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+// # define RGBLIGHT_EFFECT_SNAKE
+// # define RGBLIGHT_EFFECT_KNIGHT
+// # define RGBLIGHT_EFFECT_CHRISTMAS
+// # define RGBLIGHT_EFFECT_STATIC_GRADIENT
+// # define RGBLIGHT_EFFECT_RGB_TEST
+// # define RGBLIGHT_EFFECT_ALTERNATING
+/*== customize breathing effect ==*/
+/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
+# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
+/*==== use exp() and sin() ====*/
+// # define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
+// # define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
+#endif
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 5
@@ -61,99 +86,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
-/* number of backlight levels */
-#define BACKLIGHT_LEVELS 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
-/*
- * 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.
- *
- */
-
-/* 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
diff --git a/keyboards/kc60/info.json b/keyboards/kc60/info.json
index adc3355eb..bd21b6a6c 100644
--- a/keyboards/kc60/info.json
+++ b/keyboards/kc60/info.json
@@ -1,16 +1,212 @@
{
- "keyboard_name": "KC60",
- "url": "",
- "maintainer": "qmk",
- "width": 15,
- "height": 5,
- "layouts": {
- "LAYOUT": {
- "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"x":12.75, "y":2}, {"label":"Enter", "x":13.75, "y":2, "w":1.25}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"x":14, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":5}, {"x":8.75, "y":4, "w":1.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
- },
-
- "LAYOUT_60_ansi": {
- "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
- }
- }
+ "keyboard_name": "KC60",
+ "url": "",
+ "maintainer": "qmk",
+ "width": 15,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_all": {
+ "layout": [
+ {"label":"Esc", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":7, "y":0},
+ {"label":"8", "x":8, "y":0},
+ {"label":"9", "x":9, "y":0},
+ {"label":"0", "x":10, "y":0},
+ {"label":"-", "x":11, "y":0},
+ {"label":"=", "x":12, "y":0},
+ {"label":"Backspace", "x":13, "y":0},
+ {"label":"`", "x":14, "y":0},
+ {"label":"Tab", "x":0, "y":1, "w":1.5},
+ {"label":"Q", "x":1.5, "y":1},
+ {"label":"W", "x":2.5, "y":1},
+ {"label":"E", "x":3.5, "y":1},
+ {"label":"R", "x":4.5, "y":1},
+ {"label":"T", "x":5.5, "y":1},
+ {"label":"Y", "x":6.5, "y":1},
+ {"label":"U", "x":7.5, "y":1},
+ {"label":"I", "x":8.5, "y":1},
+ {"label":"O", "x":9.5, "y":1},
+ {"label":"P", "x":10.5, "y":1},
+ {"label":"[", "x":11.5, "y":1},
+ {"label":"]", "x":12.5, "y":1},
+ {"label":"\\", "x":13.5, "y":1, "w":1.5},
+ {"label":"CapsLock", "x":0, "y":2, "w":1.75},
+ {"label":"A", "x":1.75, "y":2},
+ {"label":"S", "x":2.75, "y":2},
+ {"label":"D", "x":3.75, "y":2},
+ {"label":"F", "x":4.75, "y":2},
+ {"label":"G", "x":5.75, "y":2},
+ {"label":"H", "x":6.75, "y":2},
+ {"label":"J", "x":7.75, "y":2},
+ {"label":"K", "x":8.75, "y":2},
+ {"label":"L", "x":9.75, "y":2},
+ {"label":";", "x":10.75, "y":2},
+ {"label":"'", "x":11.75, "y":2},
+ {"label":"ISO#", "x":12.75, "y":2},
+ {"label":"Enter", "x":13.75, "y":2, "w":1.25},
+ {"label":"Shift", "x":0, "y":3, "w":1.25},
+ {"label":"ISO\\", "x":1.25, "y":3},
+ {"label":"Z", "x":2.25, "y":3},
+ {"label":"X", "x":3.25, "y":3},
+ {"label":"C", "x":4.25, "y":3},
+ {"label":"V", "x":5.25, "y":3},
+ {"label":"B", "x":6.25, "y":3},
+ {"label":"N", "x":7.25, "y":3},
+ {"label":"M", "x":8.25, "y":3},
+ {"label":",", "x":9.25, "y":3},
+ {"label":".", "x":10.25, "y":3},
+ {"label":"/", "x":11.25, "y":3},
+ {"label":"Shift", "x":12.25, "y":3, "w":1.75},
+ {"label":"HHKBFn", "x":14, "y":3},
+ {"label":"Ctrl", "x":0, "y":4, "w":1.25},
+ {"label":"GUI", "x":1.25, "y":4, "w":1.25},
+ {"label":"Alt", "x":2.5, "y":4, "w":1.25},
+ {"label":"Space", "x":3.75, "y":4, "w":6.25},
+ {"label":"Alt", "x":10, "y":4, "w":1.25},
+ {"label":"GUI", "x":11.25, "y":4, "w":1.25},
+ {"label":"Menu", "x":12.5, "y":4, "w":1.25},
+ {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}
+ ]
+ },
+ "LAYOUT": {
+ "layout": [
+ {"label":"K00", "x":0, "y":0},
+ {"label":"K01", "x":1, "y":0},
+ {"label":"K02", "x":2, "y":0},
+ {"label":"K03", "x":3, "y":0},
+ {"label":"K04", "x":4, "y":0},
+ {"label":"K05", "x":5, "y":0},
+ {"label":"K06", "x":6, "y":0},
+ {"label":"K07", "x":7, "y":0},
+ {"label":"K08", "x":8, "y":0},
+ {"label":"K09", "x":9, "y":0},
+ {"label":"K0A", "x":10, "y":0},
+ {"label":"K0B", "x":11, "y":0},
+ {"label":"K0C", "x":12, "y":0},
+ {"label":"K0D", "x":13, "y":0},
+ {"label":"K10", "x":0, "y":1, "w":1.5},
+ {"label":"K11", "x":1.5, "y":1},
+ {"label":"K12", "x":2.5, "y":1},
+ {"label":"K13", "x":3.5, "y":1},
+ {"label":"K14", "x":4.5, "y":1},
+ {"label":"K15", "x":5.5, "y":1},
+ {"label":"K16", "x":6.5, "y":1},
+ {"label":"K17", "x":7.5, "y":1},
+ {"label":"K18", "x":8.5, "y":1},
+ {"label":"K19", "x":9.5, "y":1},
+ {"label":"K1A", "x":10.5, "y":1},
+ {"label":"K1B", "x":11.5, "y":1},
+ {"label":"K1C", "x":12.5, "y":1},
+ {"label":"K1D", "x":13.5, "y":1, "w":1.5},
+ {"label":"K20", "x":0, "y":2, "w":1.75},
+ {"label":"K21", "x":1.75, "y":2},
+ {"label":"K22", "x":2.75, "y":2},
+ {"label":"K23", "x":3.75, "y":2},
+ {"label":"K24", "x":4.75, "y":2},
+ {"label":"K25", "x":5.75, "y":2},
+ {"label":"K26", "x":6.75, "y":2},
+ {"label":"K27", "x":7.75, "y":2},
+ {"label":"K28", "x":8.75, "y":2},
+ {"label":"K29", "x":9.75, "y":2},
+ {"label":"K2A", "x":10.75, "y":2},
+ {"label":"K2B", "x":11.75, "y":2},
+ {"label":"K2C", "x":12.75, "y":2},
+ {"label":"K2D", "x":13.75, "y":2, "w":1.25},
+ {"label":"K30", "x":0, "y":3, "w":1.25},
+ {"label":"K31", "x":1.25, "y":3},
+ {"label":"K32", "x":2.25, "y":3},
+ {"label":"K33", "x":3.25, "y":3},
+ {"label":"K34", "x":4.25, "y":3},
+ {"label":"K35", "x":5.25, "y":3},
+ {"label":"K36", "x":6.25, "y":3},
+ {"label":"K37", "x":7.25, "y":3},
+ {"label":"K38", "x":8.25, "y":3},
+ {"label":"K39", "x":9.25, "y":3},
+ {"label":"K3A", "x":10.25, "y":3},
+ {"label":"K3B", "x":11.25, "y":3},
+ {"label":"K3C", "x":12.25, "y":3, "w":1.75},
+ {"label":"K3D", "x":14, "y":3},
+ {"label":"K40", "x":0, "y":4, "w":1.25},
+ {"label":"K41", "x":1.25, "y":4, "w":1.25},
+ {"label":"K42", "x":2.5, "y":4, "w":1.25},
+ {"label":"K45", "x":3.75, "y":4, "w":6.25},
+ {"label":"K49", "x":14, "y":0},
+ {"label":"K4A", "x":10, "y":4, "w":1.25},
+ {"label":"K4B", "x":11.25, "y":4, "w":1.25},
+ {"label":"K4C", "x":12.5, "y":4, "w":1.25},
+ {"label":"K4D", "x":13.75, "y":4, "w":1.25}
+ ]
+ },
+ "LAYOUT_60_ansi": {
+ "layout": [
+ {"label":"~", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":7, "y":0},
+ {"label":"8", "x":8, "y":0},
+ {"label":"9", "x":9, "y":0},
+ {"label":"0", "x":10, "y":0},
+ {"label":"-", "x":11, "y":0},
+ {"label":"=", "x":12, "y":0},
+ {"label":"Backspace", "x":13, "y":0, "w":2},
+ {"label":"Tab", "x":0, "y":1, "w":1.5},
+ {"label":"Q", "x":1.5, "y":1},
+ {"label":"W", "x":2.5, "y":1},
+ {"label":"E", "x":3.5, "y":1},
+ {"label":"R", "x":4.5, "y":1},
+ {"label":"T", "x":5.5, "y":1},
+ {"label":"Y", "x":6.5, "y":1},
+ {"label":"U", "x":7.5, "y":1},
+ {"label":"I", "x":8.5, "y":1},
+ {"label":"O", "x":9.5, "y":1},
+ {"label":"P", "x":10.5, "y":1},
+ {"label":"[", "x":11.5, "y":1},
+ {"label":"]", "x":12.5, "y":1},
+ {"label":"\\", "x":13.5, "y":1, "w":1.5},
+ {"label":"CapsLock", "x":0, "y":2, "w":1.75},
+ {"label":"A", "x":1.75, "y":2},
+ {"label":"S", "x":2.75, "y":2},
+ {"label":"D", "x":3.75, "y":2},
+ {"label":"F", "x":4.75, "y":2},
+ {"label":"G", "x":5.75, "y":2},
+ {"label":"H", "x":6.75, "y":2},
+ {"label":"J", "x":7.75, "y":2},
+ {"label":"K", "x":8.75, "y":2},
+ {"label":"L", "x":9.75, "y":2},
+ {"label":";", "x":10.75, "y":2},
+ {"label":"'", "x":11.75, "y":2},
+ {"label":"Enter", "x":12.75, "y":2, "w":2.25},
+ {"label":"Shift", "x":0, "y":3, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3},
+ {"label":"X", "x":3.25, "y":3},
+ {"label":"C", "x":4.25, "y":3},
+ {"label":"V", "x":5.25, "y":3},
+ {"label":"B", "x":6.25, "y":3},
+ {"label":"N", "x":7.25, "y":3},
+ {"label":"M", "x":8.25, "y":3},
+ {"label":",", "x":9.25, "y":3},
+ {"label":".", "x":10.25, "y":3},
+ {"label":"/", "x":11.25, "y":3},
+ {"label":"Shift", "x":12.25, "y":3, "w":2.75},
+ {"label":"Ctrl", "x":0, "y":4, "w":1.25},
+ {"label":"Win", "x":1.25, "y":4, "w":1.25},
+ {"label":"Alt", "x":2.5, "y":4, "w":1.25},
+ {"label":"Space", "x":3.75, "y":4, "w":6.25},
+ {"label":"Alt", "x":10, "y":4, "w":1.25},
+ {"label":"Win", "x":11.25, "y":4, "w":1.25},
+ {"label":"Menu", "x":12.5, "y":4, "w":1.25},
+ {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}
+ ]
+ }
+ }
}
diff --git a/keyboards/kc60/kc60.h b/keyboards/kc60/kc60.h
index b8e16c0b3..2f26b2c0e 100644
--- a/keyboards/kc60/kc60.h
+++ b/keyboards/kc60/kc60.h
@@ -1,25 +1,53 @@
-#ifndef KC60_H
-#define KC60_H
+#pragma once
#include "quantum.h"
-// K49 key is for the key at row 1 and column 15 when you split the backspace in 2 1U key.
+/* LAYOUT_all
+ * ,-----------------------------------------------------------.
+ * |00 |01 |02 |03 |04 |05 |06 |07 |08 |09 |0A |0B |0C |0D |49 |
+ * |-----------------------------------------------------------| ,-----.
+ * |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |1A |1B |1C |1D | | |
+ * |-----------------------------------------------------------| ,---. |
+ * |20 |21 |22 |23 |24 |25 |26 |17 |28 |29 |2A |2B |2D | |2C |2D |
+ * |-----------------------------------------------------------| `--------'
+ * |30 |31 |32 |33 |34 |35 |36 |37 |38 |39 |3A |3B |3D |3C |
+ * |-----------------------------------------------------------|
+ * |40 |41 |42 | 45 |4A |4B |4C |4D |
+ * `-----------------------------------------------------------'
+ * 2u Backspace = K0D
+ * 2.25u left Shift = K30
+ * 2.75u right Shift = K3D
+ */
+#define LAYOUT_all( \
+ 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, K3D, K3C, \
+ K40, K41, K42, K45, 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, 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 } \
+}
-// 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 multi-dimensional array
-/*
- * ,-----------------------------------------------------------------------------------------.
- * | 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 | K17 | K28 | K29 | K2A | K2B | K2C |
- * |-----------------------------------------------------------------------------------------+
- * | K30 | K32 | K33 | K34 | K35 | K36 | K37 | K38 | K39 | K3A | K3B | K3D | K3C |
- * |-----------------------------------------------------------------------------------------+
- * | K40 | K41 | K42 | K45 | K4A | K4B | K4C | K4D |
- * `-----------------------------------------------------------------------------------------'
+/* LAYOUT
+ * Present for backwards compatibility with older keymaps. The commit that added
+ * split Backspace support put the right 1u key of the split on the bottom row,
+ * next to right Alt. The arguments for 1.75/1u right Shift are also in reverse
+ * order.
+ * ,-----------------------------------------------------------.
+ * |00 |01 |02 |03 |04 |05 |06 |07 |08 |09 |0A |0B |0C |0D |49 |
+ * |-----------------------------------------------------------| ,-----.
+ * |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |1A |1B |1C |1D | | |
+ * |-----------------------------------------------------------| ,---. |
+ * |20 |21 |22 |23 |24 |25 |26 |17 |28 |29 |2A |2B |2D | |2C |2D |
+ * |-----------------------------------------------------------| `--------'
+ * |30 |31 |32 |33 |34 |35 |36 |37 |38 |39 |3A |3B |3D |3C |
+ * |-----------------------------------------------------------|
+ * |40 |41 |42 | 45 |4A |4B |4C |4D |
+ * `-----------------------------------------------------------'
*/
#define LAYOUT( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
@@ -27,82 +55,37 @@
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, 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, 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 } \
-}
+) LAYOUT_all( \
+ 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, K3D, K3C, \
+ K40, K41, K42, K45, K4A, K4B, K4C, K4D \
+)
-/* Default layout
- * ,-----------------------------------------------------------------------------------------.
- * | 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 | K17 | 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 |
- * `-----------------------------------------------------------------------------------------'
+/* LAYOUT_60_ansi
+ * ,-----------------------------------------------------------.
+ * |00 |01 |02 |03 |04 |05 |06 |07 |08 |09 |0A |0B |0C |0D |
+ * |-----------------------------------------------------------|
+ * |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |1A |1B |1C |1D |
+ * |-----------------------------------------------------------|
+ * |20 |21 |22 |23 |24 |25 |26 |17 |28 |29 |2A |2B |2D |
+ * |-----------------------------------------------------------|
+ * |30 |32 |33 |34 |35 |36 |37 |38 |39 |3A |3B |3D |
+ * |-----------------------------------------------------------|
+ * |40 |41 |42 | 45 |4A |4B |4C |4D |
+ * `-----------------------------------------------------------'
*/
-
#define LAYOUT_60_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 \
- ) { \
- { 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 } \
+ 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 \
+) { \
+ { 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 } \
}
-
-/* Mini Lshift
- * ,-----------------------------------------------------------------------------------------.
- * | 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 | K17 | K28 | K29 | K2A | K2B | K2C |
- * |-----------------------------------------------------------------------------------------+
- * | K30 |K31| K32 | K33 | K34 | K35 | K36 | K37 | K38 | K39 | K3A | K3B | K3C |
- * |-----------------------------------------------------------------------------------------+
- * | K40 | K41 | K42 | K45 | K4A | K4B | K4C | K4D |
- * `-----------------------------------------------------------------------------------------'
- */
-
-/* Mini Rshift
- * ,-----------------------------------------------------------------------------------------.
- * | 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 | K17 | K28 | K29 | K2A | K2B | K2C |
- * |-----------------------------------------------------------------------------------------+
- * | K30 | K32 | K33 | K34 | K35 | K36 | K37 | K38 | K39 | K3A | K3B | K3C | K3D |
- * |-----------------------------------------------------------------------------------------+
- * | K40 | K41 | K42 | K45 | K4A | K4B | K4C | K4D |
- * `-----------------------------------------------------------------------------------------'
- */
-
-/* Mini Enter
- * ,-----------------------------------------------------------------------------------------.
- * | 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 | K17 | K28 | K29 | K2A | K2B | K2C | K2D |
- * |-----------------------------------------------------------------------------------------+
- * | K30 | K32 | K33 | K34 | K35 | K36 | K37 | K38 | K39 | K3A | K3B | K3C |
- * |-----------------------------------------------------------------------------------------+
- * | K40 | K41 | K42 | K45 | K4A | K4B | K4C | K4D |
- * `-----------------------------------------------------------------------------------------'
- */
-
-#endif
diff --git a/keyboards/kc60/keymaps/default/keymap.c b/keyboards/kc60/keymaps/default/keymap.c
index a96b9d377..d5286e351 100644
--- a/keyboards/kc60/keymaps/default/keymap.c
+++ b/keyboards/kc60/keymaps/default/keymap.c
@@ -1,12 +1,18 @@
-
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [0] = LAYOUT( /* 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_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, \
- 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_NO, KC_RSFT, \
- KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_NO, KC_RGUI, KC_RALT, KC_RCTL, RESET \
- ),
+ [0] = LAYOUT_all(
+ 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_NUHS, 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, LT(1,KC_APP),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT(1,KC_APP), KC_RCTL
+ ),
+ [1] = LAYOUT_all(
+ 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, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, KC_UP, XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_PSCR, KC_SLCK, KC_PAUS,
+ XXXXXXX, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, KC_DEL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, XXXXXXX, XXXXXXX, XXXXXXX,
+ _______, XXXXXXX, XXXXXXX, BL_DEC, BL_TOGG, BL_INC, BL_BRTG, XXXXXXX, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, _______, _______,
+ _______, _______, _______, XXXXXXX, _______, _______, _______, _______
+ ),
};
diff --git a/keyboards/kc60/keymaps/default/readme.md b/keyboards/kc60/keymaps/default/readme.md
new file mode 100644
index 000000000..b10124eac
--- /dev/null
+++ b/keyboards/kc60/keymaps/default/readme.md
@@ -0,0 +1,5 @@
+# The default keymap for KC60
+
+![keymap](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/keyboards/kc60/keymaps/default/keymap.png)
+
+Both `Fn` keys trigger `KC_APP` when tapped, and activate Layer 1 when held.
diff --git a/keyboards/kc60/keymaps/ws2812/config.h b/keyboards/kc60/keymaps/ws2812/config.h
index 43abf6228..ef39965b3 100644
--- a/keyboards/kc60/keymaps/ws2812/config.h
+++ b/keyboards/kc60/keymaps/ws2812/config.h
@@ -1,9 +1,4 @@
-#include "../../config.h"
+#pragma once
-/* WS2812B RGB Underglow LED */
-#define RGB_DI_PIN F5 // Based on wiring depicted in ws2812_wiring.jpg
-#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
-#define RGBLIGHT_VAL_STEP 8
+#undef RGBLED_NUM
+#define RGBLED_NUM 16 // Number of LEDs. Change this to match your use case.
diff --git a/keyboards/kc60/keymaps/ws2812/keymap.c b/keyboards/kc60/keymaps/ws2812/keymap.c
index d445df337..aaefb61ca 100644
--- a/keyboards/kc60/keymaps/ws2812/keymap.c
+++ b/keyboards/kc60/keymaps/ws2812/keymap.c
@@ -1,96 +1,18 @@
-
#include QMK_KEYBOARD_H
-// 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
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* Keymap _BL: (Base Layer) Default Layer
- * ,-----------------------------------------------------------.
- * |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
- * |-----------------------------------------------------------|
- * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |
- * |-----------------------------------------------------------|
- * |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
- * |-----------------------------------------------------------|
- * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl|Gui |Alt | Space |Alt |Gui |FN |Ctrl |
- * `-----------------------------------------------------------'
- */
-[_BL] = LAYOUT(
- 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_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, \
- 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_NO, KC_RSFT, \
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_NO, KC_RALT,KC_RGUI, MO(_FL), KC_RCTL),
-
- /* Keymap _FL: Function Layer
- * ,-----------------------------------------------------------.
- * |~ |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12| DEL |
- * |-----------------------------------------------------------|
- * | | |UP | | | | | | | | |BL-|BL+|BL |
- * |-----------------------------------------------------------|
- * | |LFT|DWN|RGT| | | | | | | | |
- * |-----------------------------------------------------------|
- * | |FN1|FN2|FN3|FN4|FN5|FN6|FN7|FN8| | | |
- * |-----------------------------------------------------------|
- * | | | | | | | |RSET|
- * `-----------------------------------------------------------'
- */
-[_FL] = LAYOUT(
- #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, KC_DEL, \
- KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_INC, BL_TOGG, \
- 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, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, RESET),
- #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, KC_DEL, \
- KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_DEC, BL_INC, BL_TOGG, \
- 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_NO, KC_TRNS, KC_TRNS, KC_TRNS, RESET),
- #endif
+ [0] = LAYOUT_all(
+ 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_NUHS, 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, LT(1,KC_APP),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT(1,KC_APP), KC_RCTL
+ ),
+ [1] = LAYOUT_all(
+ 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, XXXXXXX, XXXXXXX,
+ XXXXXXX, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, KC_INS, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_PSCR, KC_SLCK, KC_PAUS,
+ XXXXXXX, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, KC_DEL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, XXXXXXX, XXXXXXX, XXXXXXX,
+ _______, XXXXXXX, XXXXXXX, BL_DEC, BL_TOGG, BL_INC, BL_BRTG, XXXXXXX, KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, _______, _______,
+ _______, _______, _______, XXXXXXX, _______, _______, _______, _______
+ ),
};
-
-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;
- }
-}
diff --git a/keyboards/kc60/keymaps/ws2812/readme.md b/keyboards/kc60/keymaps/ws2812/readme.md
deleted file mode 100644
index 49357a0f5..000000000
--- a/keyboards/kc60/keymaps/ws2812/readme.md
+++ /dev/null
@@ -1,21 +0,0 @@
-KC60 with WS2812 RGB Underglow
-======================
-
-![Image of KC60 with RGB Underglow](https://i.imgur.com/LpUkVqG.jpg)
-
-## Quantum MK Firmware
-For the full Quantum feature list, see [the parent readme.md](/readme.md).
-
-## WS2812 Support
-By default, it is now setup for 16 LEDs on the PF5 breakout pin. See [included image](https://i.imgur.com/TcKL2Sn.jpg) for wiring reference.
-
-### Build
-To build this keymap with WS2812 enabled, simply run `make KEYMAP=ws2812`.
-
-### Reference Images
-![Wiring Reference](https://i.imgur.com/TcKL2Sn.jpg)
-![RGB Strip turned on](https://i.imgur.com/21POu4l.jpg)
-![RGB Strip turned off](https://i.imgur.com/vAOLYNV.jpg)
-
-### Additional Credits
-Keymap based on work by [TerryMatthews](https://github.com/TerryMathews) for GH60 Satan.
diff --git a/keyboards/kc60/keymaps/ws2812/rules.mk b/keyboards/kc60/keymaps/ws2812/rules.mk
index 393ff863e..72a3d6f6c 100644
--- a/keyboards/kc60/keymaps/ws2812/rules.mk
+++ b/keyboards/kc60/keymaps/ws2812/rules.mk
@@ -1,22 +1,2 @@
-
-
-# Build Options
-# change yes to no to disable
-#
-BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = yes # Console for debug
-COMMAND_ENABLE = yes # Commands for debug and configuration
-KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key
-BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
-RGBLIGHT_ENABLE = yes # Enable WS2812 underglow RGB strip
-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
-# 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
-
+COMMAND_ENABLE = no
+RGBLIGHT_ENABLE = yes
diff --git a/keyboards/kc60/mod_rgb_underglow.md b/keyboards/kc60/mod_rgb_underglow.md
new file mode 100644
index 000000000..6aab1e1d2
--- /dev/null
+++ b/keyboards/kc60/mod_rgb_underglow.md
@@ -0,0 +1,31 @@
+# Adding RGB Underglow to the KC60
+
+![Image of KC60 with RGB Underglow](https://i.imgur.com/LpUkVqGl.jpg)
+
+The KC60 has breakout pins to which one may wire a strip of WS2812-compatible LEDs.
+
+By default, the source is set up for 16 LEDs on the F5 breakout pin. See [included image](https://i.imgur.com/TcKL2Sn.jpg) for wiring reference. If you attach a different number of LEDs, configure your source for the correct number of LEDs by adding a `config.h` file alongside your `keymap.c` file, with the following contents:
+
+```c
+#pragma once
+
+#undef RGBLED_NUM
+#define RGBLED_NUM <number of leds>
+```
+
+To enable RGB Underglow, simply add a `rules.mk` file containing `RGBLIGHT_ENABLE = yes` alongside your `keymap.c` file, and compile as normal:
+
+```shell
+make kc60:<keymap>
+```
+
+The [ws2812 keymap](keymaps/ws2812/) may be copied and used as a starting point.
+
+RGB Underglow is a fairly large feature, and your firmware may be too large to be flashed with it enabled. Adding `CONSOLE_ENABLE = no` or `COMMAND_ENABLE = no` to your `rules.mk` file will reduce the size of the firmware greatly, and if you don't use either feature, is a very low impact change.
+
+
+## Reference Images
+
+![Wiring Reference](https://i.imgur.com/TcKL2Sn.jpg)
+![RGB Strip turned on](https://i.imgur.com/21POu4l.jpg)
+![RGB Strip turned off](https://i.imgur.com/vAOLYNV.jpg)
diff --git a/keyboards/kc60/readme.md b/keyboards/kc60/readme.md
index e152824cc..71888e750 100644
--- a/keyboards/kc60/readme.md
+++ b/keyboards/kc60/readme.md
@@ -1,35 +1,19 @@
-KC60 (version 2.0) keyboard firmware
-======================
+# KC60
-## Quantum MK Firmware
-For the full Quantum feature list, see [the parent readme.md](/readme.md).
+![KC60](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/keyboards/kc60/kc60.jpg)
-## Building
-Download or clone the whole firmware and navigate to the keyboards/kc60 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.
+A 60% PCB supporting in-switch LEDs, formerly available on AliExpress and (Mass)Drop. Supports ANSI, ISO, split Backspace, and both standard and Tsangan bottom row layouts.
-Depending on which keymap you would like to use, you will have to compile slightly differently.
+* Keyboard Maintainer: [The QMK Community](https://github.com/qmk)
+* Hardware Supported: KC60 v1.6, v2.0; ATmega32U4
+* Hardware Availability: [Drop.com](https://drop.com/buy/kc60-mechanical-keyboard?mode=guest_open) (no longer available)
-### Default
-To build with the default keymap, simply run `make default`.
+Make example for this keyboard (after setting up your build environment):
-### 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` in the keymaps folder, and see keymap document (you can find in top readme.md) and existent keymap files.
+ make kc60:default
-To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
+## RGB Underglow Support
-```
-$ make [default|jack|<name>]
-```
+To add RGB Underglow to the KC60, see [Adding RGB Underglow to the KC60](mod_rgb_underglow.md).
-Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.
-
-## WS2812 Support
-
-Build with WS2812 Support by running `make ws2812`.
-
-## Warning
-For those who want to use 2x1U instead of classic backspace you need to use K0D and K49 like this:
-* K0D represents the key at the right of =.
-* K49 represents the last key of the row (is wired at the right of the space key on the PCB)
-
-In kc60.h I've put several definitions' examples of possible layouts proposed by online editor (http://123.57.250.164:9128/).
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/kc60/rules.mk b/keyboards/kc60/rules.mk
index 487b22c38..e1c92de96 100644
--- a/keyboards/kc60/rules.mk
+++ b/keyboards/kc60/rules.mk
@@ -19,15 +19,17 @@ MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug
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 = 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 = yes # Enable keyboard backlight functionality
-MIDI_ENABLE = no # MIDI controls
-UNICODE_ENABLE = no # Unicode
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key
LAYOUTS = 60_ansi
diff --git a/keyboards/keebio/bdn9/keymaps/via/keymap.c b/keyboards/keebio/bdn9/keymaps/via/keymap.c
new file mode 100644
index 000000000..6ef7a06ea
--- /dev/null
+++ b/keyboards/keebio/bdn9/keymaps/via/keymap.c
@@ -0,0 +1,52 @@
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ _ZERO,
+ _ONE,
+ _TWO,
+ _THREE
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[_ZERO] = LAYOUT(
+ KC_MPLY, KC_HOME, KC_MUTE,
+ MO(1), KC_UP, RGB_MOD,
+ KC_LEFT, KC_DOWN, KC_RGHT
+),
+
+[_ONE] = LAYOUT(
+ RESET, BL_STEP, KC_STOP,
+ _______, KC_HOME, RGB_MOD,
+ KC_MPRV, KC_END , KC_MNXT
+),
+
+[_TWO] = LAYOUT(
+ _______, _______, _______,
+ _______, _______, _______,
+ _______, _______, _______
+),
+
+[_THREE] = LAYOUT(
+ _______, _______, _______,
+ _______, _______, _______,
+ _______, _______, _______
+)
+
+};
+
+void encoder_update_user(uint8_t index, bool clockwise) {
+ if (index == 0) {
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ } else if (index == 1) {
+ if (clockwise) {
+ tap_code(KC_WH_U);
+ } else {
+ tap_code(KC_WH_D);
+ }
+ }
+}
diff --git a/keyboards/keebio/bdn9/keymaps/via/rules.mk b/keyboards/keebio/bdn9/keymaps/via/rules.mk
new file mode 100644
index 000000000..5b604f2b0
--- /dev/null
+++ b/keyboards/keebio/bdn9/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+VIA_ENABLE = yes
+LINK_TIME_OPTIMIZATION_ENABLE = yes
+MOUSEKEY_ENABLE = yes
+CONSOLE_ENABLE = no
+COMMAND_ENABLE = no
diff --git a/keyboards/keebio/choconum/chconf.h b/keyboards/keebio/choconum/chconf.h
new file mode 100644
index 000000000..03f63da36
--- /dev/null
+++ b/keyboards/keebio/choconum/chconf.h
@@ -0,0 +1,714 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file rt/templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+#define _CHIBIOS_RT_CONF_VER_6_0_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_ST_RESOLUTION)
+#define CH_CFG_ST_RESOLUTION 32
+#endif
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_CFG_ST_FREQUENCY)
+#define CH_CFG_ST_FREQUENCY 10000
+#endif
+
+/**
+ * @brief Time intervals data size.
+ * @note Allowed values are 16, 32 or 64 bits.
+ */
+#if !defined(CH_CFG_INTERVALS_SIZE)
+#define CH_CFG_INTERVALS_SIZE 32
+#endif
+
+/**
+ * @brief Time types data size.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#if !defined(CH_CFG_TIME_TYPES_SIZE)
+#define CH_CFG_TIME_TYPES_SIZE 32
+#endif
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#if !defined(CH_CFG_ST_TIMEDELTA)
+#define CH_CFG_ST_TIMEDELTA 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#if !defined(CH_CFG_TIME_QUANTUM)
+#define CH_CFG_TIME_QUANTUM 0
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#if !defined(CH_CFG_MEMCORE_SIZE)
+#define CH_CFG_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#if !defined(CH_CFG_NO_IDLE_THREAD)
+#define CH_CFG_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_OPTIMIZE_SPEED)
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_TM)
+#define CH_CFG_USE_TM FALSE
+#endif
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_REGISTRY)
+#define CH_CFG_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_WAITEXIT)
+#define CH_CFG_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES)
+#define CH_CFG_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MUTEXES)
+#define CH_CFG_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#if !defined(CH_CFG_USE_CONDVARS)
+#define CH_CFG_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_EVENTS)
+#define CH_CFG_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MESSAGES)
+#define CH_CFG_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
+#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#if !defined(CH_CFG_USE_MAILBOXES)
+#define CH_CFG_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMCORE)
+#define CH_CFG_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_CFG_USE_HEAP)
+#define CH_CFG_USE_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#define CH_CFG_USE_MEMPOOLS FALSE
+#endif
+
+/**
+ * @brief Objects FIFOs APIs.
+ * @details If enabled then the objects FIFOs APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#define CH_CFG_USE_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Pipes APIs.
+ * @details If enabled then the pipes APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_CFG_USE_PIPES)
+#define CH_CFG_USE_PIPES FALSE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#if !defined(CH_CFG_USE_DYNAMIC)
+#define CH_CFG_USE_DYNAMIC FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Objects factory options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Objects Factory APIs.
+ * @details If enabled then the objects factory APIs are included in the
+ * kernel.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_CFG_USE_FACTORY)
+#define CH_CFG_USE_FACTORY FALSE
+#endif
+
+/**
+ * @brief Maximum length for object names.
+ * @details If the specified length is zero then the name is stored by
+ * pointer but this could have unintended side effects.
+ */
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
+#endif
+
+/**
+ * @brief Enables the registry of generic objects.
+ */
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
+#endif
+
+/**
+ * @brief Enables factory for generic buffers.
+ */
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
+#endif
+
+/**
+ * @brief Enables factory for semaphores.
+ */
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#define CH_CFG_FACTORY_SEMAPHORES FALSE
+#endif
+
+/**
+ * @brief Enables factory for mailboxes.
+ */
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#define CH_CFG_FACTORY_MAILBOXES FALSE
+#endif
+
+/**
+ * @brief Enables factory for objects FIFOs.
+ */
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
+#endif
+
+/**
+ * @brief Enables factory for Pipes.
+ */
+#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
+#define CH_CFG_FACTORY_PIPES FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_STATISTICS)
+#define CH_DBG_STATISTICS FALSE
+#endif
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_MASK)
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+#endif
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING)
+#define CH_DBG_THREADS_PROFILING FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System structure extension.
+ * @details User fields added to the end of the @p ch_system_t structure.
+ */
+#define CH_CFG_SYSTEM_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief System initialization hook.
+ * @details User initialization code added to the @p chSysInit() function
+ * just before interrupts are enabled globally.
+ */
+#define CH_CFG_SYSTEM_INIT_HOOK() { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p _thread_init() function.
+ *
+ * @note It is invoked from within @p _thread_init() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/keebio/choconum/choconum.c b/keyboards/keebio/choconum/choconum.c
new file mode 100644
index 000000000..5360a716d
--- /dev/null
+++ b/keyboards/keebio/choconum/choconum.c
@@ -0,0 +1 @@
+#include "choconum.h"
diff --git a/keyboards/keebio/choconum/choconum.h b/keyboards/keebio/choconum/choconum.h
new file mode 100644
index 000000000..e77c5886e
--- /dev/null
+++ b/keyboards/keebio/choconum/choconum.h
@@ -0,0 +1,49 @@
+/* Copyright 2020 Keebio
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT_ortho_5x4( \
+ KA1, KA2, KA3, KA4, \
+ KB1, KB2, KB3, KB4, \
+ KC1, KC2, KC3, KC4, \
+ KD1, KD2, KD3, KD4, \
+ KE1, KE2, KE3, KE4 \
+) \
+{ \
+ { KA1, KA2, KA3, KA4 }, \
+ { KB1, KB2, KB3, KB4 }, \
+ { KC1, KC2, KC3, KC4 }, \
+ { KD1, KD2, KD3, KD4 }, \
+ { KE1, KE2, KE3, KE4 } \
+}
+
+#define LAYOUT_numpad_5x4( \
+ KA1, KA2, KA3, KA4, \
+ KB1, KB2, KB3, KB4, \
+ KC1, KC2, KC3, \
+ KD1, KD2, KD3, KD4, \
+ KE1, KE3 \
+) \
+{ \
+ { KA1, KA2, KA3, KA4 }, \
+ { KB1, KB2, KB3, KB4 }, \
+ { KC1, KC2, KC3, KC_NO }, \
+ { KD1, KD2, KD3, KD4 }, \
+ { KE1, KC_NO, KE3, KC_NO } \
+}
diff --git a/keyboards/keebio/choconum/config.h b/keyboards/keebio/choconum/config.h
new file mode 100644
index 000000000..9eee4eca9
--- /dev/null
+++ b/keyboards/keebio/choconum/config.h
@@ -0,0 +1,207 @@
+/*
+Copyright 2020 Keebio
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xCB10
+#define PRODUCT_ID 0x1154
+#define DEVICE_VER 0x0100
+#define MANUFACTURER Keebio
+#define PRODUCT Choconum
+#define DESCRIPTION Low-Profile Numpad
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 4
+#define DIRECT_PINS { \
+ { B2, B10, B3, B4 }, \
+ { B1, B11, A15, B5 }, \
+ { B0, A5, B7, F0 }, \
+ { A7, A6, B8, B6 }, \
+ { A4, A3, B9, F1 } \
+}
+
+/* COL2ROW, ROW2COL*/
+#define DIODE_DIRECTION COL2ROW
+
+#define DEBOUNCE 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* 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
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+// #define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * 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 */
+/* defined by default; to change, uncomment and set to the combination you want */
+// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
+
+/* 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_HELP H
+//#define MAGIC_KEY_HELP_ALT 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 0
+//#define MAGIC_KEY_LAYER0_ALT GRAVE
+//#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 B
+//#define MAGIC_KEY_BOOTLOADER_ALT ESC
+//#define MAGIC_KEY_LOCK CAPS
+//#define MAGIC_KEY_EEPROM E
+//#define MAGIC_KEY_EEPROM_CLEAR BSPACE
+//#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
+
+/* disable these deprecated features by default */
+#ifndef LINK_TIME_OPTIMIZATION_ENABLE
+ #define NO_ACTION_MACRO
+ #define NO_ACTION_FUNCTION
+#endif
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+ - MIDI notes can be sent when in Music mode is on
+*/
+//#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+ - MIDI notes can be added to the keymap
+ - Octave shift and transpose
+ - Virtual sustain, portamento, and modulation wheel
+ - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 1
+
+/*
+ * HD44780 LCD Display Configuration
+ */
+/*
+#define LCD_LINES 2 //< number of visible lines of the display
+#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
+
+#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
+
+#if LCD_IO_MODE
+#define LCD_PORT PORTB //< port for the LCD lines
+#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
+#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
+#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
+#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
+#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
+#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
+#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
+#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
+#define LCD_RS_PORT LCD_PORT //< port for RS line
+#define LCD_RS_PIN 3 //< pin for RS line
+#define LCD_RW_PORT LCD_PORT //< port for RW line
+#define LCD_RW_PIN 2 //< pin for RW line
+#define LCD_E_PORT LCD_PORT //< port for Enable line
+#define LCD_E_PIN 1 //< pin for Enable line
+#endif
+*/
+
+/* Bootmagic Lite key configuration */
+// #define BOOTMAGIC_LITE_ROW 0
+// #define BOOTMAGIC_LITE_COLUMN 0
diff --git a/keyboards/keebio/choconum/halconf.h b/keyboards/keebio/choconum/halconf.h
new file mode 100644
index 000000000..ff5ae7e8a
--- /dev/null
+++ b/keyboards/keebio/choconum/halconf.h
@@ -0,0 +1,525 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#define _CHIBIOS_HAL_CONF_
+#define _CHIBIOS_HAL_CONF_VER_7_0_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the cryptographic subsystem.
+ */
+#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__)
+#define HAL_USE_CRY FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C FALSE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SIO subsystem.
+ */
+#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__)
+#define HAL_USE_SIO FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the TRNG subsystem.
+ */
+#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__)
+#define HAL_USE_TRNG FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/**
+ * @brief Enables the WSPI subsystem.
+ */
+#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__)
+#define HAL_USE_WSPI FALSE
+#endif
+
+/*===========================================================================*/
+/* PAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define PAL_USE_CALLBACKS FALSE
+#endif
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
+#define PAL_USE_WAIT FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/**
+ * @brief Enforces the driver to use direct callbacks rather than OSAL events.
+ */
+#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__)
+#define CAN_ENFORCE_USE_CALLBACKS FALSE
+#endif
+
+/*===========================================================================*/
+/* CRY driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the SW fall-back of the cryptographic driver.
+ * @details When enabled, this option, activates a fall-back software
+ * implementation for algorithms not supported by the underlying
+ * hardware.
+ * @note Fall-back implementations may not be present for all algorithms.
+ */
+#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_USE_FALLBACK FALSE
+#endif
+
+/**
+ * @brief Makes the driver forcibly use the fall-back implementations.
+ */
+#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__)
+#define HAL_CRY_ENFORCE_FALLBACK FALSE
+#endif
+
+/*===========================================================================*/
+/* DAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
+#define DAC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define DAC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the zero-copy API.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief OCR initialization constant for V20 cards.
+ */
+#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR_V20 0x50FF8000U
+#endif
+
+/**
+ * @brief OCR initialization constant for non-V20 cards.
+ */
+#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__)
+#define SDC_INIT_OCR 0x80100000U
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables circular transfers APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
+#define SPI_USE_CIRCULAR FALSE
+#endif
+
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/**
+ * @brief Handling method for SPI CS line.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+/*===========================================================================*/
+/* WSPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
+#define WSPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define WSPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/keebio/choconum/info.json b/keyboards/keebio/choconum/info.json
new file mode 100644
index 000000000..888623566
--- /dev/null
+++ b/keyboards/keebio/choconum/info.json
@@ -0,0 +1,64 @@
+{
+ "keyboard_name": "Choconum",
+ "url": "https://keeb.io",
+ "maintainer": "Keebio",
+ "width": 5,
+ "height": 4,
+ "layouts": {
+ "LAYOUT_numpad_5x4": {
+ "key_count": 17,
+ "layout": [
+ {"x":0, "y":0},
+ {"x":1, "y":0},
+ {"x":2, "y":0},
+ {"x":3, "y":0},
+
+ {"x":0, "y":1},
+ {"x":1, "y":1},
+ {"x":2, "y":1},
+ {"x":3, "y":1, "h":2},
+
+ {"x":0, "y":2},
+ {"x":1, "y":2},
+ {"x":2, "y":2},
+
+ {"x":0, "y":3},
+ {"x":1, "y":3},
+ {"x":2, "y":3},
+ {"x":3, "y":3, "h":2},
+
+ {"x":0, "y":4,"w":2},
+ {"x":2, "y":4}
+ ]
+ },
+ "LAYOUT_ortho_5x4": {
+ "key_count": 20,
+ "layout": [
+ {"x":0, "y":0},
+ {"x":1, "y":0},
+ {"x":2, "y":0},
+ {"x":3, "y":0},
+
+ {"x":0, "y":1},
+ {"x":1, "y":1},
+ {"x":2, "y":1},
+ {"x":3, "y":1},
+
+ {"x":0, "y":2},
+ {"x":1, "y":2},
+ {"x":2, "y":2},
+ {"x":3, "y":2},
+
+ {"x":0, "y":3},
+ {"x":1, "y":3},
+ {"x":2, "y":3},
+ {"x":3, "y":3},
+
+ {"x":0, "y":4},
+ {"x":1, "y":4},
+ {"x":2, "y":4},
+ {"x":3, "y":4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/keebio/choconum/keymaps/default/keymap.c b/keyboards/keebio/choconum/keymaps/default/keymap.c
new file mode 100644
index 000000000..d6f0af3c8
--- /dev/null
+++ b/keyboards/keebio/choconum/keymaps/default/keymap.c
@@ -0,0 +1,40 @@
+/* Copyright 2020 Keebio
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+ _BASE,
+ _FN
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Base */
+ [_BASE] = LAYOUT_numpad_5x4(
+ 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, KC_PDOT
+ ),
+ [_FN] = LAYOUT_numpad_5x4(
+ _______, _______, _______, _______,
+ KC_HOME, KC_UP, KC_PGUP, _______,
+ KC_LEFT, _______, KC_RGHT,
+ KC_END, KC_DOWN, KC_PGDN, KC_PEQL,
+ KC_INS, KC_DEL
+ )
+};
diff --git a/keyboards/keebio/choconum/keymaps/via/keymap.c b/keyboards/keebio/choconum/keymaps/via/keymap.c
new file mode 100644
index 000000000..fec5e59e7
--- /dev/null
+++ b/keyboards/keebio/choconum/keymaps/via/keymap.c
@@ -0,0 +1,48 @@
+/* Copyright 2020 Keebio
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Base */
+ [0] = LAYOUT_ortho_5x4(
+ KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_P4, KC_P5, KC_P6, KC_PEQL,
+ KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_P0, KC_P0, KC_PDOT, KC_PENT
+ ),
+ [1] = LAYOUT_ortho_5x4(
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______
+ ),
+ [2] = LAYOUT_ortho_5x4(
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______
+ ),
+ [3] = LAYOUT_ortho_5x4(
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______,
+ _______, _______, _______, _______
+ )
+};
diff --git a/keyboards/keebio/choconum/keymaps/via/readme.md b/keyboards/keebio/choconum/keymaps/via/readme.md
new file mode 100644
index 000000000..58d53f0df
--- /dev/null
+++ b/keyboards/keebio/choconum/keymaps/via/readme.md
@@ -0,0 +1 @@
+# The default keymap for choconum
diff --git a/keyboards/keebio/choconum/keymaps/via/rules.mk b/keyboards/keebio/choconum/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/keebio/choconum/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/keebio/choconum/mcuconf.h b/keyboards/keebio/choconum/mcuconf.h
new file mode 100644
index 000000000..0e49478c8
--- /dev/null
+++ b/keyboards/keebio/choconum/mcuconf.h
@@ -0,0 +1,176 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+/*
+ * STM32F0xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 3...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F0xx_MCUCONF
+// #define STM32F070xB
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_HSI_ENABLED TRUE
+#define STM32_HSI14_ENABLED TRUE
+#define STM32_HSI48_ENABLED FALSE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
+#define STM32_PREDIV_VALUE 1
+#define STM32_PLLMUL_VALUE 12
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE STM32_PPRE_DIV1
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_ADCSW STM32_ADCSW_HSI14
+#define STM32_USBSW STM32_USBSW_HSI48
+#define STM32_CECSW STM32_CECSW_HSI
+#define STM32_I2C1SW STM32_I2C1SW_HSI
+#define STM32_USART1SW STM32_USART1SW_PCLK
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 2
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 2
+#define STM32_GPT_TIM2_IRQ_PRIORITY 2
+#define STM32_GPT_TIM3_IRQ_PRIORITY 2
+#define STM32_GPT_TIM14_IRQ_PRIORITY 2
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 FALSE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C2_IRQ_PRIORITY 3
+#define STM32_I2C_USE_DMA TRUE
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 3
+#define STM32_ICU_TIM2_IRQ_PRIORITY 3
+#define STM32_ICU_TIM3_IRQ_PRIORITY 3
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 TRUE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 3
+#define STM32_PWM_TIM2_IRQ_PRIORITY 3
+#define STM32_PWM_TIM3_IRQ_PRIORITY 3
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 3
+#define STM32_SERIAL_USART2_PRIORITY 3
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 FALSE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_IRQ_PRIORITY 2
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 2
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 3
+#define STM32_UART_USART2_IRQ_PRIORITY 3
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
+
+#endif /* _MCUCONF_H_ */
diff --git a/keyboards/keebio/choconum/readme.md b/keyboards/keebio/choconum/readme.md
new file mode 100644
index 000000000..7c2f70001
--- /dev/null
+++ b/keyboards/keebio/choconum/readme.md
@@ -0,0 +1,18 @@
+# Choconum
+
+![Choconum](https://cdn.shopify.com/s/files/1/1851/5125/products/image_ac483e26-c47b-4939-904f-41ad8de28210_1024x1024@2x.jpg?v=1586055933)
+
+A numpad for Kailh Choc switches
+
+* Keyboard Maintainer: [Keebio](https://github.com/nooges)
+* Hardware Availability: [Keebio - Choconum](https://keeb.io/products/choconum-kailh-choc-numpad)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make keebio/choconum:default
+
+Example of flashing this keyboard:
+
+ make keebio/choconum:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/keebio/choconum/rules.mk b/keyboards/keebio/choconum/rules.mk
new file mode 100644
index 000000000..9e754e09a
--- /dev/null
+++ b/keyboards/keebio/choconum/rules.mk
@@ -0,0 +1,27 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+
+LAYOUTS = ortho_5x4 numpad_5x4
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/keebio/iris/keymaps/pvinis/config.h b/keyboards/keebio/iris/keymaps/pvinis/config.h
index b2fb43be9..9574f2a83 100644
--- a/keyboards/keebio/iris/keymaps/pvinis/config.h
+++ b/keyboards/keebio/iris/keymaps/pvinis/config.h
@@ -1,24 +1,36 @@
#pragma once
-
#ifdef PRODUCT
- #undef PRODUCT
- #define PRODUCT Iris Keyboard - pvinis
+# undef PRODUCT
+# define PRODUCT Iris Keyboard - pvinis
#endif
-
-// Use I2C or Serial, not both
+// Use I2C or Serial, not both.
#define USE_SERIAL
// #define USE_I2C
-
-// Select hand configuration
-#define MASTER_LEFT
-// #define MASTER_RIGHT
+// Select hand configuration.
+// #define MASTER_LEFT
+#define MASTER_RIGHT
// #define EE_HANDS
-
-// choose pin to use for audio. c6 is the one iris uses.
+// Choose pin to use for audio. C6 is the one iris uses.
#ifdef AUDIO_ENABLE
- #define C6_AUDIO
+# define C6_AUDIO
+# define STARTUP_SONG SONG(NO_SOUND) // No startup song.
+#endif
+
+#ifdef RGBLIGHT_ENABLE
+# undef RGBLED_NUM
+# define RGBLED_NUM 16
+#endif
+
+#ifdef ENCODER_ENABLE
+# define ENCODERS_PAD_A \
+ { F5 } // I connected the encoder to F4 and F5.
+# define ENCODERS_PAD_B \
+ { F4 }
+// #define ENCODERS_PAD_A_RIGHT { B5 }
+// #define ENCODERS_PAD_B_RIGHT { C6 }
+# define ENCODER_RESOLUTION 2
#endif
diff --git a/keyboards/keebio/iris/keymaps/pvinis/keymap.c b/keyboards/keebio/iris/keymaps/pvinis/keymap.c
index 2f6d5a6b4..5c61c1321 100644
--- a/keyboards/keebio/iris/keymaps/pvinis/keymap.c
+++ b/keyboards/keebio/iris/keymaps/pvinis/keymap.c
@@ -1,16 +1,16 @@
// pvinis iris
-// ,-----------------------------. ,-----------------------------.
-// | | | | | | | | | | | | | |
-// |----+----+----+----+----+----| |----+----+----+----+----+----|
-// | | | | | | | | | | | | | |
-// |----+----+----+----x----x----| |----x----x----+----+----+----|
-// | | | | | | | | | | | | | |
-// |----+----+----+----x----x----+----. ,----|----x----x----+----+----+----|
-// | | | | | | | | | | | | | | | |
-// `-------------------+----+----+----/ \----+----+----+-------------------'
-// | | | | | | | |
-// `----+---------' `--------------'
-
+// make keebio/iris/rev2:pvinis:avrdude
+// ,-----------------------------. ┌────┬────┬────┬────┬────┬────┐
+// | | | | | | | │ │ │ │ │ │ │
+// |----+----+----+----+----+----| ├────┼────┼────┼────┼────┼────┤
+// | | | | | | | │ │ │ │ │ │ │
+// |----+----+----+----x----x----| ├────╆━━━━╅────┼────┼────┼────┤
+// | | | | | | | │ ┃ ┃ │ │ │ │
+// |----+----+----+----x----x----+----. ┌────┼────╄━━━━╃────┼────┼────┼────┤
+// | | | | | | | | │ │ │ │ │ │ │ │
+// `-------------------+----+----+----/ └┬───┴┬───┴┬───┴┬───┴────┴────┴────┘
+// | | | | │ │ │ │
+// `----+---------' └────┴────┴────┘
#include QMK_KEYBOARD_H
#include "pvinis.h"
@@ -19,102 +19,179 @@
//#include "eeconfig.h"
#ifdef AUDIO_ENABLE
- #include "audio.h"
+# include "audio.h"
#endif
#ifdef AUDIO_ENABLE
- // #define STARTUP_SONG SONG(SONIC_RING)
+// #define STARTUP_SONG SONG(SONIC_RING)
#endif
#ifdef AUDIO_ENABLE
- float tone_sonic[][2] = SONG(IN_LIKE_FLINT);
- float tone_1[][2] = SONG(QWERTY_SOUND);
- float tone_2[][2] = SONG(OLD_SPICE);
- float tone_3[][2] = SONG(OVERWATCH_THEME);
- float tone_4[][2] = SONG(QWERTY_SOUND);
+// float n04[][2] = SONG(CLOSE_ENCOUNTERS_5_NOTE);
+// float n10[][2] = SONG(STARTUP_SOUND);
+// float n11[][2] = SONG(GOODBYE_SOUND);
+// float n12[][2] = SONG(PLANCK_SOUND);
+// float n19[][2] = SONG(MUSIC_ON_SOUND);
+// float n20[][2] = SONG(AUDIO_ON_SOUND);
+// float n29[][2] = SONG(CAPS_LOCK_ON_SOUND);
+// float n30[][2] = SONG(CAPS_LOCK_OFF_SOUND);
+// float n31[][2] = SONG(SCROLL_LOCK_ON_SOUND);
+// float n32[][2] = SONG(SCROLL_LOCK_OFF_SOUND);
+// float n33[][2] = SONG(NUM_LOCK_ON_SOUND);
+// float n34[][2] = SONG(NUM_LOCK_OFF_SOUND);
+// float n40[][2] = SONG(ONE_UP_SOUND);
+// float n49[][2] = SONG(E1M1_DOOM);
+// float n53[][2] = SONG(OLD_SPICE);
+// float n56[][2] = SONG(RICK_ROLL);
+// float n57[][2] = SONG(FF_PRELUDE);
+// RGB_MODE_KNIGHT
+// float n78[][2] = SONG(KATAMARI_ROLLING_STAR);
#endif
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // ,-----------------------------. ,-----------------------------.
- // | | | | | |QWER| | | | | | | |
- // |----+----+----+----+----+----| |----+----+----+----+----+----|
- // |Tab | | | | |CARP| | | | | | |Del |
- // |----+----+----+----x----x----| |----x----x----+----+----+----|
- // |EscC| | | | | | | | | | | |Ent |
- // |----+----+----+----x----x----+----. ,----|----x----x----+----+----+----|
- // |LSft| | | | | |Home| |End | | | | | |Rsft|
- // `-------------------+----+----+----/ \----+----+----+-------------------'
- // |Cmd |LOWR|Bspc| |Spc |RASE|RAlt|
- // `----+---------' `--------------'
- [LR_BASE] = LAYOUT_wrapper(
- _______, _______, _______, _______, _______, QWERTY , _______, _______, _______, _______, _______, _______,
- KC_TAB , _______, _______, _______, _______, CARPALX, _______, _______, _______, _______, _______, KC_DEL ,
- PV_ESCC, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ENT ,
- KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT,
- KC_LGUI, SYMBOL , KC_BSPC, KC_SPC , SYSCTL , KC_RALT
- ),
+ // ,-----------------------------. ,-----------------------------.
+ // | | | | |GAME|QWER| | | | | | | |
+ // |----+----+----+----+----+----| |----+----+----+----+----+----|
+ // |Tab | | | | |CRPL| | | | | | |Del |
+ // |----+----+----+----x----x----| |----x----x----+----+----+----|
+ // |EscC| | | | | | | | | | | |Ent |
+ // |----+----+----+----x----x----+----. ,----|----x----x----+----+----+----|
+ // |LSft| | | | | |Home| |End | | | | | |Rsft|
+ // `-------------------+----+----+----/ \----+----+----+-------------------'
+ // |Cmd |LOWR|Bspc| |Spc |RASE|RAlt|
+ // `----+---------' `--------------'
+ [LR_BASE] = LAYOUT_wrapper(
+ // clang-format off
+ KC_MUTE, _______, _______, _______, GAME1 , QWERTY , KC_1 , _______, _______, _______, _______, _______,
+ KC_TAB , ___________________________________________, ___________________________________________, KC_DEL ,
+ PV_ESCC, ___________________________________________, ___________________________________________, KC_ENT ,
+ KC_LSFT, ___________________________________________, _______, _______, _______, _______, _______, _______, _______, KC_RSFT,
+ KC_LGUI, SYMBOL , KC_BSPC, KC_SPC , SYSCTL , KC_RALT
+ // clang-format on
+ ),
+
+ // ,-----------------------------. ,-----------------------------.
+ // | | NUMBERS_L | | NUMBERS_R | |
+ // |----+----+----+----+----+----| |----+----+----+----+----+----|
+ // | | | | | |
+ // |----+ | | +----|
+ // | | QWERTY_L | | QWERTY_R | |
+ // |----+ +----. ,----| +----|
+ // | | | | | | | |
+ // `-------------------+----+----+----/ \----+----+----+-------------------'
+ // | | | | | | | |
+ // `----+---------' `--------------'
+ [LR_QWERTY] = LAYOUT_wrapper(
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, _______,
+ _______, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, _______,
+ _______, _____________MOD_QWERTY_L2_________________, _________________QWERTY_R2_________________, _______,
+ _______, _________________QWERTY_L3_________________, _______, _______, _________________QWERTY_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- // ,-----------------------------. ,-----------------------------.
- // | | NUMBERS_L | | NUMBERS_R | |
- // |----+----+----+----+----+----| |----+----+----+----+----+----|
- // | | | | | |
- // |----+ | | +----|
- // | | QWERTY_L | | QWERTY_R | |
- // |----+ +----. ,----| +----|
- // | | | | | | | |
- // `-------------------+----+----+----/ \----+----+----+-------------------'
- // | | | | | | | |
- // `----+---------' `--------------'
- [LR_QWERTY] = LAYOUT_wrapper(
- _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, _______,
- _______, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, _______,
- _______, _____________MOD_QWERTY_L2_________________, _____________MOD_QWERTY_R2_________________, _______,
- _______, _________________QWERTY_L3_________________, _______, _______, _________________QWERTY_R3_________________, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ // ,-----------------------------. ,-----------------------------.
+ // | | NUMBERS_L | | NUMBERS_R | |
+ // |----+----+----+----+----+----| |----+----+----+----+----+----|
+ // | | | | | |
+ // |----+ | | +----|
+ // | | CARPALX_L | | CARPALX_R | |
+ // |----+ +----. ,----| +----|
+ // | | | | | | | |
+ // `-------------------+----+----+----/ \----+----+----+-------------------'
+ // | | | | | | | |
+ // `----+---------' `--------------'
+ [LR_CARPALX] = LAYOUT_wrapper(
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, _______,
+ _______, ________________CARPALX_L1_________________, ________________CARPALX_R1_________________, _______,
+ _______, ________________CARPALX_L2_________________, ________________CARPALX_R2_________________, _______,
+ _______, ________________CARPALX_L3_________________, _______, _______, ________________CARPALX_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- // ,-----------------------------. ,-----------------------------.
- // | | NUMBERS_L | | NUMBERS_R | |
- // |----+----+----+----+----+----| |----+----+----+----+----+----|
- // | | | | | |
- // |----+ | | +----|
- // | | CARPALX_L | | CARPALX_R | |
- // |----+ +----. ,----| +----|
- // | | | | | | | |
- // `-------------------+----+----+----/ \----+----+----+-------------------'
- // | | | | | | | |
- // `----+---------' `--------------'
- [LR_CARPALX] = LAYOUT_wrapper(
- _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, _______,
- _______, ________________CARPALX_L1_________________, ________________CARPALX_R1_________________, _______,
- _______, ________________CARPALX_L2_________________, ________________CARPALX_R2_________________, _______,
- _______, ________________CARPALX_L3_________________, _______, _______, ________________CARPALX_R3_________________, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ [LR_SYMBOL] = LAYOUT_wrapper(
+ // clang-format off
+ KC_F12 , ______________________F_L__________________, ______________________F_R__________________, KC_F11 ,
+ _______, _________________SYMBOL_L1_________________, _________________SYMBOL_R1_________________, _______,
+ _______, _________________SYMBOL_L2_________________, _________________SYMBOL_R2_________________, _______,
+ _______, _________________SYMBOL_L3_________________, _______, _______, _________________SYMBOL_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- [LR_SYMBOL] = LAYOUT_wrapper(
- KC_F12 , ______________________F_L__________________, ______________________F_R__________________, KC_F11 ,
- _______, _________________SYMBOL_L1_________________, _________________SYMBOL_R1_________________, _______,
- _______, _________________SYMBOL_L2_________________, _________________SYMBOL_R2_________________, _______,
- _______, _________________SYMBOL_L3_________________, _______, _______, _________________SYMBOL_R3_________________, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ [LR_SYSCTL] = LAYOUT_wrapper(
+ // clang-format off
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _________________SYSCTL_L1_________________, _________________SYSCTL_R1_________________, _______,
+ _______, _________________SYSCTL_L2_________________, _________________SYSCTL_R2_________________, _______,
+ _______, _________________SYSCTL_L3_________________, _______, _______, _________________SYSCTL_R3_________________, _______,
+ _______, _______, _______, _______, _______, _______
+ // clang-format on
+ ),
- [LR_SYSCTL] = LAYOUT_wrapper(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
- _______, _______, _______, _______, _______, _______, _________________SYSCTL_R1_________________, _______,
- _______, _______, _______, _______, _______, _______, _________________SYSCTL_R2_________________, _______,
- _______, _______, _______, _______, _______, _______, _______, _______, _________________SYSCTL_R3_________________, _______,
- _______, _______, _______, _______, _______, _______
- ),
+ [LR_KBCTL] = LAYOUT_wrapper(
+ // clang-format off
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, __________________KBCTL_L1_________________, __________________KBCTL_R1_________________, XXXXXXX,
+ XXXXXXX, __________________KBCTL_L2_________________, __________________KBCTL_R2_________________, XXXXXXX,
+ BASE , __________________KBCTL_L3_________________, XXXXXXX, XXXXXXX, __________________KBCTL_R3_________________, XXXXXXX,
+ XXXXXXX, _______, XXXXXXX, XXXXXXX, _______, XXXXXXX
+ // clang-format on
+ ),
- [LR_KBCTL] = LAYOUT_wrapper(
- XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
- XXXXXXX, __________________KBCTL_L1_________________, __________________KBCTL_R1_________________, XXXXXXX,
- XXXXXXX, __________________KBCTL_L2_________________, __________________KBCTL_R2_________________, XXXXXXX,
- BASE , __________________KBCTL_L3_________________, XXXXXXX, XXXXXXX, __________________KBCTL_R3_________________, XXXXXXX,
- XXXXXXX, _______, XXXXXXX, XXXXXXX, _______, XXXXXXX
- )
+ // ,-----------------------------. ,-----------------------------.
+ // | | NUMBERS_L | | NUMBERS_R | |
+ // |----+----+----+----+----+----| |----+----+----+----+----+----|
+ // | | | | | |
+ // |----+ | | +----|
+ // |ESC | QWERTY_L | | QWERTY_R | |
+ // |----+ +----. ,----| +----|
+ // | | | | | | | |
+ // `-------------------+----+----+----/ \----+----+----+-------------------'
+ // | |SPC | | | | | |
+ // `----+---------' `--------------'
+ [LR_GAME1] = LAYOUT_wrapper(
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, KC_BSPC,
+ _______, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, QWERTY ,
+ KC_ESC , _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, _______,
+ _______, _________________QWERTY_L3_________________, _______, _______, _________________QWERTY_R3_________________, _______,
+ _______, _______, KC_SPC , _______, _______, _______
+ // clang-format on
+ ),
+
+ [LR_GAME2] = LAYOUT_wrapper(
+ // clang-format off
+ _______, ________________NUMBERS_L__________________, ________________NUMBERS_R__________________, KC_BSPC,
+ _______, _________________QWERTY_L1_________________, KC_Y , KC_U , KC_UP , KC_O , KC_P , QWERTY ,
+ KC_ESC , _________________QWERTY_L2_________________, KC_H , KC_LEFT, KC_DOWN, KC_RGHT, KC_SCLN, _______,
+ _______, _________________QWERTY_L3_________________, _______, _______, _________________QWERTY_R3_________________, _______,
+ _______, _______, KC_SPC , _______, _______, _______
+ // clang-format on
+ ),
};
+
+#ifdef ENCODER_ENABLE
+void encoder_update_user(uint8_t index, bool clockwise) {
+ // if (index == 0) { /* First encoder */
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ // }
+}
+#endif
+
+bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+#ifdef AUDIO_ENABLE
+// case PV_S04: if (record->event.pressed) PLAY_SONG(n04); return false; break;
+#endif
+ }
+ return true; // Process everything else normally
+}
diff --git a/keyboards/keebio/iris/keymaps/pvinis/rules.mk b/keyboards/keebio/iris/keymaps/pvinis/rules.mk
index 899312894..deeb31203 100644
--- a/keyboards/keebio/iris/keymaps/pvinis/rules.mk
+++ b/keyboards/keebio/iris/keymaps/pvinis/rules.mk
@@ -1,2 +1,9 @@
-AUDIO_ENABLE = no # off for now
-RGBLIGHT_ENABLE = no # off for now
+TAP_DANCE_ENABLE = yes
+AUDIO_ENABLE = no # piezo speaker sounds
+RGBLIGHT_ENABLE = yes # rgb leds underlight
+ENCODER_ENABLE = yes # rotary knob
+
+# Some extra stuff to make firmware smaller.
+LINK_TIME_OPTIMIZATION_ENABLE = yes
+CONSOLE_ENABLE = no
+COMMAND_ENABLE = no
diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri3/config.h b/keyboards/keebio/nyquist/keymaps/georgepetri3/config.h
new file mode 100644
index 000000000..2e84fa0d5
--- /dev/null
+++ b/keyboards/keebio/nyquist/keymaps/georgepetri3/config.h
@@ -0,0 +1,25 @@
+/*
+Copyright 2017 Danny Nguyen <danny@hexwire.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/>.
+*/
+
+#pragma once
+
+#define RGBLIGHT_LAYERS
+
+#define TAPPING_TOGGLE 2
+#define TAPPING_TERM 150
+
+#define USE_I2C
diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri3/keymap.c b/keyboards/keebio/nyquist/keymaps/georgepetri3/keymap.c
new file mode 100644
index 000000000..a20c0d935
--- /dev/null
+++ b/keyboards/keebio/nyquist/keymaps/georgepetri3/keymap.c
@@ -0,0 +1,106 @@
+#include QMK_KEYBOARD_H
+#define _BASE 0
+#define _L 1
+#define _R 2
+
+#define KC_TL LCTL(KC_PGUP)
+#define KC_TR LCTL(KC_PGDN)
+#define KC_TC LCTL(KC_W)
+#define KC_TRO LCTL(LSFT(KC_T))
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+[_BASE] = LAYOUT(
+//┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐
+ KC_GRV , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , KC_BSPC,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ 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_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 ,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_CAPS, KC_LCTL, KC_LGUI, KC_LALT, MO(_L) , KC_SPC , KC_RSFT, TT(_R) , KC_LEFT, KC_DOWN, KC_UP , KC_RGHT
+//└────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_L] = LAYOUT(
+//┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐
+ _______, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, KC_F11 , KC_F12 , _______, _______, _______, _______, KC_MINS, KC_EQL , KC_LBRC, KC_RBRC, KC_BSLS,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_PGUP, KC_HOME, KC_END , _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+//└────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_R] = LAYOUT(
+//┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, KC_TL , KC_TR , KC_TC , KC_TRO , _______, _______, KC_TL , KC_TR , KC_TC , KC_TRO , _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, KC_PGDN, KC_PGUP, KC_HOME, KC_END , _______, _______, KC_PGDN, KC_PGUP, KC_HOME, KC_END , _______,
+//├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+//└────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┘
+ )
+};
+
+const rgblight_segment_t PROGMEM left[] = RGBLIGHT_LAYER_SEGMENTS(
+ {0, 12, HSV_SPRINGGREEN}
+);
+
+const rgblight_segment_t PROGMEM right[] = RGBLIGHT_LAYER_SEGMENTS(
+ {0, 12, HSV_RED}
+);
+
+const rgblight_segment_t PROGMEM capslock[] = RGBLIGHT_LAYER_SEGMENTS(
+ {2, 3, HSV_GOLD},
+ {6, 1, HSV_GOLD},
+ {11, 1, HSV_GOLD}
+);
+
+const rgblight_segment_t* const PROGMEM rgb_layers[] = RGBLIGHT_LAYERS_LIST(left, right, capslock);
+
+void keyboard_post_init_user(void) {
+ rgblight_sethsv_noeeprom(HSV_BLUE);
+ rgblight_layers = rgb_layers;
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ rgblight_set_layer_state(0, layer_state_cmp(state, _L));
+ rgblight_set_layer_state(1, layer_state_cmp(state, _R));
+ return state;
+}
+
+void suspend_power_down_user(void) {
+ rgblight_disable();
+}
+
+void suspend_wakeup_init_user(void) {
+ rgblight_enable();
+}
+
+bool is_shift_pressed = false;
+
+bool led_update_user(led_t led_state) {
+ rgblight_set_layer_state(2, is_shift_pressed != led_state.caps_lock);
+ return true;
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t* record) {
+ switch (keycode) {
+ case KC_LSFT:
+ case KC_RSFT:
+ is_shift_pressed = record->event.pressed;
+ rgblight_set_layer_state(2, is_shift_pressed != host_keyboard_led_state().caps_lock);
+ default:
+ return true;
+ }
+}
diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri3/readme.md b/keyboards/keebio/nyquist/keymaps/georgepetri3/readme.md
new file mode 100644
index 000000000..db4af6b31
--- /dev/null
+++ b/keyboards/keebio/nyquist/keymaps/georgepetri3/readme.md
@@ -0,0 +1,52 @@
+# George Petri's Nyquist rev3 layout
+
+```
+sudo make keebio/nyquist/rev3:georgepetri3:dfu
+```
+
+Features a dedicated navigation layer on rise and current layer status on rgb underglow.
+
+### Base Layer
+```
+┌──────┬──────┬──────┬──────┬──────┬──────┐ ┌──────┬──────┬──────┬──────┬──────┬──────┐
+│ GRAVE│ 1 │ 2 │ 3 │ 4 │ 5 │ │ 6 │ 7 │ 8 │ 9 │ 0 │ BSPC │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ TAB │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ DEL │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ ESC │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ SCLN│ QUOT │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ LSFT│ Z │ X │ C │ V │ B │ │ N │ M │ COMM│ DOT │ SLSH│ ENT │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ CAPS│ LCTL│ LGUI │ LALT │MO(_L)│ SPC │ │ RSFT│MO(_R)│ LEFT│ DOWN│ UP │ RGHT │
+└──────┴──────┴──────┴──────┴──────┴──────┘ └──────┴──────┴──────┴──────┴──────┴──────┘
+```
+
+### Lower
+```
+┌──────┬──────┬──────┬──────┬──────┬──────┐ ┌──────┬──────┬──────┬──────┬──────┬──────┐
+│ │ F1 │ F2 │ F3 │ F4 │ F5 │ │ F6 │ F7 │ F8 │ F9 │ F10 │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ F11 │ F12 │ │ │ │ │ │ MINS│ EQL │ LBRC│ RBRC│ BSLS │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ │ │ │ │ │ │ LEFT│ DOWN│ UP │ RGHT│ │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ │ │ │ │ │ │ │ PGDN│ PGUP │ HOME│ END │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ │ │ │ │ │ │ │ │ │ │ │ │
+└──────┴──────┴──────┴──────┴──────┴──────┘ └──────┴──────┴──────┴──────┴──────┴──────┘
+```
+
+### Rise
+```
+┌──────┬──────┬──────┬──────┬──────┬──────┐ ┌──────┬──────┬──────┬──────┬──────┬──────┐
+│ │ │ │ │ │ │ │ │ │ │ │ │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ TAB_L│ TAB_R│ TAB_C│ TAB_R│ │ │ │ TAB_L│ TAB_R│ TAB_C│ TAB_R│ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ LEFT│ DOWN│ UP │ RGHT│ │ │ LEFT│ DOWN│ UP │ RGHT│ │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ PGDN│ PGUP│ HOME│ END │ │ │ │ PGDN│ PGUP│ HOME│ END │ │
+├──────┼──────┼──────┼──────┼──────┼──────┤ ├──────┼──────┼──────┼──────┼──────┼──────┤
+│ │ │ │ │ │ │ │ │ │ │ │ │ │
+└──────┴──────┴──────┴──────┴──────┴──────┘ └──────┴──────┴──────┴──────┴──────┴──────┘
+```
diff --git a/keyboards/keebio/nyquist/keymaps/georgepetri3/rules.mk b/keyboards/keebio/nyquist/keymaps/georgepetri3/rules.mk
new file mode 100644
index 000000000..4010d90f0
--- /dev/null
+++ b/keyboards/keebio/nyquist/keymaps/georgepetri3/rules.mk
@@ -0,0 +1,5 @@
+MOUSEKEY_ENABLE = no
+COMMAND_ENABLE = no
+RGBLIGHT_ENABLE = yes
+LTO_ENABLE = yes
+DEBOUNCE_TYPE = eager_pk
diff --git a/keyboards/keebio/quefrency/rev1/config.h b/keyboards/keebio/quefrency/rev1/config.h
index 15771f531..815a3e197 100644
--- a/keyboards/keebio/quefrency/rev1/config.h
+++ b/keyboards/keebio/quefrency/rev1/config.h
@@ -55,3 +55,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 16 // Number of LEDs
+
+// Set 65% column (option 1) and Macro (option 2) on by default
+#define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x06
diff --git a/keyboards/keebio/quefrency/rev1/rules.mk b/keyboards/keebio/quefrency/rev1/rules.mk
index e69de29bb..58e9a76b2 100644
--- a/keyboards/keebio/quefrency/rev1/rules.mk
+++ b/keyboards/keebio/quefrency/rev1/rules.mk
@@ -0,0 +1 @@
+BOOTLOADER = caterina
diff --git a/keyboards/keebio/quefrency/rev2/config.h b/keyboards/keebio/quefrency/rev2/config.h
index d18b7be1f..ba85dc0f6 100644
--- a/keyboards/keebio/quefrency/rev2/config.h
+++ b/keyboards/keebio/quefrency/rev2/config.h
@@ -47,6 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DEBOUNCE 5
#define BACKLIGHT_PIN B5
+#define CAPS_LOCK_LED_PIN B6
/* serial.c configuration for split keyboard */
#define SOFT_SERIAL_PIN D0
@@ -62,3 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLED_NUM 16 // Number of LEDs
#define RGBLED_SPLIT { 8, 8 }
#define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 }
+
+// Set 65% column (option 3) and Macro (option 4) on by default
+#define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x0018
+#define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 2
diff --git a/keyboards/keebio/quefrency/rev2/rev2.c b/keyboards/keebio/quefrency/rev2/rev2.c
index d713a0ff3..69edfd415 100644
--- a/keyboards/keebio/quefrency/rev2/rev2.c
+++ b/keyboards/keebio/quefrency/rev2/rev2.c
@@ -1 +1,32 @@
#include "quefrency.h"
+#include "split_util.h"
+
+void matrix_init_kb(void) {
+ setPinOutput(CAPS_LOCK_LED_PIN);
+ matrix_init_user();
+}
+
+bool led_update_kb(led_t led_state) {
+ // Only update if left half
+ if (isLeftHand && led_update_user(led_state)) {
+ writePin(CAPS_LOCK_LED_PIN, !led_state.caps_lock);
+ }
+ return true;
+}
+
+void eeconfig_init_kb(void) {
+#ifdef BACKLIGHT_ENABLE
+ backlight_enable();
+ backlight_level(3);
+#endif
+#ifdef RGBLIGHT_ENABLE
+ rgblight_enable(); // Enable RGB by default
+ rgblight_sethsv(0, 255, 255); // Set default HSV - red hue, full saturation, full brightness
+#ifdef RGBLIGHT_ANIMATIONS
+ rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL + 2); // set to RGB_RAINBOW_SWIRL by default
+#endif
+#endif
+
+ eeconfig_update_kb(0);
+ eeconfig_init_user();
+}
diff --git a/keyboards/keebio/quefrency/rev2/rules.mk b/keyboards/keebio/quefrency/rev2/rules.mk
index 32e788159..0a368deb4 100644
--- a/keyboards/keebio/quefrency/rev2/rules.mk
+++ b/keyboards/keebio/quefrency/rev2/rules.mk
@@ -1,3 +1,4 @@
+BOOTLOADER = atmel-dfu
BACKLIGHT_ENABLE = yes
RGBLIGHT_ENABLE = yes
ENCODER_ENABLE = yes
diff --git a/keyboards/keebio/quefrency/rules.mk b/keyboards/keebio/quefrency/rules.mk
index a13f0478b..2c5ad0c36 100644
--- a/keyboards/keebio/quefrency/rules.mk
+++ b/keyboards/keebio/quefrency/rules.mk
@@ -1,32 +1,18 @@
# MCU name
MCU = atmega32u4
-# Bootloader selection
-# Teensy halfkay
-# Pro Micro caterina
-# Atmel DFU atmel-dfu
-# LUFA DFU lufa-dfu
-# QMK DFU qmk-dfu
-# ATmega32A bootloadHID
-# ATmega328P USBasp
-BOOTLOADER = caterina
-
-# 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
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = yes # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
+CONSOLE_ENABLE = yes # Console for debug
+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 = 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 = yes # Enable WS2812 RGB underlight.
+RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
diff --git a/keyboards/keebwerk/nano_slider/keymaps/default/keymap.c b/keyboards/keebwerk/nano_slider/keymaps/default/keymap.c
index 85f2d55ec..f9a14452f 100644
--- a/keyboards/keebwerk/nano_slider/keymaps/default/keymap.c
+++ b/keyboards/keebwerk/nano_slider/keymaps/default/keymap.c
@@ -21,7 +21,7 @@
enum layer_names {
_BASE,
_FN,
- _DEMO
+ _MEDIA
};
// Defines the keycodes used by our macros in process_record_user
@@ -30,6 +30,7 @@ enum custom_keycodes {
QMKURL
};
+
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Base */
[_BASE] = LAYOUT(
@@ -38,14 +39,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_4, KC_5, KC_6, KC_0
),
[_FN] = LAYOUT(
- TO(_DEMO),
- RGB_TOG, RGB_MOD, RGB_VAI,
- _______, _______, _______, _______
+ TO(_MEDIA),
+ RGB_TOG, RGB_MOD, RGB_VAI,
+ QMKURL, RGB_RMOD, RGB_VAD, QMKBEST
),
- [_DEMO] = LAYOUT(
+ [_MEDIA] = LAYOUT(
TO(_BASE),
- QMKBEST, _______, _______,
- _______, _______, _______, QMKURL
+ KC_VOLD, KC_VOLU, KC_F24,
+ KC_MRWD, KC_MFFD, KC_F23, KC_MPLY
)
};
diff --git a/keyboards/kira80/config.h b/keyboards/kira80/config.h
index b9ad85eb2..725b68d6e 100644
--- a/keyboards/kira80/config.h
+++ b/keyboards/kira80/config.h
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
+#define VENDOR_ID 0x6986
#define PRODUCT_ID 0xC583
#define DEVICE_VER 0x0102
#define MANUFACTURER EVE
diff --git a/keyboards/kira80/keymaps/via/keymap.c b/keyboards/kira80/keymaps/via/keymap.c
new file mode 100644
index 000000000..ebac6c6bd
--- /dev/null
+++ b/keyboards/kira80/keymaps/via/keymap.c
@@ -0,0 +1,52 @@
+/* Copyright 2020 Lorenz Wellmer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT_all(
+ 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_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_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_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_TRNS, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [1] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BL_TOGG, BL_DEC, BL_INC,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 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] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ [3] = LAYOUT_all(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/kira80/keymaps/via/readme.md b/keyboards/kira80/keymaps/via/readme.md
new file mode 100644
index 000000000..a72e88c8b
--- /dev/null
+++ b/keyboards/kira80/keymaps/via/readme.md
@@ -0,0 +1 @@
+# VIA keymap for Kira 80
diff --git a/keyboards/kira80/keymaps/via/rules.mk b/keyboards/kira80/keymaps/via/rules.mk
new file mode 100644
index 000000000..981c7ad4c
--- /dev/null
+++ b/keyboards/kira80/keymaps/via/rules.mk
@@ -0,0 +1,3 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/kudox/kudox.h b/keyboards/kudox/kudox.h
index 09549fbc5..ca61ea82d 100644
--- a/keyboards/kudox/kudox.h
+++ b/keyboards/kudox/kudox.h
@@ -22,6 +22,9 @@
#ifdef KEYBOARD_kudox_rev2
#include "rev2.h"
#endif
+#ifdef KEYBOARD_kudox_rev3
+ #include "rev3.h"
+#endif
#ifdef KEYBOARD_kudox_columner
#include "columner.h"
#endif
diff --git a/keyboards/kudox/readme.md b/keyboards/kudox/readme.md
index cc97bf83b..107b99b10 100644
--- a/keyboards/kudox/readme.md
+++ b/keyboards/kudox/readme.md
@@ -5,25 +5,23 @@
</p>
<p align="center">
-<img src="https://raw.githubusercontent.com/kumaokobo/kudox-keyboard/master/img/kudox-pcb.jpg" alt="Kudox PCB rev2.0" width="600"/>
+<img src="https://raw.githubusercontent.com/kumaokobo/kudox-keyboard/master/img/kudox-rev3-image1.jpg" alt="Kudox rev3.0" width="600"/>
</p>
- Keyboard Maintainer: [Kumao Kobo](https://github.com/kumaokobo)
-- Hardware Supported: Kudox PCB rev1.0 rev2.0 w/ Pro Micro
+- Hardware Supported: Kudox PCB rev1.0 rev2.0 rev3.0 w/ Pro Micro
Make example for this keyboard (after setting up your build environment):
```sh
-make kudox/rev2:default
+make kudox/rev3:default
```
Example of flashing this keyboard:
```sh
-make kudox/rev2:default:flash
+make kudox/rev3:default:flash
```
-*keymaps/default is for rev2.0. If you want to use rev1.0, you should remove Left-06 key and Right-06 key.*
-
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/kudox/rev3/config.h b/keyboards/kudox/rev3/config.h
new file mode 100644
index 000000000..88969feed
--- /dev/null
+++ b/keyboards/kudox/rev3/config.h
@@ -0,0 +1,91 @@
+/* Copyright 2019 Kumao Kobo <kumaokobo@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/>.
+ */
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x9690
+#define DEVICE_VER 0x0300
+#define MANUFACTURER Kumao Kobo
+#define PRODUCT The Kudox Keyboard
+#define DESCRIPTION Split row staggered 5x7 custom keyboard
+
+/* key matrix size */
+// Rows are doubled-up
+#define MATRIX_ROWS 10
+#define MATRIX_COLS 7
+
+// wiring of each half
+#define MATRIX_ROW_PINS { D4, D7, E6, B4, B5 }
+#define MATRIX_COL_PINS { F5, F6, F7, B1, B3, B2, B6 }
+// #define MATRIX_COL_PINS { B6, B2, B3, B1, F7, F6, F5} //uncomment this line and comment line above if you need to reverse left-to-right key order
+
+/* 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 DEBOUNCE 5
+
+/* serial.c configuration for split keyboard */
+#define SOFT_SERIAL_PIN D0
+
+/* 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
+
+/* ws2812 RGB LED */
+#define RGB_DI_PIN D3
+
+#undef RGBLED_NUM
+#define RGBLED_NUM 14 // Number of LEDs
+#define RGBLIGHT_ANIMATIONS
+#define RGBLIGHT_HUE_STEP 8
+#define RGBLIGHT_SAT_STEP 8
+#define RGBLIGHT_VAL_STEP 8
+
+/*
+ * 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
+
+#define MOUSEKEY_INTERVAL 20
+#define MOUSEKEY_DELAY 0
+#define MOUSEKEY_TIME_TO_MAX 60
+#define MOUSEKEY_MAX_SPEED 7
+#define MOUSEKEY_WHEEL_DELAY 0
diff --git a/keyboards/kudox/rev3/info.json b/keyboards/kudox/rev3/info.json
new file mode 100644
index 000000000..84b5ce0f3
--- /dev/null
+++ b/keyboards/kudox/rev3/info.json
@@ -0,0 +1,77 @@
+{
+ "url": "http://kumaokobo.com/",
+ "maintainer": "Kumao Kobo",
+ "keyboard_name": "Kudox Keyboard Rev3",
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label":"`", "x":0, "y":0},
+ {"label":"1", "x":1, "y":0},
+ {"label":"2", "x":2, "y":0},
+ {"label":"3", "x":3, "y":0},
+ {"label":"4", "x":4, "y":0},
+ {"label":"5", "x":5, "y":0},
+ {"label":"6", "x":6, "y":0},
+ {"label":"7", "x":10, "y":0},
+ {"label":"8", "x":11, "y":0},
+ {"label":"9", "x":12, "y":0},
+ {"label":"0", "x":13, "y":0},
+ {"label":"-", "x":14, "y":0},
+ {"label":"=", "x":15, "y":0},
+ {"label":"\u2190", "x":16, "y":0},
+ {"label":"Tab", "x":0, "y":1, "w":1.25},
+ {"label":"Q", "x":1.25, "y":1},
+ {"label":"W", "x":2.25, "y":1},
+ {"label":"E", "x":3.25, "y":1},
+ {"label":"R", "x":4.25, "y":1},
+ {"label":"T", "x":5.25, "y":1},
+ {"label":"Esc", "x":6.25, "y":1},
+ {"label":"Y", "x":9.75, "y":1},
+ {"label":"U", "x":10.75, "y":1},
+ {"label":"I", "x":11.75, "y":1},
+ {"label":"O", "x":12.75, "y":1},
+ {"label":"P", "x":13.75, "y":1},
+ {"label":"'", "x":14.75, "y":1},
+ {"label":"\\", "x":15.75, "y":1, "w":1.25},
+ {"label":"Ctrl", "x":0, "y":2, "w":1.75},
+ {"label":"A", "x":1.75, "y":2},
+ {"label":"S", "x":2.75, "y":2},
+ {"label":"D", "x":3.75, "y":2},
+ {"label":"F", "x":4.75, "y":2},
+ {"label":"G", "x":5.75, "y":2},
+ {"label":"H", "x":10.25, "y":2},
+ {"label":"J", "x":11.25, "y":2},
+ {"label":"K", "x":12.25, "y":2},
+ {"label":"L", "x":13.25, "y":2},
+ {"label":";", "x":14.25, "y":2},
+ {"label":"Enter", "x":15.25, "y":2, "w":1.75},
+ {"label":"Shift", "x":0, "y":3, "w":2.25},
+ {"label":"Z", "x":2.25, "y":3},
+ {"label":"X", "x":3.25, "y":3},
+ {"label":"C", "x":4.25, "y":3},
+ {"label":"V", "x":5.25, "y":3},
+ {"label":"B", "x":6.25, "y":3},
+ {"label":"N", "x":9.75, "y":3},
+ {"label":"M", "x":10.75, "y":3},
+ {"label":",", "x":11.75, "y":3},
+ {"label":".", "x":12.75, "y":3},
+ {"label":"/", "x":13.75, "y":3},
+ {"label":"Shift", "x":14.75, "y":3, "w":2.25},
+ {"label":"Alt", "x":0, "y":4, "w":1.25},
+ {"label":"[", "x":1.25, "y":4},
+ {"label":"]", "x":2.25, "y":4},
+ {"label":"LANG2", "x":3.25, "y":4},
+ {"label":"Enter", "x":4.25, "y":4.33, "w":1.25},
+ {"label":"GUI", "x":5.5, "y":4.67},
+ {"label":"Space", "x":6.5, "y":5},
+ {"label":"Space", "x":9.5, "y":5},
+ {"label":"GUI", "x":10.5, "y":4.67},
+ {"label":"LANG1", "x":11.5, "y":4.33, "w":1.25},
+ {"label":"\u2190", "x":12.75, "y":4},
+ {"label":"\u2193", "x":13.75, "y":4},
+ {"label":"\u2191", "x":14.75, "y":4},
+ {"label":"\u2192", "x":15.75, "y":4, "w":1.25}
+ ]
+ }
+ }
+}
diff --git a/keyboards/kudox/rev3/keymaps/default/keymap.c b/keyboards/kudox/rev3/keymaps/default/keymap.c
new file mode 100644
index 000000000..53166e735
--- /dev/null
+++ b/keyboards/kudox/rev3/keymaps/default/keymap.c
@@ -0,0 +1,70 @@
+#include QMK_KEYBOARD_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 _QWERTY 0
+#define _SYMB 1
+#define _LIGHT 2
+
+// Shortcut to make keymap more readable
+#define SYM_L2 LT(_SYMB, KC_LANG2)
+#define TO_LIGH TO(_LIGHT)
+#define TO_QWER TO(_QWERTY)
+
+#define KC_ALES LALT_T(KC_ESC)
+#define KC_ALEN LALT_T(KC_ENT)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_QWERTY] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ KC_GRV ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 ,KC_6 , KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINS, KC_EQL ,KC_BSPC ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_ESC , KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_SLSH ,KC_BSLS ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_LCTL ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G , KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN ,KC_ENT ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B , KC_N ,KC_M ,KC_COMM ,KC_DOT ,KC_UP ,KC_RSFT ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ KC_ALES ,KC_LBRC ,KC_RBRC ,SYM_L2 ,KC_ALEN ,KC_LGUI ,KC_SPC , KC_SPC ,KC_RGUI ,TO_LIGH ,KC_LANG1,KC_LEFT, KC_DOWN ,KC_RIGHT
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_SYMB] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ 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_DEL ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,KC_DQUO ,KC_QUOT ,KC_GRV ,KC_ASTR ,KC_PLUS ,KC_EQL , KC_LPRN ,KC_RPRN ,KC_PIPE ,KC_ASTR ,KC_TILD ,KC_CIRC ,KC_PIPE ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,KC_AT ,KC_COLN ,KC_GRV ,KC_SLSH ,KC_MINS , KC_LBRC ,KC_RBRC ,KC_DOT ,KC_SLSH ,KC_MINS ,_______ ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , KC_LCBR ,KC_RCBR ,_______ ,_______ ,KC_CIRC ,_______ ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ _______ ,_______ ,_______ ,_______ ,_______ ,_______ ,_______ , _______ ,_______ ,_______ ,_______ ,KC_LABK ,KC_UNDS ,KC_RABK
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_LIGHT] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ _______ ,RGB_HUI ,RGB_HUD ,RGB_SAI ,RGB_SAD ,RGB_VAI ,RGB_VAD , RGB_HUI ,RGB_HUD ,RGB_SAI ,RGB_SAD ,RGB_VAI ,RGB_VAD ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_P ,RGB_M_SW ,RGB_M_X,XXXXXXX ,XXXXXXX ,XXXXXXX , RGB_M_P ,RGB_M_SW ,RGB_M_X ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_B ,RGB_M_SN ,RGB_M_G,XXXXXXX ,XXXXXXX , RGB_M_B ,RGB_M_SN ,RGB_M_G ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_R ,RGB_M_K ,RGB_M_T ,XXXXXXX ,XXXXXXX , RGB_M_R ,RGB_M_K ,RGB_M_T ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ _______ ,_______ ,_______ ,_______ ,_______ ,RGB_MOD ,RGB_TOG , RGB_TOG ,RGB_MOD ,TO_QWER ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ )
+
+};
+
+
+#ifdef RGBLIGHT_ENABLE
+void keyboard_post_init_user(void) {
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL);
+};
+#endif
diff --git a/keyboards/kudox/rev3/keymaps/default/readme.md b/keyboards/kudox/rev3/keymaps/default/readme.md
new file mode 100644
index 000000000..aead0ad1f
--- /dev/null
+++ b/keyboards/kudox/rev3/keymaps/default/readme.md
@@ -0,0 +1 @@
+# The default keymap for Kudox Keyboard Rev3.0
diff --git a/keyboards/kudox/rev3/keymaps/jis/keymap.c b/keyboards/kudox/rev3/keymaps/jis/keymap.c
new file mode 100644
index 000000000..bc1b33310
--- /dev/null
+++ b/keyboards/kudox/rev3/keymaps/jis/keymap.c
@@ -0,0 +1,70 @@
+#include QMK_KEYBOARD_H
+#include"keymap_jp.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 _QWERTY 0
+#define _SYMB 1
+#define _LIGHT 2
+
+// Shortcut to make keymap more readable
+#define SYM_L2 LT(_SYMB, KC_LANG2)
+#define TO_LIGH TO(_LIGHT)
+#define TO_QWER TO(_QWERTY)
+
+#define KC_ALES LALT_T(KC_ESC)
+#define KC_ALEN LALT_T(KC_ENT)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [_QWERTY] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ JP_ZKHK ,KC_1 ,KC_2 ,KC_3 ,KC_4 ,KC_5 ,KC_6 , KC_7 ,KC_8 ,KC_9 ,KC_0 ,JP_MINS ,JP_CIRC ,KC_BSPC ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_TAB ,KC_Q ,KC_W ,KC_E ,KC_R ,KC_T ,KC_ESC , KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,JP_AT ,JP_SLSH ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_LCTL ,KC_A ,KC_S ,KC_D ,KC_F ,KC_G , KC_H ,KC_J ,KC_K ,KC_L ,JP_SCLN ,KC_ENT ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ KC_LSFT ,KC_Z ,KC_X ,KC_C ,KC_V ,KC_B , KC_N ,KC_M ,JP_COMM ,JP_DOT ,KC_UP ,KC_RSFT ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ KC_ALES ,JP_YEN ,JP_COLN ,SYM_L2 ,KC_ALEN ,KC_LGUI ,KC_SPC , KC_SPC ,KC_RGUI ,TO_LIGH ,KC_LANG1,KC_LEFT, KC_DOWN ,KC_RIGHT
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_SYMB] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ 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_DEL ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,JP_DQUO ,JP_QUOT ,KC_GRV ,JP_ASTR ,JP_PLUS ,JP_EQL , JP_LPRN ,JP_RPRN ,JP_PIPE ,JP_ASTR ,JP_TILD ,JP_CIRC ,JP_PIPE ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,JP_AT ,JP_COLN ,KC_GRV ,JP_SLSH ,JP_MINS , JP_LBRC ,JP_RBRC ,JP_DOT ,JP_SLSH ,JP_MINS ,_______ ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX , JP_LCBR ,JP_RCBR ,_______ ,_______ ,JP_CIRC ,_______ ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ _______ ,_______ ,_______ ,_______ ,_______ ,_______ ,_______ , _______ ,_______ ,_______ ,_______ ,JP_LABK ,JP_UNDS ,JP_RABK
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ ),
+
+ [_LIGHT] = LAYOUT(
+ //┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┐
+ _______ ,RGB_HUI ,RGB_HUD ,RGB_SAI ,RGB_SAD ,RGB_VAI ,RGB_VAD , RGB_HUI ,RGB_HUD ,RGB_SAI ,RGB_SAD ,RGB_VAI ,RGB_VAD ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_P ,RGB_M_SW ,RGB_M_X,XXXXXXX ,XXXXXXX ,XXXXXXX , RGB_M_P ,RGB_M_SW ,RGB_M_X ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┘ └────────┼────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_B ,RGB_M_SN ,RGB_M_G,XXXXXXX ,XXXXXXX , RGB_M_B ,RGB_M_SN ,RGB_M_G ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤
+ _______ ,RGB_M_R ,RGB_M_K ,RGB_M_T ,XXXXXXX ,XXXXXXX , RGB_M_R ,RGB_M_K ,RGB_M_T ,XXXXXXX ,XXXXXXX ,XXXXXXX ,
+ //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┴────────┼────────┼────────┼────────┤
+ _______ ,_______ ,_______ ,_______ ,_______ ,RGB_MOD ,RGB_TOG , RGB_TOG ,RGB_MOD ,TO_QWER ,XXXXXXX ,XXXXXXX ,XXXXXXX ,XXXXXXX
+ //└────────┴────────┴────────┴────────┴────────┴────────┴────────┘ └────────┴────────┴────────┴────────┴────────┴────────┴────────┘
+ )
+
+};
+
+#ifdef RGBLIGHT_ENABLE
+void keyboard_post_init_user(void) {
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_RAINBOW_SWIRL);
+};
+#endif
diff --git a/keyboards/kudox/rev3/keymaps/jis/readme.md b/keyboards/kudox/rev3/keymaps/jis/readme.md
new file mode 100644
index 000000000..90e790215
--- /dev/null
+++ b/keyboards/kudox/rev3/keymaps/jis/readme.md
@@ -0,0 +1 @@
+# The JIS keymap for Kudox Keyboard Rev3.0
diff --git a/keyboards/kudox/rev3/rev3.c b/keyboards/kudox/rev3/rev3.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/kudox/rev3/rev3.c
diff --git a/keyboards/kudox/rev3/rev3.h b/keyboards/kudox/rev3/rev3.h
new file mode 100644
index 000000000..dcc745ddb
--- /dev/null
+++ b/keyboards/kudox/rev3/rev3.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT( \
+ L00, L01, L02, L03, L04, L05, L06, R06, R05, R04, R03, R02, R01, R00, \
+ L10, L11, L12, L13, L14, L15, L16, R16, R15, R14, R13, R12, R11, R10, \
+ L20, L21, L22, L23, L24, L25, R25, R24, R23, R22, R21, R20, \
+ L30, L31, L32, L33, L34, L35, R35, R34, R33, R32, R31, R30, \
+ L40, L41, L42, L43, L44, L45, L46, R46, R45, R44, R43, R42, R41, R40 \
+) \
+{ \
+ { L00, L01, L02, L03, L04, L05, L06 }, \
+ { L10, L11, L12, L13, L14, L15, L16 }, \
+ { L20, L21, L22, L23, L24, L25 }, \
+ { L30, L31, L32, L33, L34, L35 }, \
+ { L40, L41, L42, L43, L44, L45, L46 }, \
+ { R00, R01, R02, R03, R04, R05, R06 }, \
+ { R10, R11, R12, R13, R14, R15, R16 }, \
+ { R20, R21, R22, R23, R24, R25 }, \
+ { R30, R31, R32, R33, R34, R35 }, \
+ { R40, R41, R42, R43, R44, R45, R46 } \
+}
diff --git a/keyboards/kudox/rev3/rules.mk b/keyboards/kudox/rev3/rules.mk
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/kudox/rev3/rules.mk
diff --git a/keyboards/kudox/rules.mk b/keyboards/kudox/rules.mk
index 4ae8ea7fb..1b00218c7 100644
--- a/keyboards/kudox/rules.mk
+++ b/keyboards/kudox/rules.mk
@@ -33,4 +33,4 @@ RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
SPLIT_KEYBOARD = yes
-DEFAULT_FOLDER = kudox/rev2
+DEFAULT_FOLDER = kudox/rev3
diff --git a/keyboards/launchpad/keymaps/via/keymap.c b/keyboards/launchpad/keymaps/via/keymap.c
index c98432035..ac25fa1e1 100644
--- a/keyboards/launchpad/keymaps/via/keymap.c
+++ b/keyboards/launchpad/keymaps/via/keymap.c
@@ -9,7 +9,7 @@
enum layer_names {
_QWERTY,
_FUNC,
- _LAYER2,
+ _RGB,
_LAYER3
};
@@ -34,7 +34,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_1, KC_2,
KC_3, KC_4,
KC_5, KC_6,
- MO(_FUNC), KC_8
+ MO(_FUNC), TG(_RGB)
),
/* Function
@@ -55,22 +55,22 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_C
),
-/* Layer 2
+/* RGB
* ,-------------.
- * | | |
+ * | MODE-| MODE+|
* |------+------|
- * | | |
+ * | HUE- | HUE+ |
* |------+------|
- * | | |
+ * | SAT- | SAT+ |
* |------+------|
- * | | |
+ * |TOGGLE| |
* `-------------'
*/
-[_LAYER2] = LAYOUT(
- KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS,
- KC_TRNS, KC_TRNS
+[_RGB] = LAYOUT(
+ RGB_RMOD, RGB_MOD,
+ RGB_HUD, RGB_HUI,
+ RGB_SAD, RGB_SAI,
+ RGB_TOG, KC_TRNS
),
/* Layer 3
diff --git a/keyboards/launchpad/keymaps/via/rules.mk b/keyboards/launchpad/keymaps/via/rules.mk
index 1e5b99807..87843cb0d 100644
--- a/keyboards/launchpad/keymaps/via/rules.mk
+++ b/keyboards/launchpad/keymaps/via/rules.mk
@@ -1 +1,3 @@
VIA_ENABLE = yes
+LINK_TIME_OPTIMIZATION_ENABLE = yes
+RGBLIGHT_ENABLE = yes
diff --git a/keyboards/launchpad/rev1/config.h b/keyboards/launchpad/rev1/config.h
index 67a415422..debc28fab 100644
--- a/keyboards/launchpad/rev1/config.h
+++ b/keyboards/launchpad/rev1/config.h
@@ -15,8 +15,7 @@ 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 REV1_CONFIG_H
-#define REV1_CONFIG_H
+#pragma once
#include "../config.h"
@@ -29,4 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DIODE_DIRECTION COL2ROW
-#endif
+#define RGBLED_NUM 10
+#define RGB_DI_PIN F6
+#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/maartenwut/wasdat/config.h b/keyboards/maartenwut/wasdat/config.h
index ffd33d853..d30263bfc 100644
--- a/keyboards/maartenwut/wasdat/config.h
+++ b/keyboards/maartenwut/wasdat/config.h
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
+#define VENDOR_ID 0x4705
#define PRODUCT_ID 0xC474
#define DEVICE_VER 0x0001
#define MANUFACTURER Maartenwut
@@ -252,5 +252,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Bootmagic Lite key configuration */
-// #define BOOTMAGIC_LITE_ROW 0
-// #define BOOTMAGIC_LITE_COLUMN 0
+#define BOOTMAGIC_LITE_ROW 0
+#define BOOTMAGIC_LITE_COLUMN 5
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/maartenwut/wasdat/keymaps/konstantin/rules.mk b/keyboards/maartenwut/wasdat/keymaps/konstantin/rules.mk
index 041d32114..c3a73fd84 100644
--- a/keyboards/maartenwut/wasdat/keymaps/konstantin/rules.mk
+++ b/keyboards/maartenwut/wasdat/keymaps/konstantin/rules.mk
@@ -3,6 +3,7 @@ BOOTMAGIC_ENABLE = no
COMMAND_ENABLE = yes
CONSOLE_ENABLE = yes
EXTRAKEY_ENABLE = yes
+GRAVE_ESC_ENABLE = no
MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
SPACE_CADET_ENABLE = no
diff --git a/keyboards/maartenwut/wasdat/keymaps/via/keymap.c b/keyboards/maartenwut/wasdat/keymaps/via/keymap.c
new file mode 100644
index 000000000..9ad78d60d
--- /dev/null
+++ b/keyboards/maartenwut/wasdat/keymaps/via/keymap.c
@@ -0,0 +1,96 @@
+/* Copyright 2020
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
+ * │Esc│   │F1 │F2 │F3 │F4 │ │F5 │F6 │F7 │F8 │ │F9 │F10│F11│F12│ │PSc│Slk│Pse│
+ * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│ │Num│ / │ * │ - │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │ │Del│End│PgD│ │ 7 │ 8 │ 9 │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
+ * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │               │ 4 │ 5 │ 6 │   │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
+ * │Shft│ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │    Shift │     │ ↑ │     │ 1 │ 2 │ 3 │   │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤Ent│
+ * │Ctrl│GUI │Alt │                        │ Alt│ GUI│FnMn│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │   │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
+ */
+ LAYOUT_all(
+ 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_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_PPLS,
+ 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_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_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, LT(1, KC_APP), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ ),
+
+ /*
+ * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
+ * │Rst│   │   │   │   │   │ │   │   │   │   │ │   │   │   │   │ │   │   │   │
+ * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
+ * │   │   │   │   │   │   │   │   │   │   │   │   │   │       │ │   │   │   │ │   │   │   │   │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │   │   │     │ │   │   │   │ │   │   │   │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤   │
+ * │      │   │   │   │   │   │   │   │   │   │   │   │        │               │   │   │   │   │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
+ * │    │   │   │   │   │   │   │   │   │   │   │   │          │     │   │     │   │   │   │   │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤   │
+ * │    │    │    │                        │    │    │    │    │ │   │   │   │ │       │   │   │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
+ */
+ LAYOUT_all(
+ RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /*
+ * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
+ * │   │   │   │   │   │   │ │   │   │   │   │ │   │   │   │   │ │   │   │   │
+ * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
+ * │   │   │   │   │   │   │   │   │   │   │   │   │   │       │ │   │   │   │ │   │   │   │   │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │   │   │     │ │   │   │   │ │   │   │   │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤   │
+ * │      │   │   │   │   │   │   │   │   │   │   │   │        │               │   │   │   │   │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
+ * │    │   │   │   │   │   │   │   │   │   │   │   │          │     │   │     │   │   │   │   │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤   │
+ * │    │    │    │                        │    │    │    │    │ │   │   │   │ │       │   │   │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
+ */
+ LAYOUT_all(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
diff --git a/keyboards/maartenwut/wasdat/keymaps/via/rules.mk b/keyboards/maartenwut/wasdat/keymaps/via/rules.mk
new file mode 100644
index 000000000..36b7ba9cb
--- /dev/null
+++ b/keyboards/maartenwut/wasdat/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
diff --git a/keyboards/maartenwut/wasdat/rules.mk b/keyboards/maartenwut/wasdat/rules.mk
index db9728623..822baf5ed 100644
--- a/keyboards/maartenwut/wasdat/rules.mk
+++ b/keyboards/maartenwut/wasdat/rules.mk
@@ -14,7 +14,7 @@ BOOTLOADER = qmk-dfu
# Build Options
# change yes to no to disable
#
-BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
diff --git a/keyboards/maartenwut/wasdat/wasdat.h b/keyboards/maartenwut/wasdat/wasdat.h
index d9f1f95a2..a25646b62 100644
--- a/keyboards/maartenwut/wasdat/wasdat.h
+++ b/keyboards/maartenwut/wasdat/wasdat.h
@@ -27,6 +27,25 @@
* The second converts the arguments into a two-dimensional array which
* represents the switch matrix.
*/
+#define LAYOUT_all( \
+ K05, K44, K42, K32, K02, K21, K0A, K3E, K4E, K4D, K2D, K0D, K7D, K23, K53, K51, \
+ K45, K25, K24, K22, K20, K40, K48, K28, K2A, K2E, K2F, K4F, K4A, K3D, K47, K4C, K46, K69, K67, K66, K76, \
+ K35, K55, K54, K52, K50, K30, K38, K58, K5A, K5E, K5F, K3F, K3A, K1D, K49, K2C, K26, K59, K57, K56, K5C, \
+ K34, K15, K14, K12, K10, K00, K08, K18, K1A, K1E, K1F, K0F, K6D, K39, K37, K36, \
+ K3B, K04, K65, K64, K62, K60, K70, K78, K68, K6A, K6E, K7F, K1B, K0C, K19, K17, K16, K1C, \
+ K41, K31, K03, K09, K73, K11, K33, K61, K7C, K79, K77, K07, K06 \
+) \
+{ \
+ { K00, XXX, K02, K03, K04, K05, K06, K07, K08, K09, K0A, XXX, K0C, K0D, XXX, K0F }, \
+ { K10, K11, K12, XXX, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F }, \
+ { K20, K21, K22, K23, K24, K25, K26, XXX, K28, XXX, K2A, XXX, K2C, K2D, K2E, K2F }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, XXX, K3D, K3E, K3F }, \
+ { K40, K41, K42, XXX, K44, K45, K46, K47, K48, K49, K4A, XXX, K4C, K4D, K4E, K4F }, \
+ { K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5A, XXX, K5C, XXX, K5E, K5F }, \
+ { K60, K61, K62, XXX, K64, K65, K66, K67, K68, K69, K6A, XXX, XXX, K6D, K6E, XXX }, \
+ { K70, XXX, XXX, K73, XXX, XXX, K76, K77, K78, K79, XXX, XXX, K7C, K7D, XXX, K7F } \
+}
+
#define LAYOUT_fullsize_ansi( \
K05, K44, K42, K32, K02, K21, K0A, K3E, K4E, K4D, K2D, K0D, K7D, K23, K53, K51, \
K45, K25, K24, K22, K20, K40, K48, K28, K2A, K2E, K2F, K4F, K4A, K3D, K47, K4C, K46, K69, K67, K66, K76, \
diff --git a/keyboards/massdrop/ctrl/keymaps/default/keymap.c b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
index 9f111725c..51b7f3931 100644
--- a/keyboards/massdrop/ctrl/keymaps/default/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
@@ -49,9 +49,9 @@ void matrix_init_user(void) {
void matrix_scan_user(void) {
};
-#define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
-#define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
-#define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
+#define MODS_SHIFT (get_mods() & MOD_MASK_SHIFT)
+#define MODS_CTRL (get_mods() & MOD_MASK_CTRL)
+#define MODS_ALT (get_mods() & MOD_MASK_ALT)
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
static uint32_t key_timer;
diff --git a/keyboards/melody96/keymaps/konstantin/rules.mk b/keyboards/melody96/keymaps/konstantin/rules.mk
index 995402cb0..5b36eef2c 100644
--- a/keyboards/melody96/keymaps/konstantin/rules.mk
+++ b/keyboards/melody96/keymaps/konstantin/rules.mk
@@ -3,6 +3,7 @@ BOOTMAGIC_ENABLE = no
COMMAND_ENABLE = yes
CONSOLE_ENABLE = no
EXTRAKEY_ENABLE = yes
+GRAVE_ESC_ENABLE = no
MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
RGBLIGHT_ENABLE = yes
diff --git a/keyboards/mint60/config.h b/keyboards/mint60/config.h
index 19a17a7c5..1b11092eb 100644
--- a/keyboards/mint60/config.h
+++ b/keyboards/mint60/config.h
@@ -148,6 +148,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGB_DI_PIN D3
#define RGBLED_NUM 8
+#define RGBLIGHT_SPLIT
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
diff --git a/keyboards/niu_mini/config.h b/keyboards/niu_mini/config.h
index be94fd9e7..84ccc6a68 100644
--- a/keyboards/niu_mini/config.h
+++ b/keyboards/niu_mini/config.h
@@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* USB Device descriptor parameter */
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x6060
+#define VENDOR_ID 0x6E6D
+#define PRODUCT_ID 0x0001
#define DEVICE_VER 0x0001
#define MANUFACTURER KBDFans
#define PRODUCT NIU Mini
diff --git a/keyboards/niu_mini/keymaps/via/keymap.c b/keyboards/niu_mini/keymaps/via/keymap.c
new file mode 100644
index 000000000..702e41994
--- /dev/null
+++ b/keyboards/niu_mini/keymaps/via/keymap.c
@@ -0,0 +1,79 @@
+#include QMK_KEYBOARD_H
+
+#define LOWER FN_MO13
+#define RAISE FN_MO23
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ /* Layer 0
+ * ,-----------------------------------------------------------------------------------.
+ * | 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 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Ctrl | GUI | Caps | Alt |Layer1| Space| Space|Layer2| Left | Down | Up |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+ [0] = LAYOUT_ortho_4x12(
+ 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,
+ KC_LCTL, KC_LGUI, KC_CAPS, KC_LALT, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
+ ),
+
+ /* Layer 1
+ * ,-----------------------------------------------------------------------------------.
+ * | ` | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | | Vol- | Vol+ | Mute | | | | F11 | F12 | | | |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | | | | | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Reset| | | | | | | | | | | |
+ * `-----------------------------------------------------------------------------------'
+ */
+ [1] = LAYOUT_ortho_4x12(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,
+ _______, KC_VOLD, KC_VOLU, KC_MUTE, _______, _______, _______, KC_F11, KC_F12, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /* Layer 2 (r_ Indicates RGB Controls)
+ * ,-----------------------------------------------------------------------------------.
+ * | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | |r_TOG |r_Mode|r_Hue+|r_Hue-| | | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | |BL_TOG|BL_STEP| | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | |
+ * `-----------------------------------------------------------------------------------'
+ */
+ [2] = LAYOUT_ortho_4x12(
+ _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
+ _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
+ _______, BL_TOGG, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /* Layer 3 (r_ Indicates RGB Controls)
+ * ,-----------------------------------------------------------------------------------.
+ * | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | |r_TOG |r_Mode|r_Hue+|r_Hue-| | | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | |BL_TOG|BL_STEP| | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | RESET| | | | | | | | | | | |
+ * `-----------------------------------------------------------------------------------'
+ */
+ [3] = LAYOUT_ortho_4x12(
+ _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
+ _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
+ _______, BL_TOGG, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+};
diff --git a/keyboards/niu_mini/keymaps/via/rules.mk b/keyboards/niu_mini/keymaps/via/rules.mk
new file mode 100644
index 000000000..43061db1d
--- /dev/null
+++ b/keyboards/niu_mini/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes \ No newline at end of file
diff --git a/keyboards/pancake/config.h b/keyboards/pancake/config.h
index a83ef5d0c..5a01a572e 100644
--- a/keyboards/pancake/config.h
+++ b/keyboards/pancake/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
@@ -20,7 +20,7 @@
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xB195
#define DEVICE_VER 0x0001
-#define MANUFACTURER rionlion100
+#define MANUFACTURER Spaceman
#define PRODUCT Pancake
#define DESCRIPTION Choc Ortho Keyboard
diff --git a/keyboards/pancake/feather/config.h b/keyboards/pancake/feather/config.h
index fbb175758..eac91a5ad 100644
--- a/keyboards/pancake/feather/config.h
+++ b/keyboards/pancake/feather/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/pancake/info.json b/keyboards/pancake/info.json
index c18e48b8b..6d2b2a9bb 100644
--- a/keyboards/pancake/info.json
+++ b/keyboards/pancake/info.json
@@ -2,7 +2,7 @@
"keyboard_name": "Pancake",
"keyboard_folder": "Pancake",
"url": "",
- "maintainer": "rionlion100",
+ "maintainer": "rionlion100 (Spaceman)",
"width": 12,
"height": 4,
"layouts": {
diff --git a/keyboards/pancake/pancake.c b/keyboards/pancake/pancake.c
index e01636016..d77dbfbe0 100644
--- a/keyboards/pancake/pancake.c
+++ b/keyboards/pancake/pancake.c
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/pancake/pancake.h b/keyboards/pancake/pancake.h
index cb7756996..312d789b4 100644
--- a/keyboards/pancake/pancake.h
+++ b/keyboards/pancake/pancake.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/pancake/promicro/config.h b/keyboards/pancake/promicro/config.h
index 3b65ced81..ee02bff2b 100644
--- a/keyboards/pancake/promicro/config.h
+++ b/keyboards/pancake/promicro/config.h
@@ -1,4 +1,4 @@
-/* Copyright 2019 Sebastian Williams
+/* Copyright 2019 Spaceman
*
* 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
diff --git a/keyboards/pancake/readme.md b/keyboards/pancake/readme.md
index bbf341b97..3e3125f4d 100644
--- a/keyboards/pancake/readme.md
+++ b/keyboards/pancake/readme.md
@@ -2,7 +2,7 @@
Ortho 40% Ortho Keyboard with an option for the adafruit feather
-Keyboard Maintainer: [Rionlion100](https://github.com/rionlion100)
+Keyboard Maintainer: Spaceman AKA:[Rionlion100](https://github.com/rionlion100)
Hardware Availability: [GB](https://geekhack.org/index.php?topic=101371.0)
Make example for this keyboard (after setting up your build environment):
diff --git a/keyboards/planck/keymaps/oeywil/.gitignore b/keyboards/planck/keymaps/oeywil/.gitignore
deleted file mode 100644
index 03b2b4666..000000000
--- a/keyboards/planck/keymaps/oeywil/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-secrets.h
diff --git a/keyboards/planck/keymaps/oeywil/config.h b/keyboards/planck/keymaps/oeywil/config.h
deleted file mode 100644
index 09b22e193..000000000
--- a/keyboards/planck/keymaps/oeywil/config.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#ifdef AUDIO_ENABLE
- #define STARTUP_SONG SONG(PLANCK_SOUND)
- // #define STARTUP_SONG SONG(NO_SOUND)
-#endif
-
-/*
- * MIDI options
- */
-
-/* Prevent use of disabled MIDI features in the keymap */
-//#define MIDI_ENABLE_STRICT 1
-
-/* enable basic MIDI features:
- - MIDI notes can be sent when in Music mode is on
-*/
-
-#define MIDI_BASIC
-
-/* enable advanced MIDI features:
- - MIDI notes can be added to the keymap
- - Octave shift and transpose
- - Virtual sustain, portamento, and modulation wheel
- - etc.
-*/
-//#define MIDI_ADVANCED
-
-/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
-//#define MIDI_TONE_KEYCODE_OCTAVES 2
-
-// Leader Key
-#define LEADER_TIMEOUT 250
-#define LEADER_PER_KEY_TIMING
-
-// Tap dance
-#define TAPPING_TERM 200
diff --git a/keyboards/planck/keymaps/oeywil/keymap.c b/keyboards/planck/keymaps/oeywil/keymap.c
deleted file mode 100644
index 59e76cab1..000000000
--- a/keyboards/planck/keymaps/oeywil/keymap.c
+++ /dev/null
@@ -1,392 +0,0 @@
-#include QMK_KEYBOARD_H
-#include "no_keycodes.h"
-
-#if __has_include("secrets.h")
-# include "secrets.h"
-#else
-# define mail_str ""
-# define pwd_str ""
-#endif
-
-// layer definitions
-enum planck_layers {
- _DEFAULT,
- _LOWER,
- _RAISE,
- _GAME,
- _GLOW
-};
-
-// sounds
-#ifdef AUDIO_ENABLE
- float gamesong[][2] = SONG(MARIO_MUSHROOM);
- float defsong[][2] = SONG(PLOVER_GOODBYE_SOUND);
- float failed[][2] = SONG(TERMINAL_SOUND);
-#endif
-
-// leader key
-bool leader_succeed;
-bool leader_layer_game;
-bool leader_layer_def;
-LEADER_EXTERNS();
-
-void matrix_scan_user(void) {
- LEADER_DICTIONARY() {
- leader_succeed = leading = false;
- leader_layer_game = false;
- leader_layer_def = false;
-
- SEQ_TWO_KEYS(KC_P, KC_P) {
- SEND_STRING(pwd_str);
- leader_succeed = true;
- }
- SEQ_TWO_KEYS(KC_P, KC_M) {
- SEND_STRING(mail_str);
- leader_succeed = true;
- }
- SEQ_TWO_KEYS(KC_B, KC_B) {
- SEND_STRING("build"SS_TAP(X_ENTER));
- leader_succeed = true;
- }
- SEQ_TWO_KEYS(KC_B, KC_F) {
- SEND_STRING("flash"SS_TAP(X_ENTER));
- reset_keyboard();
- leader_succeed = true;
- }
- SEQ_TWO_KEYS(KC_L, KC_G) {
- layer_on(_GAME);
- leader_layer_game = true;
- }
- SEQ_TWO_KEYS(KC_L, KC_D) {
- layer_off(_GAME);
- leader_layer_def = true;
- }
- leader_end();
- }
-}
-
-void leader_end(void) {
- if (leader_succeed) {
- // do nothing
- } else if (leader_layer_game) {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(gamesong);
- #endif
- } else if (leader_layer_def) {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(defsong);
- #endif
- } else {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(failed);
- #endif
- }
-}
-
-// tap dance definitions
-typedef struct {
- bool is_press_action;
- int state;
-} tap;
-
-enum {
- SINGLE_TAP = 1,
- SINGLE_HOLD = 2,
- DOUBLE_TAP = 3,
- DOUBLE_HOLD = 4,
- DOUBLE_SINGLE_TAP = 5,
- TRIPLE_TAP = 6,
- TRIPLE_HOLD = 7
-};
-
-enum {
- TD_LSFT = 0,
- TD_LCTL,
- TD_RSFT,
- TD_RCTL
-};
-
-int cur_dance (qk_tap_dance_state_t *state);
-void lsft_finished (qk_tap_dance_state_t *state, void *user_data);
-void lsft_reset (qk_tap_dance_state_t *state, void *user_data);
-void rsft_finished (qk_tap_dance_state_t *state, void *user_data);
-void rsft_reset (qk_tap_dance_state_t *state, void *user_data);
-void lctl_finished (qk_tap_dance_state_t *state, void *user_data);
-void lctl_reset (qk_tap_dance_state_t *state, void *user_data);
-void rctl_finished (qk_tap_dance_state_t *state, void *user_data);
-void rctl_reset (qk_tap_dance_state_t *state, void *user_data);
-
-// layer declarations
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* Default
- * ,-----------------------------------------------------------------------------------.
- * | Tab | Q | W | E | R | T | Y | U | I | O | Å | BkSp |
- * |------+------+------+------+------+-------------+------+------+------+------+------|
- * | Esc | A | S | D | F | G | H | J | K | L | Ø | Æ |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| Z | X | C | V | B | N | M | P | , | . | Shift|
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Ctrl | Lead | Win | Alt | Lower| Space| Enter| Raise| AltGr| App | Lead | Ctrl |
- * `-----------------------------------------------------------------------------------'
- */
- [_DEFAULT] = LAYOUT_planck_grid(
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, NO_AA, KC_BSPC,
- KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, NO_OE, NO_AE,
- TD(TD_LSFT), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_P, KC_COMM, KC_DOT, TD(TD_RSFT),
- TD(TD_LCTL), KC_LEAD, KC_LGUI, KC_LALT, MO(_LOWER), KC_SPC, KC_ENT, MO(_RAISE), KC_ALGR, KC_APP, KC_LEAD, TD(TD_RCTL)
- ),
- /* Lower
- * ,-----------------------------------------------------------------------------------.
- * | Tab | <Word| Up | Word>| PgUp | | | | F7 | F8 | F9 | Del |
- * |------+------+------+------+------+-------------+------+------+------+------+------|
- * | BkSp | Left | Down | Right| PgDn | | | | F4 | F5 | F6 | |
- * |------+------+------+------+------+------|------+------+------+------+------+------|
- * | Shift| Home | | End | | | | | F1 | F2 | F3 | Shift|
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Ctrl | | Win | Alt | Lower| M_PP |M_Next| | | Mute | VolD | VolUp|
- * `-----------------------------------------------------------------------------------'
- */
- [_LOWER] = LAYOUT_planck_grid(
- KC_TRNS, LCTL(KC_LEFT), KC_UP, LCTL(KC_RIGHT), KC_PGUP, KC_NO, KC_NO, KC_NO, KC_F7, KC_F8, KC_F9, KC_DEL,
- KC_BSPC, KC_LEFT, KC_DOWN, KC_RIGHT, KC_PGDN, KC_NO, KC_NO, KC_NO, KC_F4, KC_F5, KC_F6, KC_NO,
- KC_TRNS, KC_HOME, KC_NO, KC_END, KC_NO, KC_NO, KC_NO, KC_NO, KC_F1, KC_F2, KC_F3, KC_TRNS,
- KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_NO, KC_NO, KC_MUTE, KC_VOLD, KC_VOLU
- ),
- /* Raise
- * ,-----------------------------------------------------------------------------------.
- * | Tab | ! | ? | # | * | | | = | / | 7 | 8 | 9 | Ins |
- * |------+------+------+------+------+-------------+------+------+------+------+------|
- * | BkSp | @ | & | $ | % | ~ | + | \ | 4 | 5 | 6 | |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| ' | " | ¨ | | | - | 0 | 1 | 2 | 3 | Shift|
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Ctrl | | Win | Alt | | Space| Enter| Raise| AltGr| | | |
- * `-----------------------------------------------------------------------------------'
- */
- [_RAISE] = LAYOUT_planck_grid(
- KC_TRNS, NO_EXCL, NO_QEST, NO_HASH, NO_ASTE, NO_PIPE, NO_EQUA, NO_FSLS, KC_7, KC_8, KC_9, KC_INS,
- KC_BSPC, NO_ALFA, NO_AMPE, NO_USDO, NO_PERC, NO_TILD, NO_PLUS, NO_BSLS, KC_4, KC_5, KC_6, KC_NO,
- KC_TRNS, NO_APOS, NO_QUOT, NO_UMLA, KC_NO, KC_NO, NO_DASH, KC_0, KC_1, KC_2, KC_3, KC_TRNS,
- KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO
- ),
- /* Game
- * ,-----------------------------------------------------------------------------------.
- * | Tab | Q | W | E | R | T | Y | U | I | O | | BkSp |
- * |------+------+------+------+------+-------------+------+------+------+------+------|
- * | Esc | A | S | D | F | G | H | J | K | L | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| Z | X | C | V | B | N | M | P | , | . | |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Ctrl | Lead | | Alt | Lower| Space| Enter| Lower| | | Lead | |
- * `-----------------------------------------------------------------------------------'
- */
- [_GAME] = LAYOUT_planck_grid(
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_NO, KC_BSPC,
- KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_NO, KC_NO,
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_P, KC_COMM, KC_DOT, KC_NO,
- KC_LCTL, KC_LEAD, KC_NO, KC_LALT, MO(_GLOW), KC_SPC, KC_ENT, MO(_GLOW), KC_NO, KC_NO, KC_LEAD, KC_NO
- ),
- /* Game lower
- * ,-----------------------------------------------------------------------------------.
- * | Tab | 1 | 2 | 3 | | | | | | | | Steam|
- * |------+------+------+------+------+-------------+------+------+------+------+------|
- * | Esc | 4 | 5 | 6 | | | | | | | | F12 |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| 7 | 8 | 9 | 0 | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Ctrl | | | Alt | | PlyPa| Next | | | Mute | VolD | VolUp|
- * `-----------------------------------------------------------------------------------'
- */
- [_GLOW] = LAYOUT_planck_grid(
- KC_TRNS, KC_1, KC_2, KC_3, KC_PPLS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, LSFT(KC_F7),
- KC_TRNS, KC_4, KC_5, KC_6, KC_PMNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12,
- KC_TRNS, KC_7, KC_8, KC_9, KC_0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_MUTE,
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_NO, KC_TRNS, KC_MUTE, KC_VOLD, KC_VOLU
- )
-};
-
-// tap dance declarations
-int cur_dance (qk_tap_dance_state_t *state) {
- if (state->count == 1) {
- if (state->interrupted || !state->pressed) return SINGLE_TAP;
- else return SINGLE_HOLD;
- }
- else if (state->count == 2) {
- if (state->interrupted) return DOUBLE_SINGLE_TAP;
- else if (state->pressed) return DOUBLE_HOLD;
- else return DOUBLE_TAP;
- }
- if (state->count == 3) {
- if (state->interrupted || !state->pressed) return TRIPLE_TAP;
- else return TRIPLE_HOLD;
- }
- else return 8;
-}
-
-static tap xtap_state = {
- .is_press_action = true,
- .state = 0
-};
-
-void lsft_finished (qk_tap_dance_state_t *state, void *user_data) {
- xtap_state.state = cur_dance(state);
- switch (xtap_state.state) {
- case SINGLE_TAP:
- register_code16(LSFT(KC_8));
- break;
- case SINGLE_HOLD:
- register_code(KC_LSFT);
- break;
- case DOUBLE_TAP:
- register_code(KC_NUBS);
- break;
- case DOUBLE_SINGLE_TAP:
- register_code(KC_NUBS);
- break;
- }
-}
-
-void lsft_reset (qk_tap_dance_state_t *state, void *user_data) {
- switch (xtap_state.state) {
- case SINGLE_TAP:
- unregister_code16(LSFT(KC_8));
- break;
- case SINGLE_HOLD:
- unregister_code(KC_LSFT);
- break;
- case DOUBLE_TAP:
- unregister_code(KC_NUBS);
- break;
- case DOUBLE_SINGLE_TAP:
- unregister_code(KC_NUBS);
- break;
- }
- xtap_state.state = 0;
-}
-
-void rsft_finished (qk_tap_dance_state_t *state, void *user_data) {
- xtap_state.state = cur_dance(state);
- switch (xtap_state.state) {
- case SINGLE_TAP:
- register_code16(LSFT(KC_9));
- break;
- case SINGLE_HOLD:
- register_code(KC_RSFT);
- break;
- case DOUBLE_TAP:
- register_code16(LSFT(KC_NUBS));
- break;
- case DOUBLE_SINGLE_TAP:
- register_code16(LSFT(KC_NUBS));
- break;
- }
-}
-
-void rsft_reset (qk_tap_dance_state_t *state, void *user_data) {
- switch (xtap_state.state) {
- case SINGLE_TAP:
- unregister_code16(LSFT(KC_9));
- break;
- case SINGLE_HOLD:
- unregister_code(KC_RSFT);
- break;
- case DOUBLE_TAP:
- unregister_code16(LSFT(KC_NUBS));
- break;
- case DOUBLE_SINGLE_TAP:
- unregister_code16(LSFT(KC_NUBS));
- break;
- }
- xtap_state.state = 0;
-}
-
-void lctl_finished (qk_tap_dance_state_t *state, void *user_data) {
- xtap_state.state = cur_dance(state);
- switch (xtap_state.state) {
- case SINGLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_7);
- break;
- case SINGLE_HOLD:
- register_code(KC_LCTL);
- break;
- case DOUBLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_8);
- break;
- case DOUBLE_SINGLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_8);
-break;
- }
-}
-
-void lctl_reset (qk_tap_dance_state_t *state, void *user_data) {
- switch (xtap_state.state) {
- case SINGLE_TAP:
- unregister_code(KC_7);
- unregister_mods(MOD_BIT(KC_ALGR));
- break;
- case SINGLE_HOLD:
- unregister_code(KC_LCTL);
- break;
- case DOUBLE_TAP:
- unregister_code(KC_8);
- unregister_mods(MOD_BIT(KC_ALGR));
- break;
- case DOUBLE_SINGLE_TAP:
- unregister_code(KC_8);
- unregister_mods(MOD_BIT(KC_ALGR));
-break;
- }
- xtap_state.state = 0;
-}
-
-void rctl_finished (qk_tap_dance_state_t *state, void *user_data) {
- xtap_state.state = cur_dance(state);
- switch (xtap_state.state) {
- case SINGLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_0);
- break;
- case SINGLE_HOLD:
- register_code(KC_RCTL);
- break;
- case DOUBLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_9);
- break;
- case DOUBLE_SINGLE_TAP:
- register_mods(MOD_BIT(KC_ALGR));
- register_code(KC_9);
- break;
- }
-}
-
-void rctl_reset (qk_tap_dance_state_t *state, void *user_data) {
- switch (xtap_state.state) {
- case SINGLE_TAP:
- unregister_code(KC_0);
- unregister_mods(MOD_BIT(KC_ALGR));
- break;
- case SINGLE_HOLD:
- unregister_code(KC_RCTL);
- break;
- case DOUBLE_TAP:
- unregister_code(KC_9);
- unregister_mods(MOD_BIT(KC_ALGR));
- break;
- case DOUBLE_SINGLE_TAP:
- unregister_code(KC_9);
- unregister_mods(MOD_BIT(KC_ALGR));
- break;
- }
- xtap_state.state = 0;
-}
-
-qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_LSFT] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, lsft_finished, lsft_reset),
- [TD_RSFT] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, rsft_finished, rsft_reset),
- [TD_LCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, lctl_finished, lctl_reset),
- [TD_RCTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, rctl_finished, rctl_reset),
-};
diff --git a/keyboards/planck/keymaps/oeywil/no_keycodes.h b/keyboards/planck/keymaps/oeywil/no_keycodes.h
deleted file mode 100644
index c412c35d8..000000000
--- a/keyboards/planck/keymaps/oeywil/no_keycodes.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// øæå
-#define NO_OE KC_SCLN
-#define NO_AE KC_QUOT
-#define NO_AA KC_LBRC
-// rename
-#define NO_ANBR KC_NUBS
-#define NO_APOS KC_BSLS
-#define NO_BSLS KC_EQL
-#define NO_DASH KC_SLSH
-#define NO_PLUS KC_MINS
-#define NO_UMLA KC_RBRC
-#define NO_PIPE KC_GRV
-// shifted
-#define NO_EXCL LSFT(KC_1)
-#define NO_QUOT LSFT(KC_2)
-#define NO_HASH LSFT(KC_3)
-#define NO_PERC LSFT(KC_5)
-#define NO_AMPE LSFT(KC_6)
-#define NO_FSLS LSFT(KC_7)
-#define NO_LPAR LSFT(KC_8)
-#define NO_RPAR LSFT(KC_9)
-#define NO_EQUA LSFT(KC_0)
-#define NO_QEST LSFT(KC_MINS)
-#define NO_ASTE LSFT(KC_BSLS)
-// altgr
-#define NO_ALFA ALGR(KC_2)
-#define NO_USDO ALGR(KC_4)
-#define NO_TILD ALGR(KC_RBRC)
diff --git a/keyboards/planck/keymaps/oeywil/readme.md b/keyboards/planck/keymaps/oeywil/readme.md
deleted file mode 100644
index 364f9422c..000000000
--- a/keyboards/planck/keymaps/oeywil/readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-About
-------
-
-A simple Norwegian grid layout using Leader Key, Tap Dance and audio.
diff --git a/keyboards/planck/keymaps/oeywil/rules.mk b/keyboards/planck/keymaps/oeywil/rules.mk
deleted file mode 100644
index 23b261173..000000000
--- a/keyboards/planck/keymaps/oeywil/rules.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-SRC += muse.c
-
-# Build Options
-NKRO_ENABLE = yes
-EXTRAKEY_ENABLE = yes
-LEADER_ENABLE = yes
-TAP_DANCE_ENABLE = yes
-AUDIO_ENABLE = yes
-COMMAND_ENABLE = no
-CONSOLE_ENABLE = no
-MOUSEKEY_ENABLE = no
diff --git a/keyboards/projectkb/alice/alice.c b/keyboards/projectkb/alice/alice.c
index ca0c7da2b..b82e2050e 100644
--- a/keyboards/projectkb/alice/alice.c
+++ b/keyboards/projectkb/alice/alice.c
@@ -1,17 +1,17 @@
#include "alice.h"
void matrix_init_board(void){
- setPinOutput(A0);
- setPinOutput(A1);
- setPinOutput(A2);
+ setPinOutput(INDICATOR_PIN_0);
+ setPinOutput(INDICATOR_PIN_1);
+ setPinOutput(INDICATOR_PIN_2);
}
bool led_update_kb(led_t led_state) {
bool runDefault = led_update_user(led_state);
if (runDefault) {
- writePin(A0, !led_state.num_lock);
- writePin(A1, !led_state.caps_lock);
- writePin(A2, !led_state.scroll_lock);
+ writePin(INDICATOR_PIN_0, !led_state.num_lock);
+ writePin(INDICATOR_PIN_1, !led_state.caps_lock);
+ writePin(INDICATOR_PIN_2, !led_state.scroll_lock);
}
return runDefault;
}
diff --git a/keyboards/projectkb/alice/keymaps/keithlo/keymap.c b/keyboards/projectkb/alice/keymaps/keithlo/keymap.c
new file mode 100644
index 000000000..c6801308a
--- /dev/null
+++ b/keyboards/projectkb/alice/keymaps/keithlo/keymap.c
@@ -0,0 +1,43 @@
+/*
+Copyright 2012,2013 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 QMK_KEYBOARD_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 _BASE 0
+#define _FN1 1
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_default(
+ KC_ESC, KC_TILD, 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_DEL,
+ 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_BSPC,
+ KC_PGDN, 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_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RGUI,
+ KC_LCTL, KC_LCMD, KC_SPC, MO(_FN1), KC_RCMD, KC_RALT, KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_default(
+ RGB_TOG, _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_VOLD, KC_VOLU, _______, KC_MUTE,
+ RGB_MOD, _______, _______, KC_UP, _______, _______, _______, RGB_SAI, RGB_HUI, RGB_VAI, _______, KC_F11, KC_F12, _______, _______,
+ RGB_RMOD, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, KC_LEFT, KC_DOWN, KC_UP , KC_RIGHT, _______, _______, _______,
+ _______, BL_INC, BL_DEC, BL_TOGG, BL_BRTG, _______, RGB_SAD, RGB_HUD, RGB_VAD, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, RESET
+ )
+};
diff --git a/keyboards/projectkb/alice/readme.md b/keyboards/projectkb/alice/readme.md
index 583ddf592..193343b31 100644
--- a/keyboards/projectkb/alice/readme.md
+++ b/keyboards/projectkb/alice/readme.md
@@ -7,7 +7,7 @@ Keyboard Maintainer: onefiftynine
Hardware Supported: STM32F072CBT6
Make example for this keyboard (after setting up your build environment):
- make projectkb/alice:default
+ make projectkb/alice/rev2:default
If you are flashing this keyboard/pcb for the first time:
diff --git a/keyboards/projectkb/alice/config.h b/keyboards/projectkb/alice/rev1/config.h
index 11863b807..549af2928 100644
--- a/keyboards/projectkb/alice/config.h
+++ b/keyboards/projectkb/alice/rev1/config.h
@@ -58,6 +58,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define WS2812_SPI SPID2
#define WS2812_SPI_MOSI_PAL_MODE 0
+#define INDICATOR_PIN_0 A0
+#define INDICATOR_PIN_1 A1
+#define INDICATOR_PIN_2 A2
// 2 bits for 4 layout options
#define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 2
diff --git a/keyboards/projectkb/alice/rev1/rules.mk b/keyboards/projectkb/alice/rev1/rules.mk
new file mode 100644
index 000000000..258444db4
--- /dev/null
+++ b/keyboards/projectkb/alice/rev1/rules.mk
@@ -0,0 +1,27 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+WS2812_DRIVER = spi
+
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/projectkb/alice/rev2/config.h b/keyboards/projectkb/alice/rev2/config.h
new file mode 100644
index 000000000..eb3332026
--- /dev/null
+++ b/keyboards/projectkb/alice/rev2/config.h
@@ -0,0 +1,85 @@
+/*
+Copyright 2015 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/>.
+*/
+
+#pragma once
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x0159
+#define PRODUCT_ID 0xA71C
+#define DEVICE_VER 0x0001
+#define MANUFACTURER ProjectKB
+#define PRODUCT Alice
+#define DESCRIPTION ProjectKB Alice
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 16
+
+#define MATRIX_COL_PINS { B1, B0, A7, A1, A5, A4, A3, A10, B9, B8, B7, B6, B5, B4, B3, A15 }
+#define MATRIX_ROW_PINS { B2, B10, B11, A2, A0 }
+#define DIODE_DIRECTION COL2ROW
+
+#define BACKLIGHT_PIN A6
+#define BACKLIGHT_PWM_DRIVER PWMD3
+#define BACKLIGHT_PWM_CHANNEL 1
+#define BACKLIGHT_PAL_MODE 1
+#define BACKLIGHT_LEVELS 6
+#define BACKLIGHT_BREATHING
+#define BREATHING_PERIOD 6
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 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
+
+#define RGBLIGHT_ANIMATIONS
+#define RGB_DI_PIN B15
+#define RGBLED_NUM 14
+#define WS2812_SPI SPID2
+#define WS2812_SPI_MOSI_PAL_MODE 0
+
+#define INDICATOR_PIN_0 A9
+#define INDICATOR_PIN_1 A8
+#define INDICATOR_PIN_2 B12
+
+
+// 2 bits for 4 layout options
+#define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 2
+
+/*
+ * 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
diff --git a/keyboards/projectkb/alice/rev2/rules.mk b/keyboards/projectkb/alice/rev2/rules.mk
new file mode 100644
index 000000000..258444db4
--- /dev/null
+++ b/keyboards/projectkb/alice/rev2/rules.mk
@@ -0,0 +1,27 @@
+# MCU name
+MCU = STM32F072
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+WS2812_DRIVER = spi
+
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/projectkb/alice/rules.mk b/keyboards/projectkb/alice/rules.mk
index 0f9d71b89..d67257699 100644
--- a/keyboards/projectkb/alice/rules.mk
+++ b/keyboards/projectkb/alice/rules.mk
@@ -1,22 +1 @@
-# MCU name
-MCU = STM32F072
-
-# Build Options
-# comment out to disable the options.
-#
-
-BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = yes # Console for debug
-COMMAND_ENABLE = yes # Commands for debug and configuration
-SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
-NKRO_ENABLE = yes # USB Nkey Rollover
-CUSTOM_MATRIX = no # Custom matrix file
-BACKLIGHT_ENABLE = yes
-RGBLIGHT_ENABLE = yes
-WS2812_DRIVER = spi
-
-
-# Enter lower-power sleep mode when on the ChibiOS idle thread
-OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
+DEFAULT_FOLDER = projectkb/alice/rev1
diff --git a/keyboards/splitish/config.h b/keyboards/splitish/config.h
new file mode 100644
index 000000000..ec39d8fd4
--- /dev/null
+++ b/keyboards/splitish/config.h
@@ -0,0 +1,43 @@
+/*
+Copyright 2019 Reid Schneyer <reschneyer89@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/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6464
+#define DEVICE_VER 0x0001
+#define MANUFACTIRER Reid Schneyer
+#define PRODUCT Splitish
+#define DESCRIPTION Keyboard firmware for Splitish
+
+#define MATRIX_ROWS 4
+#define MATRIX_COLS 12
+
+#define MATRIX_COL_PINS { F4 , F5 , F6 , F7 , B1 , B3 , C6 , D4 , D0 , D1 , D2 , D3 }
+#define MATRIX_ROW_PINS { B4 , B5 , B2 , B6 }
+#define DIODE_DIRECTION COL2ROW
+#define UNUSED_PINS
+
+#define DEBOUNCE 5
+
+#define LOCKING_SUPPORT_ENABLE
+
+#define LOCKING_RESYNC_ENABLE
+
+
diff --git a/keyboards/splitish/keymaps/default/keymap.c b/keyboards/splitish/keymaps/default/keymap.c
new file mode 100644
index 000000000..470bad9b8
--- /dev/null
+++ b/keyboards/splitish/keymaps/default/keymap.c
@@ -0,0 +1,57 @@
+/*
+Copyright 2019 Reid Schneyer <reschneyer89@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 QMK_KEYBOARD_H
+
+//Layer definitions
+enum layers {
+ BASE,
+ NUMS,
+ SYMB,
+ FNS
+};
+
+enum custom_keycodes {
+ QWERTY = SAFE_RANGE,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT(
+ 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_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
+ KC_ESC, KC_LGUI, KC_LALT, KC_LALT, MO(FNS), LT(SYMB, KC_SPC), LT(NUMS, KC_SPC), MO(FNS), KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT
+ ),
+ [NUMS] = LAYOUT(
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+ [SYMB] = LAYOUT(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, 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,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+ [FNS] = LAYOUT(
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_VOLU, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_DEL,
+ KC_TRNS, KC_F5, KC_F6, KC_F7, KC_F8, KC_MPLY, KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_F9, KC_F10, KC_F11, KC_F12, KC_VOLD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END
+ )
+};
diff --git a/keyboards/splitish/keymaps/default/readme.md b/keyboards/splitish/keymaps/default/readme.md
new file mode 100644
index 000000000..112456db1
--- /dev/null
+++ b/keyboards/splitish/keymaps/default/readme.md
@@ -0,0 +1,4 @@
+# The default keymap for splitish
+This is the default keymap for splitish
+
+![splitish default layout](https://i.imgur.com/n0n9pns.png)
diff --git a/keyboards/splitish/readme.md b/keyboards/splitish/readme.md
new file mode 100644
index 000000000..e3870adcb
--- /dev/null
+++ b/keyboards/splitish/readme.md
@@ -0,0 +1,18 @@
+# splitish
+![splitish](https://i.imgur.com/6gnYPIp.jpg)
+
+A separated 4x12 ortho Kailh Choc keyboard
+
+Keyboard Maintainer: [Reid Schneyer](https://github.com/RSchneyer)
+
+Hardware Supported: Splitish PCB, Pro Micro
+
+Hardware Avaiability: [Gerber files](https://github.com/RSchneyer/splitish/tree/master/gerbers)
+
+Make example for splitish (after setting up your build environment):
+
+ make splitish:default
+
+See [build environment setup](https://docs.qmk.fm/install-build-tools) then the [make instructions](https://docs.qmk.fm/faq/build-compile-qmk) for more information.
+
+Please see [RSchneyer/splitish](https://www.github.com/RSchneyer/splitish) for **build instructions**, parts lists, and Gerber files.
diff --git a/keyboards/splitish/rules.mk b/keyboards/splitish/rules.mk
new file mode 100644
index 000000000..4cba00bcc
--- /dev/null
+++ b/keyboards/splitish/rules.mk
@@ -0,0 +1,23 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = caterina
+
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+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 = yes # USB Nkey Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
diff --git a/keyboards/splitish/splitish.c b/keyboards/splitish/splitish.c
new file mode 100644
index 000000000..b831a68c6
--- /dev/null
+++ b/keyboards/splitish/splitish.c
@@ -0,0 +1 @@
+#include "splitish.h"
diff --git a/keyboards/splitish/splitish.h b/keyboards/splitish/splitish.h
new file mode 100644
index 000000000..ff5a7d841
--- /dev/null
+++ b/keyboards/splitish/splitish.h
@@ -0,0 +1,14 @@
+#include "quantum.h"
+
+#define LAYOUT( \
+ 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 \
+) \
+{ \
+ {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} \
+}
diff --git a/keyboards/tgr/jane/config.h b/keyboards/tgr/jane/config.h
index 5fb9a9056..ed8b39c38 100644
--- a/keyboards/tgr/jane/config.h
+++ b/keyboards/tgr/jane/config.h
@@ -19,8 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
-#define VENDOR_ID 0x20A0
-#define PRODUCT_ID 0x422D
+#define VENDOR_ID 0x5447 // TG
+#define PRODUCT_ID 0x4A4E // JN
#define DEVICE_VER 0x0200
#define MANUFACTURER TGR
#define PRODUCT Jane
diff --git a/keyboards/tgr/jane/info.json b/keyboards/tgr/jane/info.json
index 6fab4db1e..000fda24f 100644
--- a/keyboards/tgr/jane/info.json
+++ b/keyboards/tgr/jane/info.json
@@ -13,8 +13,16 @@
"layout": [{"x":0, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":6.5, "y":0}, {"x":7.5, "y":0}, {"x":8.5, "y":0}, {"x":9.5, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":15.25, "y":0}, {"x":16.25, "y":0}, {"x":17.25, "y":0}, {"x":0, "y":1.5}, {"x":1, "y":1.5}, {"x":2, "y":1.5}, {"x":3, "y":1.5}, {"x":4, "y":1.5}, {"x":5, "y":1.5}, {"x":6, "y":1.5}, {"x":7, "y":1.5}, {"x":8, "y":1.5}, {"x":9, "y":1.5}, {"x":10, "y":1.5}, {"x":11, "y":1.5}, {"x":12, "y":1.5}, {"x":13, "y":1.5, "w":2}, {"x":15.25, "y":1.5}, {"x":16.25, "y":1.5}, {"x":17.25, "y":1.5}, {"x":0, "y":2.5, "w":1.5}, {"x":1.5, "y":2.5}, {"x":2.5, "y":2.5}, {"x":3.5, "y":2.5}, {"x":4.5, "y":2.5}, {"x":5.5, "y":2.5}, {"x":6.5, "y":2.5}, {"x":7.5, "y":2.5}, {"x":8.5, "y":2.5}, {"x":9.5, "y":2.5}, {"x":10.5, "y":2.5}, {"x":11.5, "y":2.5}, {"x":12.5, "y":2.5}, {"x":13.5, "y":2.5, "w":1.5}, {"x":15.25, "y":2.5}, {"x":16.25, "y":2.5}, {"x":17.25, "y":2.5}, {"x":0, "y":3.5, "w":1.75}, {"x":1.75, "y":3.5}, {"x":2.75, "y":3.5}, {"x":3.75, "y":3.5}, {"x":4.75, "y":3.5}, {"x":5.75, "y":3.5}, {"x":6.75, "y":3.5}, {"x":7.75, "y":3.5}, {"x":8.75, "y":3.5}, {"x":9.75, "y":3.5}, {"x":10.75, "y":3.5}, {"x":11.75, "y":3.5}, {"x":12.75, "y":3.5, "w":2.25}, {"x":0, "y":4.5, "w":2.25}, {"x":2.25, "y":4.5}, {"x":3.25, "y":4.5}, {"x":4.25, "y":4.5}, {"x":5.25, "y":4.5}, {"x":6.25, "y":4.5}, {"x":7.25, "y":4.5}, {"x":8.25, "y":4.5}, {"x":9.25, "y":4.5}, {"x":10.25, "y":4.5}, {"x":11.25, "y":4.5}, {"x":12.25, "y":4.5, "w":2.75}, {"x":16.25, "y":4.5}, {"x":0, "y":5.5, "w":1.25}, {"x":1.25, "y":5.5, "w":1.25}, {"x":2.5, "y":5.5, "w":1.25}, {"x":3.75, "y":5.5, "w":6.25}, {"x":10, "y":5.5, "w":1.25}, {"x":11.25, "y":5.5, "w":1.25}, {"x":12.5, "y":5.5, "w":1.25}, {"x":13.75, "y":5.5, "w":1.25}, {"x":15.25, "y":5.5}, {"x":16.25, "y":5.5}, {"x":17.25, "y":5.5}]
},
+ "LAYOUT_tkl_ansi_tsangan": {
+ "layout": [{"x":0, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":6.5, "y":0}, {"x":7.5, "y":0}, {"x":8.5, "y":0}, {"x":9.5, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":15.25, "y":0}, {"x":16.25, "y":0}, {"x":17.25, "y":0}, {"x":0, "y":1.25}, {"x":1, "y":1.25}, {"x":2, "y":1.25}, {"x":3, "y":1.25}, {"x":4, "y":1.25}, {"x":5, "y":1.25}, {"x":6, "y":1.25}, {"x":7, "y":1.25}, {"x":8, "y":1.25}, {"x":9, "y":1.25}, {"x":10, "y":1.25}, {"x":11, "y":1.25}, {"x":12, "y":1.25}, {"x":13, "y":1.25, "w":2}, {"x":15.25, "y":1.25}, {"x":16.25, "y":1.25}, {"x":17.25, "y":1.25}, {"x":0, "y":2.25, "w":1.5}, {"x":1.5, "y":2.25}, {"x":2.5, "y":2.25}, {"x":3.5, "y":2.25}, {"x":4.5, "y":2.25}, {"x":5.5, "y":2.25}, {"x":6.5, "y":2.25}, {"x":7.5, "y":2.25}, {"x":8.5, "y":2.25}, {"x":9.5, "y":2.25}, {"x":10.5, "y":2.25}, {"x":11.5, "y":2.25}, {"x":12.5, "y":2.25}, {"x":13.5, "y":2.25, "w":1.5}, {"x":15.25, "y":2.25}, {"x":16.25, "y":2.25}, {"x":17.25, "y":2.25}, {"x":0, "y":3.25, "w":1.75}, {"x":1.75, "y":3.25}, {"x":2.75, "y":3.25}, {"x":3.75, "y":3.25}, {"x":4.75, "y":3.25}, {"x":5.75, "y":3.25}, {"x":6.75, "y":3.25}, {"x":7.75, "y":3.25}, {"x":8.75, "y":3.25}, {"x":9.75, "y":3.25}, {"x":10.75, "y":3.25}, {"x":11.75, "y":3.25}, {"x":12.75, "y":3.25, "w":2.25}, {"x":0, "y":4.25, "w":2.25}, {"x":2.25, "y":4.25}, {"x":3.25, "y":4.25}, {"x":4.25, "y":4.25}, {"x":5.25, "y":4.25}, {"x":6.25, "y":4.25}, {"x":7.25, "y":4.25}, {"x":8.25, "y":4.25}, {"x":9.25, "y":4.25}, {"x":10.25, "y":4.25}, {"x":11.25, "y":4.25}, {"x":12.25, "y":4.25, "w":1.75}, {"x":14, "y":4.25}, {"x":16.25, "y":4.25}, {"x":0, "y":5.25, "w":1.5}, {"x":1.5, "y":5.25}, {"x":2.5, "y":5.25, "w":1.5}, {"x":4, "y":5.25, "w":7}, {"x":11, "y":5.25, "w":1.5}, {"x":12.5, "y":5.25}, {"x":13.5, "y":5.25, "w":1.5}, {"x":15.25, "y":5.25}, {"x":16.25, "y":5.25}, {"x":17.25, "y":5.25}]
+ },
+
"LAYOUT_tkl_iso": {
"layout": [{"x":0, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":6.5, "y":0}, {"x":7.5, "y":0}, {"x":8.5, "y":0}, {"x":9.5, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":15.25, "y":0}, {"x":16.25, "y":0}, {"x":17.25, "y":0}, {"x":0, "y":1.5}, {"x":1, "y":1.5}, {"x":2, "y":1.5}, {"x":3, "y":1.5}, {"x":4, "y":1.5}, {"x":5, "y":1.5}, {"x":6, "y":1.5}, {"x":7, "y":1.5}, {"x":8, "y":1.5}, {"x":9, "y":1.5}, {"x":10, "y":1.5}, {"x":11, "y":1.5}, {"x":12, "y":1.5}, {"x":13, "y":1.5, "w":2}, {"x":15.25, "y":1.5}, {"x":16.25, "y":1.5}, {"x":17.25, "y":1.5}, {"x":0, "y":2.5, "w":1.5}, {"x":1.5, "y":2.5}, {"x":2.5, "y":2.5}, {"x":3.5, "y":2.5}, {"x":4.5, "y":2.5}, {"x":5.5, "y":2.5}, {"x":6.5, "y":2.5}, {"x":7.5, "y":2.5}, {"x":8.5, "y":2.5}, {"x":9.5, "y":2.5}, {"x":10.5, "y":2.5}, {"x":11.5, "y":2.5}, {"x":12.5, "y":2.5}, {"x":15.25, "y":2.5}, {"x":16.25, "y":2.5}, {"x":17.25, "y":2.5}, {"x":0, "y":3.5, "w":1.75}, {"x":1.75, "y":3.5}, {"x":2.75, "y":3.5}, {"x":3.75, "y":3.5}, {"x":4.75, "y":3.5}, {"x":5.75, "y":3.5}, {"x":6.75, "y":3.5}, {"x":7.75, "y":3.5}, {"x":8.75, "y":3.5}, {"x":9.75, "y":3.5}, {"x":10.75, "y":3.5}, {"x":11.75, "y":3.5}, {"x":12.75, "y":3.5}, {"x":13.75, "y":2.5, "w":1.25, "h":2}, {"x":0, "y":4.5, "w":1.25}, {"x":1.25, "y":4.5}, {"x":2.25, "y":4.5}, {"x":3.25, "y":4.5}, {"x":4.25, "y":4.5}, {"x":5.25, "y":4.5}, {"x":6.25, "y":4.5}, {"x":7.25, "y":4.5}, {"x":8.25, "y":4.5}, {"x":9.25, "y":4.5}, {"x":10.25, "y":4.5}, {"x":11.25, "y":4.5}, {"x":12.25, "y":4.5, "w":2.75}, {"x":16.25, "y":4.5}, {"x":0, "y":5.5, "w":1.25}, {"x":1.25, "y":5.5, "w":1.25}, {"x":2.5, "y":5.5, "w":1.25}, {"x":3.75, "y":5.5, "w":6.25}, {"x":10, "y":5.5, "w":1.25}, {"x":11.25, "y":5.5, "w":1.25}, {"x":12.5, "y":5.5, "w":1.25}, {"x":13.75, "y":5.5, "w":1.25}, {"x":15.25, "y":5.5}, {"x":16.25, "y":5.5}, {"x":17.25, "y":5.5}]
+ },
+
+ "LAYOUT_tkl_iso_tsangan": {
+ "layout": [{"x":0, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":6.5, "y":0}, {"x":7.5, "y":0}, {"x":8.5, "y":0}, {"x":9.5, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":15.25, "y":0}, {"x":16.25, "y":0}, {"x":17.25, "y":0}, {"x":0, "y":1.25}, {"x":1, "y":1.25}, {"x":2, "y":1.25}, {"x":3, "y":1.25}, {"x":4, "y":1.25}, {"x":5, "y":1.25}, {"x":6, "y":1.25}, {"x":7, "y":1.25}, {"x":8, "y":1.25}, {"x":9, "y":1.25}, {"x":10, "y":1.25}, {"x":11, "y":1.25}, {"x":12, "y":1.25}, {"x":13, "y":1.25, "w":2}, {"x":15.25, "y":1.25}, {"x":16.25, "y":1.25}, {"x":17.25, "y":1.25}, {"x":0, "y":2.25, "w":1.5}, {"x":1.5, "y":2.25}, {"x":2.5, "y":2.25}, {"x":3.5, "y":2.25}, {"x":4.5, "y":2.25}, {"x":5.5, "y":2.25}, {"x":6.5, "y":2.25}, {"x":7.5, "y":2.25}, {"x":8.5, "y":2.25}, {"x":9.5, "y":2.25}, {"x":10.5, "y":2.25}, {"x":11.5, "y":2.25}, {"x":12.5, "y":2.25}, {"x":13.75, "y":2.25, "w":1.25, "h":2}, {"x":15.25, "y":2.25}, {"x":16.25, "y":2.25}, {"x":17.25, "y":2.25}, {"x":0, "y":3.25, "w":1.75}, {"x":1.75, "y":3.25}, {"x":2.75, "y":3.25}, {"x":3.75, "y":3.25}, {"x":4.75, "y":3.25}, {"x":5.75, "y":3.25}, {"x":6.75, "y":3.25}, {"x":7.75, "y":3.25}, {"x":8.75, "y":3.25}, {"x":9.75, "y":3.25}, {"x":10.75, "y":3.25}, {"x":11.75, "y":3.25}, {"x":12.75, "y":3.25}, {"x":0, "y":4.25, "w":1.25}, {"x":1.25, "y":4.25}, {"x":2.25, "y":4.25}, {"x":3.25, "y":4.25}, {"x":4.25, "y":4.25}, {"x":5.25, "y":4.25}, {"x":6.25, "y":4.25}, {"x":7.25, "y":4.25}, {"x":8.25, "y":4.25}, {"x":9.25, "y":4.25}, {"x":10.25, "y":4.25}, {"x":11.25, "y":4.25}, {"x":12.25, "y":4.25, "w":1.75}, {"x":14, "y":4.25}, {"x":16.25, "y":4.25}, {"x":0, "y":5.25, "w":1.5}, {"x":1.5, "y":5.25}, {"x":2.5, "y":5.25, "w":1.5}, {"x":4, "y":5.25, "w":7}, {"x":11, "y":5.25, "w":1.5}, {"x":12.5, "y":5.25}, {"x":13.5, "y":5.25, "w":1.5}, {"x":15.25, "y":5.25}, {"x":16.25, "y":5.25}, {"x":17.25, "y":5.25}]
}
}
}
diff --git a/keyboards/tgr/jane/jane.h b/keyboards/tgr/jane/jane.h
index 2008d49d9..9691ea589 100644
--- a/keyboards/tgr/jane/jane.h
+++ b/keyboards/tgr/jane/jane.h
@@ -58,6 +58,24 @@
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k7C, k7D, k7E }, \
}
+#define LAYOUT_tkl_ansi_tsangan( \
+ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k6B, \
+ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k6C, k6D, k6E, \
+ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k7C, k7D, k7E, \
+ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3D, \
+ k40, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k2E, \
+ k50, k51, k52, k55, k58, k59, k5A, k5E, k3E, k4E \
+){ \
+ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E }, \
+ { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, KC_NO }, \
+ { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E }, \
+ { k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, KC_NO, k3D, k3E }, \
+ { k40, KC_NO, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E }, \
+ { k50, k51, k52, KC_NO, KC_NO, k55, KC_NO, KC_NO, k58, k59, k5A, KC_NO, KC_NO, KC_NO, k5E }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k6B, k6C, k6D, k6E }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k7C, k7D, k7E }, \
+}
+
#define LAYOUT_tkl_iso( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k6B, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k6C, k6D, k6E, \
@@ -75,3 +93,21 @@
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k6B, k6C, k6D, k6E }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k7C, k7D, k7E }, \
}
+
+#define LAYOUT_tkl_iso_tsangan( \
+ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k6B, \
+ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k6C, k6D, k6E, \
+ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k7C, k7D, k7E, \
+ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, \
+ k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k2E, \
+ k50, k51, k52, k55, k58, k59, k5A, k5E, k3E, k4E \
+){ \
+ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E }, \
+ { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, KC_NO }, \
+ { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, KC_NO, k2E }, \
+ { k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E }, \
+ { k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E }, \
+ { k50, k51, k52, KC_NO, KC_NO, k55, KC_NO, KC_NO, k58, k59, k5A, KC_NO, KC_NO, KC_NO, k5E }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k6B, k6C, k6D, k6E }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k7C, k7D, k7E }, \
+}
diff --git a/keyboards/tgr/jane/keymaps/via/config.h b/keyboards/tgr/jane/keymaps/via/config.h
new file mode 100644
index 000000000..0865e4520
--- /dev/null
+++ b/keyboards/tgr/jane/keymaps/via/config.h
@@ -0,0 +1 @@
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/tgr/jane/keymaps/via/keymap.c b/keyboards/tgr/jane/keymaps/via/keymap.c
new file mode 100644
index 000000000..521a78f60
--- /dev/null
+++ b/keyboards/tgr/jane/keymaps/via/keymap.c
@@ -0,0 +1,43 @@
+/* Copyright 2020 MechMerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+[0] = LAYOUT_tkl_ansi(
+ 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_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_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_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI, KC_APP,KC_RCTL, KC_LEFT,KC_DOWN,KC_RGHT),
+
+[1] = LAYOUT_tkl_ansi(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 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] = LAYOUT_tkl_ansi(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS),
+};
diff --git a/keyboards/tgr/jane/keymaps/via/rules.mk b/keyboards/tgr/jane/keymaps/via/rules.mk
new file mode 100644
index 000000000..97010a994
--- /dev/null
+++ b/keyboards/tgr/jane/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/tkc1800/keymaps/yanfali/rules.mk b/keyboards/tkc1800/keymaps/yanfali/rules.mk
new file mode 100644
index 000000000..b595964f7
--- /dev/null
+++ b/keyboards/tkc1800/keymaps/yanfali/rules.mk
@@ -0,0 +1 @@
+OLED_DRIVER_ENABLE = no
diff --git a/keyboards/walletburner/neuron/info.json b/keyboards/walletburner/neuron/info.json
index 4ea4bcb94..9c0b4e2ef 100644
--- a/keyboards/walletburner/neuron/info.json
+++ b/keyboards/walletburner/neuron/info.json
@@ -6,7 +6,7 @@
"height": 4,
"layouts": {
"LAYOUT": {
- "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O\u2191", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"Back<br>Space", "x":11, "y":0}, {"label":"Ctrl", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K\u2190", "x":8.25, "y":1}, {"label":"L\u2192", "x":9.25, "y":1}, {"label":"Enter", "x":10.25, "y":1, "w":1.75}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<\u2193,", "x":8.75, "y":2}, {"label":">.", "x":9.75, "y":2}, {"label":"Fn", "x":10.75, "y":2, "w":1.25}, {"label":"Super", "x":1, "y":3}, {"label":"Meta", "x":2, "y":3, "w":1.5}, {"x":3.5, "y":3, "w":2.25}, {"x":5.75, "y":3, "w":2.75}, {"label":"Meta", "x":8.5, "y":3, "w":1.5}, {"label":"Alt Gr", "x":10, "y":3}]
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"Back<br>Space", "x":11, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":"Enter", "x":10.25, "y":1, "w":1.75}, {"label":"Shift", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":"Shift", "x":9.75, "y":2, "w":1.25}, {"label":"Fn", "x":11, "y":2}, {"label":"Hyper", "x":1, "y":3, "w":1.25}, {"label":"Super", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":1.75}, {"x":5.25, "y":3}, {"x":6.25, "y":3, "w":2.25}, {"label":"Meta", "x":8.5, "y":3, "w":1.25}, {"label":"Super", "x":9.75, "y":3, "w":1.25}]
}
}
-} \ No newline at end of file
+}
diff --git a/keyboards/wheatfield/split75/README.md b/keyboards/wheatfield/split75/README.md
new file mode 100644
index 000000000..ec8c7ee9e
--- /dev/null
+++ b/keyboards/wheatfield/split75/README.md
@@ -0,0 +1,28 @@
+# split75
+
+![split75](https://i1.wp.com/mechboards.co.uk/wp-content/uploads/2019/10/HTB1qf0aSOLaK1RjSZFxq6ymPFXae.jpg)
+
+This is a port of the QMK firmware for the split75 keyboard, also known as the ve.a taobao split clone. It runs on
+ps2avrGB firmware, like the [ps2avrGB keyboard](https://www.keyclack.com/product/gb-ps2avrgb/) or the ones sold
+by [Winkeyless](http://winkeyless.kr/product/ps2avrgb-parts/).
+
+Original work performed by Michael L. Walker, all credit goes to him. I've tidied up the keymap (removed 3 extra keys), a couple of functions, info.json and this Readme.
+
+* Keyboard Maintainer: [Michael L. Walker](https://github.com/walkerstop)
+* Hardware Availability: https://a.aliexpress.com/_BT9raf https://item.taobao.com/item.htm?id=556970472669&toSite=main
+
+Make example for this keyboard (after setting up your build environment):
+
+ make wheatfield/split75:default
+
+Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid))
+
+ make wheatfield/split75:default:flash
+
+or
+
+ bootloadHID -r split75_default.hex
+
+**Reset Key**: Hold down the key located at 3rd left position in the bottom row, commonly programmed as Left Control while plugging in the keyboard.
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/wheatfield/split75/config.h b/keyboards/wheatfield/split75/config.h
new file mode 100644
index 000000000..ccc6a9c44
--- /dev/null
+++ b/keyboards/wheatfield/split75/config.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#define VENDOR_ID 0x594D
+#define PRODUCT_ID 0x0001
+#define DEVICE_VER 0x0001
+#define MANUFACTURER YMDK
+#define PRODUCT Split75
+#define DESCRIPTION VE.A Clone
+
+/* matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 14
+
+#define RGBLED_NUM 8
+#define RGBLIGHT_ANIMATIONS
+#define RGBLIGHT_SLEEP
+
+#define BACKLIGHT_PIN D4
diff --git a/keyboards/wheatfield/split75/info.json b/keyboards/wheatfield/split75/info.json
new file mode 100644
index 000000000..1524f2124
--- /dev/null
+++ b/keyboards/wheatfield/split75/info.json
@@ -0,0 +1,12 @@
+{
+ "keyboard_name": "split75",
+ "url": "",
+ "maintainer": "Michael L. Walker",
+ "width": 19.25,
+ "height": 6,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [{"label":"ESC", "x":2.25, "y":0}, {"label":"F1", "x":3.25, "y":0}, {"label":"F2", "x":4.25, "y":0}, {"label":"F3", "x":5.25, "y":0}, {"label":"F4", "x":6.25, "y":0}, {"label":"F5", "x":7.25, "y":0}, {"label":"F6", "x":8.25, "y":0}, {"label":"F7", "x":10.25, "y":0}, {"label":"F8", "x":11.25, "y":0}, {"label":"F9", "x":12.25, "y":0}, {"label":"F10", "x":13.25, "y":0}, {"label":"F11", "x":14.25, "y":0}, {"label":"F12", "x":15.25, "y":0}, {"label":"Prt", "x":16.25, "y":0}, {"label":"Ins", "x":17.25, "y":0}, {"label":"Del", "x":18.25, "y":0}, {"label":"8", "x":0, "y":1}, {"label":"9", "x":1, "y":1}, {"label":"~", "x":2.25, "y":1}, {"label":"!", "x":3.25, "y":1}, {"label":"@", "x":4.25, "y":1}, {"label":"#", "x":5.25, "y":1}, {"label":"$", "x":6.25, "y":1}, {"label":"%", "x":7.25, "y":1}, {"label":"^", "x":8.25, "y":1}, {"label":"&", "x":10.25, "y":1}, {"label":"*", "x":11.25, "y":1}, {"label":"(", "x":12.25, "y":1}, {"label":")", "x":13.25, "y":1}, {"label":"_", "x":14.25, "y":1}, {"label":"+", "x":15.25, "y":1}, {"label":"Backspace", "x":16.25, "y":1, "w":2}, {"label":"Home", "x":18.25, "y":1}, {"label":"6", "x":0, "y":2}, {"label":"7", "x":1, "y":2}, {"label":"Tab", "x":2.25, "y":2, "w":1.5}, {"label":"Q", "x":3.75, "y":2}, {"label":"W", "x":4.75, "y":2}, {"label":"E", "x":5.75, "y":2}, {"label":"R", "x":6.75, "y":2}, {"label":"T", "x":7.75, "y":2}, {"label":"Y", "x":9.75, "y":2}, {"label":"U", "x":10.75, "y":2}, {"label":"I", "x":11.75, "y":2}, {"label":"O", "x":12.75, "y":2}, {"label":"P", "x":13.75, "y":2}, {"label":"{", "x":14.75, "y":2}, {"label":"}", "x":15.75, "y":2}, {"label":"|", "x":16.75, "y":2, "w":1.5}, {"label":"PgUp", "x":18.25, "y":2}, {"label":"4", "x":0, "y":3}, {"label":"5", "x":1, "y":3}, {"label":"Caps Lock", "x":2.25, "y":3, "w":1.75}, {"label":"A", "x":4, "y":3}, {"label":"S", "x":5, "y":3}, {"label":"D", "x":6, "y":3}, {"label":"F", "x":7, "y":3}, {"label":"G", "x":8, "y":3}, {"label":"H", "x":10, "y":3}, {"label":"J", "x":11, "y":3}, {"label":"K", "x":12, "y":3}, {"label":"L", "x":13, "y":3}, {"label":":", "x":14, "y":3}, {"label":"\"", "x":15, "y":3}, {"label":"Enter", "x":16, "y":3, "w":2.25}, {"label":"PgDn", "x":18.25, "y":3}, {"label":"2", "x":0, "y":4}, {"label":"3", "x":1, "y":4}, {"label":"Shift", "x":2.25, "y":4, "w":2.25}, {"label":"Z", "x":4.5, "y":4}, {"label":"X", "x":5.5, "y":4}, {"label":"C", "x":6.5, "y":4}, {"label":"V", "x":7.5, "y":4}, {"label":"B", "x":8.5, "y":4}, {"label":"N", "x":10.5, "y":4}, {"label":"M", "x":11.5, "y":4}, {"label":"<", "x":12.5, "y":4}, {"label":">", "x":13.5, "y":4}, {"label":"?", "x":14.5, "y":4}, {"label":"Shift", "x":15.5, "y":4, "w":1.75}, {"label":"\u2191", "x":17.25, "y":4}, {"label":"End", "x":18.25, "y":4}, {"label":"0", "x":0, "y":5}, {"label":"1", "x":1, "y":5}, {"label":"Ctrl", "x":2.25, "y":5, "w":1.25}, {"label":"Win", "x":3.5, "y":5, "w":1.25}, {"label":"Alt", "x":4.75, "y":5, "w":1.25}, {"x":6, "y":5, "w":2}, {"x":8, "y":5}, {"x":10, "y":5, "w":2.75}, {"label":"Alt", "x":12.75, "y":5, "w":1.25}, {"label":"Fn", "x":14, "y":5}, {"label":"Ctrl", "x":15, "y":5, "w":1.25}, {"label":"\u2190", "x":16.25, "y":5}, {"label":"\u2193", "x":17.25, "y":5}, {"label":"\u2192", "x":18.25, "y":5}]
+ }
+ }
+} \ No newline at end of file
diff --git a/keyboards/wheatfield/split75/keymaps/art/keymap.c b/keyboards/wheatfield/split75/keymaps/art/keymap.c
new file mode 100644
index 000000000..e540f1cb6
--- /dev/null
+++ b/keyboards/wheatfield/split75/keymaps/art/keymap.c
@@ -0,0 +1,189 @@
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ BASE,
+ QWERTY_MOD,
+ QWERTY,
+ WORKMAN,
+ MOD,
+ MEDIA
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ /* Base ,-----------------------------------------. ,-----------------------------------------------------.
+ * | ESC | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |Print| Ins | Home|
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | 8 | 9 | | ~ | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 0 | - | = | Backspac | Del |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | 6 | 7 | | Tab | Q | W | E | R | T | | Y | U | I | O | P | [ | ] | \ | End |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | 4 | 5 | | Caps | A | S | D | F | G | | H | J | K | L | ; | ' | Enter | PgUp|
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | 2 | 3 | | Shift | Z | X | C | V | B | | N | M | , | . | / | Shift | Up | PgDn|
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | 0 | 1 | | Ctrl | GUI | Alt | Space |Space| | Space | Alt |QW_ON| Ctrl | Left| Down|Right|
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [BASE] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------| |--------------------------------Right Hand------------------------------------------------
+ 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_INS, KC_HOME,
+KC_8, KC_9, KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPC, KC_DEL,
+KC_6, KC_7, 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_END,
+KC_4, KC_5, 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_ENTER, KC_PGUP,
+KC_2, KC_3, 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_PGDN,
+KC_0, KC_1, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(QWERTY_MOD), KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+
+ /*QWERT On + Mod ,-----------------------------------------. ,-----------------------------------------------------.
+ * | | | | | | | | | | | | | | | | | |
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | | | | |MePrv| Vol+|MeNxt| | | | | | | | | | | | |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | | | | | | Vol-| | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | | | | | | Vol0|MePly| | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | | | | QWERTY | | | | | | | | | | | | |
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [QWERTY_MOD] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------------------| |--------------------------------Right Hand------------------------------------------------
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, KC_MPRV, KC_VOLU, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, KC_VOLD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, KC_MUTE, KC_MPLY, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, TO(QWERTY),_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /* QWERTY ,-----------------------------------------. ,-----------------------------------------------------.
+ * | ESC | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |Print| Ins | Home|
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | 8 | 9 | | ~ | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 0 | - | = | Backspac | Del |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | 6 | 7 | | Tab | Q | W | E | R | T | | Y | U | I | O | P | [ | ] | \ | End |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | 4 | 5 | | Caps | A | S | D | F | G | | H | J | K | L | ; | ' | Enter | PgUp|
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | 2 | 3 | | Shift | Z | X | C | V | B | | N | M | , | . | / | Shift | Up | PgDn|
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | 0 | 1 | | Ctrl | GUI | Alt |Spac/MEDIA | BSPC| | MOD | Alt | MOD | Ctrl | Left| Down|Right|
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [QWERTY] = LAYOUT(
+//--------------------------------Left Hand------------------------------------| |--------------------------------Right Hand------------------------------------------------
+ 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_INS, KC_HOME,
+KC_8, KC_9, KC_GRAVE, KC_1, KC_2, LGUI_T(KC_3), LALT_T(KC_4), LCTL_T(KC_5), KC_6, KC_7, LCTL_T(KC_8), LALT_T(KC_9), LGUI_T(KC_0), KC_MINUS, KC_EQUAL, KC_BSPC, KC_DEL,
+KC_6, KC_7, 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_END,
+KC_4, KC_5, 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_ENTER, KC_PGUP,
+KC_2, KC_3, 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_PGDN,
+KC_0, KC_1, KC_LCTL, KC_LGUI, KC_LALT, LT(MEDIA, KC_SPC),KC_BSPC, MO(MOD), KC_RALT, MO(MOD),KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+
+ /* WORKMAN ,-----------------------------------------. ,-----------------------------------------------------.
+ * | | | | | | | | | | | | | | | | | |
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | | | | BASE | | | | | | | | | | | | |
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [WORKMAN] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------------------| |--------------------------------Right Hand------------------------------------------------
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, KC_Q, KC_D, KC_R, KC_W, KC_B, KC_J, KC_F, KC_U, KC_P, KC_SCLN,_______,_______, _______, _______,
+_______, _______, _______, 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_C, KC_V, KC_M, KC_K, KC_L, KC_COMM,KC_DOT, KC_SLSH, _______, _______, _______,
+_______, _______, TO(BASE), _______,_______,_______, _______, _______, _______, TO(QWERTY), _______, _______, _______, _______
+ ),
+
+ /* MOD ,-----------------------------------------. ,-----------------------------------------------------.
+ * | | | | | | | | | | | | | | | | | |
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | | | | BASE | | | | | | | | | | | | |
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [MOD] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------------------| |--------------------------------Right Hand------------------------------------------------
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, KC_HOME, KC_UP, KC_END, KC_PGUP, _______, KC_MS_BTN1,KC_MS_UP, KC_MS_BTN3,KC_MS_BTN2,_______,_______, _______, _______,
+_______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RIGHT, KC_PGDOWN, _______,KC_MS_LEFT,KC_MS_DOWN,KC_MS_RIGHT,KC_APPLICATION, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, TO(WORKMAN),TO(BASE), KC_MS_ACCEL0,KC_MS_ACCEL1,KC_MS_ACCEL2, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+
+ /* MEDIA ,-----------------------------------------. ,-----------------------------------------------------.
+ * | | | | | | | | | | | | | | | | | |
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | | | | | | | | | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | | | | | | | Play| | | | | | | | | | | |
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | | | | BASE | | | | | | | | | | | | |
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [MEDIA] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------------------| |--------------------------------Right Hand------------------------------------------------
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, KC_MPRV, KC_VOLU, KC_MNXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, KC_VOLD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, KC_MUTE, KC_MPLY, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
+
+bool led_update_user(led_t led_state) {
+ writePin(CAPSLOCK_LED_PIN, led_state.caps_lock);
+ return false;
+}
+
+void keyboard_pre_init_user(void) {
+ writePinHigh(SCROLLLOCK_LED_PIN);
+ wait_ms(50);
+ writePinHigh(CAPSLOCK_LED_PIN);
+ wait_ms(50);
+ writePinHigh(NUMLOCK_LED_PIN);
+ wait_ms(50);
+ writePinLow(SCROLLLOCK_LED_PIN);
+ wait_ms(50);
+ writePinLow(CAPSLOCK_LED_PIN);
+ wait_ms(50);
+ writePinLow(NUMLOCK_LED_PIN);
+
+ layer_state_set_user(layer_state);
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ writePinLow(NUMLOCK_LED_PIN);
+ writePinLow(SCROLLLOCK_LED_PIN);
+ switch (get_highest_layer(state)) {
+ case BASE:
+ writePinHigh(SCROLLLOCK_LED_PIN);
+ break;
+ }
+ return state;
+}
diff --git a/keyboards/wheatfield/split75/keymaps/default/keymap.c b/keyboards/wheatfield/split75/keymaps/default/keymap.c
new file mode 100644
index 000000000..069eb6bd1
--- /dev/null
+++ b/keyboards/wheatfield/split75/keymaps/default/keymap.c
@@ -0,0 +1,30 @@
+#include QMK_KEYBOARD_H
+
+#define BASE 0
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ /* Base ,-----------------------------------------. ,-----------------------------------------------------.
+ * | ESC | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |Print| Ins | Del |
+ * ,-----------. |-----+-----+-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----+-----+-----------+-----|
+ * | 8 | 9 | | ~ | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 0 | - | = | Backspac | Home|
+ * |-----+-----| |-----------------------------------------' ,--------------------------------------------------+-----|
+ * | 6 | 7 | | Tab | Q | W | E | R | T | | Y | U | I | O | P | [ | ] | \ | PgUp|
+ * |-----+-----| |---------------------------------------. `--------------------------------------------------+-----|
+ * | 4 | 5 | | Caps | A | S | D | F | G | | H | J | K | L | ; | ' | Enter | PgDn|
+ * |-----+-----| |-----------------------------------------. `-------------------------------------------------+-----|
+ * | 2 | 3 | | Shift | Z | X | C | V | B | | N | M | , | . | / | Shift | Up | End |
+ * |-----+-----| |-----------------------------------------' ,-------------------------------------------+-----+-----|
+ * | 0 | 1 | | Ctrl | GUI | Alt | Space |Space| | Space | Alt | | Ctrl | Left| Down|Right|
+ * `-----------' `---------------------------------------' `-------------------------------------------------------'
+ */
+ [BASE] = LAYOUT(
+//--------------------------------Left Hand-----------------------------------| |--------------------------------Right Hand------------------------------------------------
+ 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_INS, KC_DEL,
+KC_8, KC_9, KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPC, KC_HOME,
+KC_6, KC_7, 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_PGUP,
+KC_4, KC_5, 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_ENTER, KC_PGDN,
+KC_2, KC_3, 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_END,
+KC_0, KC_1, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, _______,KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
+ )
+};
diff --git a/keyboards/wheatfield/split75/matrix.c b/keyboards/wheatfield/split75/matrix.c
new file mode 100644
index 000000000..9e86bfc37
--- /dev/null
+++ b/keyboards/wheatfield/split75/matrix.c
@@ -0,0 +1,155 @@
+/*
+Copyright 2017 Luiz Ribeiro <luizribeiro@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 <string.h>
+#include <stdio.h>
+#include "quantum.h"
+#include "i2c_master.h"
+#include "split75.h"
+
+#define RIGHT_HALF
+
+
+void matrix_set_row_status(uint8_t row);
+
+
+#if defined(RIGHT_HALF)
+#define I2C_TIMEOUT 10
+#define MCP23018_TWI_ADDRESS 0b0100000
+#define TW_READ 1
+#define TW_WRITE 0
+#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE )
+#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
+#define IODIRA 0x00 // i/o direction register
+#define IODIRB 0x01
+#define IODIRA 0x00 // i/o direction register
+#define IODIRB 0x01
+#define GPPUA 0x0C // GPIO pull-up resistor register
+#define GPPUB 0x0D
+#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
+#define GPIOB 0x13
+#define OLATA 0x14 // output latch register
+#define OLATB 0x15
+#define MCP_ROWS_START 8
+
+static uint8_t mcp23018_init(void) {
+ uint8_t ret;
+ uint8_t data[3];
+ // set pin direction
+ // - unused : input : 1
+ // - input : input : 1
+ // - driving : output : 0
+ data[0] = IODIRA;
+ data[1] = 0b00000000; // IODIRA
+ data[2] = (0b11111111); // IODIRB
+
+ ret = i2c_transmit(TWI_ADDR_WRITE, (uint8_t *)data, 3, I2C_TIMEOUT);
+ if (ret) goto out; // make sure we got an ACK
+
+ // set pull-up
+ // - unused : on : 1
+ // - input : on : 1
+ // - driving : off : 0
+ data[0] = GPPUA;
+ data[1] = 0b00000000; // IODIRA
+ data[2] = (0b11111111); // IODIRB
+
+ ret = i2c_transmit(TWI_ADDR_WRITE, (uint8_t *)data, 3, I2C_TIMEOUT);
+ if (ret) goto out; // make sure we got an ACK
+
+ // set logical value (doesn't matter on inputs)
+ // - unused : hi-Z : 1
+ // - input : hi-Z : 1
+ // - driving : hi-Z : 1
+ data[0] = OLATA;
+ data[1] = 0b11111111; // IODIRA
+ data[2] = (0b11111111); // IODIRB
+
+ ret = i2c_transmit(TWI_ADDR_WRITE, (uint8_t *)data, 3, I2C_TIMEOUT);
+
+out:
+ return ret;
+}
+#endif
+
+void matrix_init_custom(void) {
+ // Set rows as output starting high
+ DDRB = 0xFF;
+ PORTB = 0xFF;
+
+ // Set columns as inputs with pull-up enabled
+ DDRA = 0x00;
+ PORTA = 0xFF;
+
+ // Initialize i2c communication
+ i2c_init();
+
+#if defined(RIGHT_HALF)
+ // Initialize the chip on the other half
+ mcp23018_init();
+#endif
+
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ bool matrix_has_changed = false;
+
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ // Store last value of row prior to reading
+ matrix_row_t last_row_value = current_matrix[row];
+
+ matrix_row_t cols = 0;
+ // Select the row to scan
+ matrix_set_row_status(row);
+
+ matrix_io_delay();
+ //Set the local row
+
+#if defined(RIGHT_HALF)
+ // Initialize to 0x7F in case I2C read fails,
+ // as 0x75 would be no keys pressed
+ uint8_t data = 0x7F;
+ // Receive the columns from right half
+ i2c_receive(TWI_ADDR_WRITE, &data, 1, I2C_TIMEOUT);
+#endif
+
+ cols |= ((~(PINA | 0x80)) & 0x7F);
+#if defined(RIGHT_HALF)
+ cols |= (((~(data | 0x80)) & 0x7F) << 7);
+#endif
+
+ current_matrix[row] = cols;
+ matrix_has_changed |= (last_row_value != current_matrix[row]);
+ }
+
+ return matrix_has_changed;
+}
+
+void matrix_set_row_status(uint8_t row) {
+#if defined(RIGHT_HALF)
+ uint8_t txdata[3];
+
+ //Set the remote row on port A
+ txdata[0] = (GPIOA);
+ txdata[1] = ( 0xFF & ~(1<<row) );
+ i2c_transmit(TWI_ADDR_WRITE, (uint8_t *)txdata, 2, I2C_TIMEOUT);
+#endif
+
+ //Set the local row on port B
+ DDRB = (1 << row);
+ PORTB = ~(1 << row);
+}
diff --git a/keyboards/wheatfield/split75/rules.mk b/keyboards/wheatfield/split75/rules.mk
new file mode 100644
index 000000000..e90f5f439
--- /dev/null
+++ b/keyboards/wheatfield/split75/rules.mk
@@ -0,0 +1,31 @@
+# MCU name
+MCU = atmega32a
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = bootloadHID
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+WS2812_DRIVER = i2c
+
+OPT_DEFS = -DDEBUG_LEVEL=0
+
+# custom matrix setup
+CUSTOM_MATRIX = lite
+SRC = matrix.c
+QUANTUM_LIB_SRC += i2c_master.c
diff --git a/keyboards/wheatfield/split75/split75.c b/keyboards/wheatfield/split75/split75.c
new file mode 100644
index 000000000..3ed456292
--- /dev/null
+++ b/keyboards/wheatfield/split75/split75.c
@@ -0,0 +1,25 @@
+#include "split75.h"
+
+#include "i2c_master.h"
+
+
+void keyboard_pre_init_kb(void) {
+ led_init_ports();
+ keyboard_pre_init_user();
+}
+
+void led_init_ports(void) {
+ setPinOutput(NUMLOCK_LED_PIN);
+ setPinOutput(CAPSLOCK_LED_PIN);
+ setPinOutput(SCROLLLOCK_LED_PIN);
+}
+
+bool led_update_kb(led_t led_state) {
+ bool res = led_update_user(led_state);
+ if(res) {
+ writePin(NUMLOCK_LED_PIN, led_state.num_lock);
+ writePin(CAPSLOCK_LED_PIN, led_state.caps_lock);
+ writePin(SCROLLLOCK_LED_PIN, led_state.scroll_lock);
+ }
+ return res;
+}
diff --git a/keyboards/wheatfield/split75/split75.h b/keyboards/wheatfield/split75/split75.h
new file mode 100644
index 000000000..d81cf0a61
--- /dev/null
+++ b/keyboards/wheatfield/split75/split75.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "quantum.h"
+
+// Number of keys in rows
+// 0 + 7 / 9
+// 2 + 7 / 8
+// 2 + 6 / 9
+// 2 + 6 / 8
+// 2 + 6 / 8
+// 2 + 5 / 7
+
+#define LAYOUT( \
+ K05, K15, K25, K35, K45, K55, K65, K75, K85, K95, K105, K115, K125, K135, K86, K87, \
+ K47, K46, K04, K14, K24, K34, K44, K54, K64, K74, K84, K94, K104, K114, K124, K96, K97, \
+ K37, K36, K03, K13, K23, K33, K43, K53, K73, K83, K93, K103, K113, K123, K133, K106, K107, \
+ K27, K26, K02, K12, K22, K32, K42, K52, K72, K82, K92, K102, K112, K122, K116, K117, \
+ K17, K16, K01, K21, K31, K41, K51, K61, K71, K81, K91, K101, K111, K131, K126, K127, \
+ K07, K06, K00, K10, K20, K30, K40, K70, K100, K110, K120, K130, K136, K137 \
+){ \
+ { K00, K10, K20, K30, K40, KC_NO, KC_NO, K70, KC_NO, KC_NO, K100, K110, K120, K130 }, \
+ { K01, KC_NO, K21, K31, K41, K51, K61, K71, K81, K91, K101, K111, KC_NO, K131 }, \
+ { K02, K12, K22, K32, K42, K52, KC_NO, K72, K82, K92, K102, K112, K122, }, \
+ { K03, K13, K23, K33, K43, K53, KC_NO, K73, K83, K93, K103, K113, K123, K133 }, \
+ { K04, K14, K24, K34, K44, K54, K64, K74, K84, K94, K104, K114, K124, }, \
+ { K05, K15, K25, K35, K45, K55, K65, K75, K85, K95, K105, K115, K125, K135 }, \
+ { K06, K16, K26, K36, K46, KC_NO, KC_NO, KC_NO, K86, K96, K106, K116, K126, K136 }, \
+ { K07, K17, K27, K37, K47, KC_NO, KC_NO, KC_NO, K87, K97, K107, K117, K127, K137 } \
+}
+
+#define NUMLOCK_LED_PIN D0
+#define CAPSLOCK_LED_PIN D1
+#define SCROLLLOCK_LED_PIN D6
diff --git a/keyboards/whitefox/keymaps/konstantin/rules.mk b/keyboards/whitefox/keymaps/konstantin/rules.mk
index bced6e8a7..c39175c97 100644
--- a/keyboards/whitefox/keymaps/konstantin/rules.mk
+++ b/keyboards/whitefox/keymaps/konstantin/rules.mk
@@ -3,6 +3,7 @@ BOOTMAGIC_ENABLE = no
COMMAND_ENABLE = yes
CONSOLE_ENABLE = yes
EXTRAKEY_ENABLE = yes
+GRAVE_ESC_ENABLE = no
MOUSEKEY_ENABLE = yes
NKRO_ENABLE = yes
SPACE_CADET_ENABLE = no
diff --git a/keyboards/winkeyless/bface/config.h b/keyboards/winkeyless/bface/config.h
index 0ef8a42b6..27ee761e9 100644
--- a/keyboards/winkeyless/bface/config.h
+++ b/keyboards/winkeyless/bface/config.h
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#define VENDOR_ID 0x20A0
-#define PRODUCT_ID 0x422D
+#define PRODUCT_ID 0x4246 // BF
#define DEVICE_VER 0x0200
#define MANUFACTURER Winkeyless
#define PRODUCT B.face
diff --git a/keyboards/winkeyless/bface/keymaps/via/config.h b/keyboards/winkeyless/bface/keymaps/via/config.h
new file mode 100644
index 000000000..0865e4520
--- /dev/null
+++ b/keyboards/winkeyless/bface/keymaps/via/config.h
@@ -0,0 +1 @@
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/winkeyless/bface/keymaps/via/keymap.c b/keyboards/winkeyless/bface/keymaps/via/keymap.c
new file mode 100644
index 000000000..1d472e055
--- /dev/null
+++ b/keyboards/winkeyless/bface/keymaps/via/keymap.c
@@ -0,0 +1,43 @@
+/*
+Copyright 2020 MechMerlin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_60_ansi(
+ 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_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,
+ KC_F1, 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,
+ KC_LCTL,KC_LALT,KC_LGUI, KC_SPC, KC_RALT,KC_RGUI,MO(1), KC_RCTL
+ ),
+ [1] = LAYOUT_60_ansi(
+ 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,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,BL_INC, BL_DEC, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,RGB_MOD,KC_TRNS,BL_ON, BL_OFF, KC_TRNS,KC_TRNS,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] = LAYOUT_60_ansi(
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS
+ ),
+};
diff --git a/keyboards/winkeyless/bface/keymaps/via/rules.mk b/keyboards/winkeyless/bface/keymaps/via/rules.mk
new file mode 100644
index 000000000..97010a994
--- /dev/null
+++ b/keyboards/winkeyless/bface/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/winkeyless/bmini/bmini.h b/keyboards/winkeyless/bmini/bmini.h
index 7bdf66fd2..82b9ec01c 100644
--- a/keyboards/winkeyless/bmini/bmini.h
+++ b/keyboards/winkeyless/bmini/bmini.h
@@ -14,9 +14,7 @@ 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 BMINI_H
-#define BMINI_H
+#pragma once
#include "quantum.h"
@@ -56,23 +54,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{ K07, K17, K27, K37, K47, K57, K67, K77, KC_NO, KC_NO, KA7, KB7, KC7, KD7, KE7 } \
}
-#define LAYOUT_kc( \
- K05, K25, K35, K45, K55, K06, KA6, KA7, K07, KB5, KC5, KD5, KE5, KD1, KE1, KE2, \
- K04, K14, K24, K34, K44, K54, K16, KB6, KB7, K17, KA4, KB4, KC4, KE4, KD0, \
- K03, K13, K23, K33, K43, K53, K26, KC6, KC7, K27, KA3, KB3, KC3, KD3, K67, \
- K02, K12, K22, K32, K42, K52, K36, KD6, KD7, K37, KA2, KB2, KD2, KE0, \
- K01, K11, K21, K31, K41, K51, K46, KE6, KE7, K47, KA1, KB1, K86, K77, \
- K00, K10, K20, K56, K57, KB0, KC0, K66, K76, K96 \
-) \
-{ \
- { KC_##K00, KC_##K10, KC_##K20, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KB0, KC_##KC0, KC_##KD0, KC_##KE0 }, \
- { KC_##K01, KC_##K11, KC_##K21, KC_##K31, KC_##K41, KC_##K51, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KA1, KC_##KB1, KC_NO, KC_##KD1, KC_##KE1 }, \
- { KC_##K02, KC_##K12, KC_##K22, KC_##K32, KC_##K42, KC_##K52, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KA2, KC_##KB2, KC_NO, KC_##KD2, KC_##KE2 }, \
- { KC_##K03, KC_##K13, KC_##K23, KC_##K33, KC_##K43, KC_##K53, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KA3, KC_##KB3, KC_##KC3, KC_##KD3, KC_NO }, \
- { KC_##K04, KC_##K14, KC_##K24, KC_##K34, KC_##K44, KC_##K54, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KA4, KC_##KB4, KC_##KC4, KC_NO, KC_##KE4 }, \
- { KC_##K05, KC_NO, KC_##K25, KC_##K35, KC_##K45, KC_##K55, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KB5, KC_##KC5, KC_##KD5, KC_##KE5 }, \
- { KC_##K06, KC_##K16, KC_##K26, KC_##K36, KC_##K46, KC_##K56, KC_##K66, KC_##K76, KC_##K86, KC_##K96, KC_##KA6, KC_##KB6, KC_##KC6, KC_##KD6, KC_##KE6 }, \
- { KC_##K07, KC_##K17, KC_##K27, KC_##K37, KC_##K47, KC_##K57, KC_##K67, KC_##K77, KC_NO, KC_NO, KC_##KA7, KC_##KB7, KC_##KC7, KC_##KD7, KC_##KE7 } \
-}
-
-#endif
diff --git a/keyboards/winkeyless/bmini/config.h b/keyboards/winkeyless/bmini/config.h
index ccce0b6c8..6e91241af 100644
--- a/keyboards/winkeyless/bmini/config.h
+++ b/keyboards/winkeyless/bmini/config.h
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
#define VENDOR_ID 0x20A0
-#define PRODUCT_ID 0x422D
+#define PRODUCT_ID 0x424D // BM
#define DEVICE_VER 0x0200
#define MANUFACTURER Winkeyless
#define PRODUCT B.mini
diff --git a/keyboards/winkeyless/bmini/keymaps/via/config.h b/keyboards/winkeyless/bmini/keymaps/via/config.h
new file mode 100644
index 000000000..0865e4520
--- /dev/null
+++ b/keyboards/winkeyless/bmini/keymaps/via/config.h
@@ -0,0 +1 @@
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/winkeyless/bmini/keymaps/via/keymap.c b/keyboards/winkeyless/bmini/keymaps/via/keymap.c
new file mode 100644
index 000000000..75ba043e5
--- /dev/null
+++ b/keyboards/winkeyless/bmini/keymaps/via/keymap.c
@@ -0,0 +1,46 @@
+/*
+Copyright 2020 MechMerlin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ 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_HOME,KC_END,
+ 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_DEL,
+ 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_INS,
+ MO(0), 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_PGUP,
+ 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_PGDN,
+ KC_LCTL,KC_LALT,KC_LGUI, KC_SPC, KC_RGUI,KC_RALT,KC_RCTL,KC_LEFT,KC_DOWN,KC_RGHT
+ ),
+ [1] = LAYOUT(
+ KC_TRNS,RGB_TOG,RGB_MOD,RGB_HUI,RGB_SAI,RGB_VAI,RGB_HUD,RGB_SAD,RGB_VAD,KC_TRNS,KC_TRNS,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_DEL,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_INS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_RGHT
+ ),
+
+ [2] = LAYOUT(
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,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_DEL,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_INS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_RGHT
+ ),
+};
diff --git a/keyboards/winkeyless/bmini/keymaps/via/rules.mk b/keyboards/winkeyless/bmini/keymaps/via/rules.mk
new file mode 100644
index 000000000..97010a994
--- /dev/null
+++ b/keyboards/winkeyless/bmini/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/winkeyless/bminiex/bminiex.h b/keyboards/winkeyless/bminiex/bminiex.h
index 8d897f639..b9532f2f0 100644
--- a/keyboards/winkeyless/bminiex/bminiex.h
+++ b/keyboards/winkeyless/bminiex/bminiex.h
@@ -72,23 +72,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{ K06, K16, K26, K36, K46, K56, K66, K76, K86, K96, KA6, KB6, KC6, KD6, KE6 }, \
{ K07, K17, K27, K37, K47, K57, K67, K77, KC_NO, KC_NO, KA7, KB7, KC7, KD7, KE7 } \
}
-
-#define LAYOUT_kc( \
- K05, K25, K35, K45, K55, K06, KA6, KA7, K07, KB5, KC5, KD5, KE5, KD1, KE1, KE2, K65, K75, K85, K95, \
- K04, K14, K24, K34, K44, K54, K16, KB6, KB7, K17, KA4, KB4, KC4, KE4, KD0, K64, K74, K84, K94, \
- K03, K13, K23, K33, K43, K53, K26, KC6, KC7, K27, KA3, KB3, KC3, KD3, K67, K63, K73, K83, \
- K02, K12, K22, K32, K42, K52, K36, KD6, KD7, K37, KA2, KB2, KC2, KD2, KE0, K62, K72, K82, K92, \
- K01, K30, K11, K21, K31, K41, K51, K46, KE6, KE7, K47, KA1, KB1, K86, K77, K61, K71, K81, \
- K00, K10, K20, K56, K57, KB0, KC0, K66, K76, K96, K60, K80, K90 \
-) \
-{ \
- { KC_##K00, KC_##K10, KC_##K20, KC_##K30, KC_NO, KC_NO, KC_##K60, KC_NO, KC_##K80, KC_##K90, KC_NO, KC_##KB0, KC_##KC0, KC_##KD0, KC_##KE0 }, \
- { KC_##K01, KC_##K11, KC_##K21, KC_##K31, KC_##K41, KC_##K51, KC_##K61, KC_##K71, KC_##K81, KC_NO, KC_##KA1, KC_##KB1, KC_NO, KC_##KD1, KC_##KE1 }, \
- { KC_##K02, KC_##K12, KC_##K22, KC_##K32, KC_##K42, KC_##K52, KC_##K62, KC_##K72, KC_##K82, KC_##K92, KC_##KA2, KC_##KB2, KC_##KC2, KC_##KD2, KC_##KE2 }, \
- { KC_##K03, KC_##K13, KC_##K23, KC_##K33, KC_##K43, KC_##K53, KC_##K63, KC_##K73, KC_##K83, KC_NO, KC_##KA3, KC_##KB3, KC_##KC3, KC_##KD3, KC_NO }, \
- { KC_##K04, KC_##K14, KC_##K24, KC_##K34, KC_##K44, KC_##K54, KC_##K64, KC_##K74, KC_##K84, KC_##K94, KC_##KA4, KC_##KB4, KC_##KC4, KC_NO, KC_##KE4 }, \
- { KC_##K05, KC_NO, KC_##K25, KC_##K35, KC_##K45, KC_##K55, KC_##K65, KC_##K75, KC_##K85, KC_##K95, KC_NO, KC_##KB5, KC_##KC5, KC_##KD5, KC_##KE5 }, \
- { KC_##K06, KC_##K16, KC_##K26, KC_##K36, KC_##K46, KC_##K56, KC_##K66, KC_##K76, KC_##K86, KC_##K96, KC_##KA6, KC_##KB6, KC_##KC6, KC_##KD6, KC_##KE6 }, \
- { KC_##K07, KC_##K17, KC_##K27, KC_##K37, KC_##K47, KC_##K57, KC_##K67, KC_##K77, KC_NO, KC_NO, KC_##KA7, KC_##KB7, KC_##KC7, KC_##KD7, KC_##KE7 } \
-}
-
diff --git a/keyboards/winkeyless/bminiex/config.h b/keyboards/winkeyless/bminiex/config.h
index 6e35c9e82..7c9c11c11 100644
--- a/keyboards/winkeyless/bminiex/config.h
+++ b/keyboards/winkeyless/bminiex/config.h
@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h"
#define VENDOR_ID 0x20A0
-#define PRODUCT_ID 0x422E
+#define PRODUCT_ID 0x4258 // BX
#define DEVICE_VER 0x0200
#define MANUFACTURER Winkeyless
#define PRODUCT B.mini EX
diff --git a/keyboards/winkeyless/bminiex/keymaps/via/config.h b/keyboards/winkeyless/bminiex/keymaps/via/config.h
new file mode 100644
index 000000000..0865e4520
--- /dev/null
+++ b/keyboards/winkeyless/bminiex/keymaps/via/config.h
@@ -0,0 +1 @@
+#define DYNAMIC_KEYMAP_LAYER_COUNT 3
diff --git a/keyboards/winkeyless/bminiex/keymaps/via/keymap.c b/keyboards/winkeyless/bminiex/keymaps/via/keymap.c
new file mode 100644
index 000000000..d612843f8
--- /dev/null
+++ b/keyboards/winkeyless/bminiex/keymaps/via/keymap.c
@@ -0,0 +1,47 @@
+/*
+Copyright 2020 MechMerlin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ 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_HOME,KC_END, KC_NO, KC_NO, KC_NO, KC_NO,
+ 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_DEL, 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_NO, KC_INS, KC_P7, KC_P8, KC_P9,
+ KC_LCAP, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_NUHS,KC_ENT, KC_PGUP, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ 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_PGDN, KC_P1, KC_P2, KC_P3,
+ KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_APP ,KC_RCTL,KC_LEFT,KC_DOWN,KC_RGHT, KC_P0, KC_PDOT, KC_PENT
+ ),
+
+ [1] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, 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] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,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, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS ,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+};
diff --git a/keyboards/winkeyless/bminiex/keymaps/via/rules.mk b/keyboards/winkeyless/bminiex/keymaps/via/rules.mk
new file mode 100644
index 000000000..97010a994
--- /dev/null
+++ b/keyboards/winkeyless/bminiex/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+VIA_ENABLE = yes
+LTO_ENABLE = yes
+
+MOUSEKEY_ENABLE = no
+EXTRAKEY_ENABLE = no
diff --git a/keyboards/winkeyless/readme.md b/keyboards/winkeyless/readme.md
index 91719f6da..a4eb6d6bd 100644
--- a/keyboards/winkeyless/readme.md
+++ b/keyboards/winkeyless/readme.md
@@ -10,4 +10,4 @@ Most Winkeyless boards were low profile and constructed out of acrylic showcasin
In late 2018, Winkeyless closed its doors. The numerous unlicensed implementations of its hardware and software were cited as one
of many reasons for shutting down.
-This directory contains official Winkeyless boards that have had QMK firmware ported to work with them.
+This directory contains official Winkeyless boards that have had QMK firmware and VIA support added.
diff --git a/keyboards/wsk/gothic50/rules.mk b/keyboards/wsk/gothic50/rules.mk
index 6a1221aa1..ea21d62b3 100644
--- a/keyboards/wsk/gothic50/rules.mk
+++ b/keyboards/wsk/gothic50/rules.mk
@@ -7,7 +7,8 @@ MCU = atmega32u4
# Atmel DFU atmel-dfu
# LUFA DFU lufa-dfu
# QMK DFU qmk-dfu
-# atmega32a bootloadHID
+# ATmega32A bootloadHID
+# ATmega328P USBasp
BOOTLOADER = atmel-dfu
# Build Options
diff --git a/keyboards/wsk/gothic70/rules.mk b/keyboards/wsk/gothic70/rules.mk
index 6a1221aa1..ea21d62b3 100644
--- a/keyboards/wsk/gothic70/rules.mk
+++ b/keyboards/wsk/gothic70/rules.mk
@@ -7,7 +7,8 @@ MCU = atmega32u4
# Atmel DFU atmel-dfu
# LUFA DFU lufa-dfu
# QMK DFU qmk-dfu
-# atmega32a bootloadHID
+# ATmega32A bootloadHID
+# ATmega328P USBasp
BOOTLOADER = atmel-dfu
# Build Options
diff --git a/keyboards/yd60mq/12led/config.h b/keyboards/yd60mq/12led/config.h
new file mode 100644
index 000000000..dde57aafe
--- /dev/null
+++ b/keyboards/yd60mq/12led/config.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define DEVICE_VER 0x0001
+
+#define RGBLED_NUM 12
diff --git a/keyboards/yd60mq/12led/readme.md b/keyboards/yd60mq/12led/readme.md
new file mode 100644
index 000000000..117069061
--- /dev/null
+++ b/keyboards/yd60mq/12led/readme.md
@@ -0,0 +1,3 @@
+# YD60MQ – 12 LED
+
+Code specific to the YD60MQ variant with 12 RGB LEDs on the back (unknown revision number).
diff --git a/keyboards/yd60mq/12led/rules.mk b/keyboards/yd60mq/12led/rules.mk
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/yd60mq/12led/rules.mk
diff --git a/keyboards/yd60mq/16led/config.h b/keyboards/yd60mq/16led/config.h
new file mode 100644
index 000000000..11ce3aeb2
--- /dev/null
+++ b/keyboards/yd60mq/16led/config.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define DEVICE_VER 0x0002
+
+#define RGBLED_NUM 16
diff --git a/keyboards/yd60mq/16led/readme.md b/keyboards/yd60mq/16led/readme.md
new file mode 100644
index 000000000..a03d6259e
--- /dev/null
+++ b/keyboards/yd60mq/16led/readme.md
@@ -0,0 +1,3 @@
+# YD60MQ – 16 LED
+
+Code specific to the YD60MQ variant with 16 RGB LEDs on the back (unknown revision number).
diff --git a/keyboards/yd60mq/16led/rules.mk b/keyboards/yd60mq/16led/rules.mk
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/keyboards/yd60mq/16led/rules.mk
diff --git a/keyboards/yd60mq/config.h b/keyboards/yd60mq/config.h
index 75e697802..26c39a5b0 100644
--- a/keyboards/yd60mq/config.h
+++ b/keyboards/yd60mq/config.h
@@ -5,7 +5,6 @@
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
-#define DEVICE_VER 0x0001
#define MANUFACTURER YMDK
#define PRODUCT YD60MQ
#define DESCRIPTION Keyboard
@@ -37,10 +36,8 @@
/* prevent stuck modifiers */
#define RGB_DI_PIN E2
-#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
-#define RGBLED_NUM 12
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
-#endif
+// RGBLED_NUM is defined in revisions
diff --git a/keyboards/yd60mq/readme.md b/keyboards/yd60mq/readme.md
index 0802c9d16..32073da63 100644
--- a/keyboards/yd60mq/readme.md
+++ b/keyboards/yd60mq/readme.md
@@ -5,15 +5,25 @@
Customizable 60% PCB by [YMDK](https://ymdk.aliexpress.com/store/429151?spm=2114.10010108.0.0.3ab23641lIkgzm).
* Keyboard Maintainer: QMK Community
-* Hardware Supported: YD60MQ PCB, ATmega32U4
+* Hardware Supported: YD60MQ PCB
+ * 12led (unknown revision number, has 12 RGB LEDs on the back) – _default variant_
+ * 16led (unknown revision number, has 16 RGB LEDs on the back)
* Hardware Availability: [YMDK on AliExpress](https://www.aliexpress.com/i/32869207240.html)
Make example for this keyboard (after setting up your build environment):
- make yd60mq:default
+```sh
+make yd60mq:default # builds the 12 LED variant
+make yd60mq/12led:default # also builds the 12 LED variant
+make yd60mq/16led:default # builds the 16 LED variant
+```
The keyboard uses a DFU bootloader. To make a keymap and use dfu to flash it:
- make yd60mq:default:flash
+```sh
+make yd60mq:default:flash # builds and flashes the 12 LED variant
+make yd60mq/12led:default:flash # also builds and flashes the 12 LED variant
+make yd60mq/16led:default:flash # builds and flashes the 16 LED variant
+```
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/yd60mq/rules.mk b/keyboards/yd60mq/rules.mk
index f28f80058..98b13aca4 100644
--- a/keyboards/yd60mq/rules.mk
+++ b/keyboards/yd60mq/rules.mk
@@ -32,3 +32,5 @@ FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
HD44780_ENABLE = no # Enable support for HD44780 based LCDs
LAYOUTS = 60_ansi
+
+DEFAULT_FOLDER = yd60mq/12led
diff --git a/keyboards/yd60mq/yd60mq.c b/keyboards/yd60mq/yd60mq.c
index a39af530d..bfe6b6c2d 100644
--- a/keyboards/yd60mq/yd60mq.c
+++ b/keyboards/yd60mq/yd60mq.c
@@ -1,10 +1,12 @@
#include "yd60mq.h"
+__attribute__((weak))
void matrix_init_kb(void){
setPinOutput(F4);
writePinHigh(F4);
}
+__attribute__((weak))
bool led_update_kb(led_t led_state) {
bool res = led_update_user(led_state);
if (res) {
diff --git a/keyboards/yushakobo/quick7/config.h b/keyboards/yushakobo/quick7/config.h
new file mode 100644
index 000000000..4fb8ba6d9
--- /dev/null
+++ b/keyboards/yushakobo/quick7/config.h
@@ -0,0 +1,252 @@
+/*
+Copyright 2020 yushakobo
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x3265
+#define PRODUCT_ID 0x0002
+#define DEVICE_VER 0x0001
+#define MANUFACTURER yushakobo
+#define PRODUCT quick7
+#define DESCRIPTION A simple macropad with rotary encoders.
+
+/* key matrix size */
+#define MATRIX_ROWS 3
+#define MATRIX_COLS 3
+
+/*
+ * 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 DIRECT_PINS { \
+ { D2, D4, F4 }, \
+ { D7, B1, B3 }, \
+ { E6, B4, B2 }, \
+}
+
+#define ENCODERS_PAD_A { D1, F5 }
+#define ENCODERS_PAD_B { D0, F6 }
+
+#define UNUSED_PINS
+
+
+
+/* COL2ROW, ROW2COL*/
+#define DIODE_DIRECTION COL2ROW
+
+#ifdef RGBLIGHT_ENABLE
+# define RGB_DI_PIN D3
+# define RGBLED_NUM 13
+# define RGBLIGHT_HUE_STEP 8
+# define RGBLIGHT_SAT_STEP 8
+# define RGBLIGHT_VAL_STEP 8
+# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
+# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+///*== all animations enable ==*/
+//# define RGBLIGHT_ANIMATIONS
+///*== or choose animations ==*/
+//# define RGBLIGHT_EFFECT_BREATHING
+# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+//# define RGBLIGHT_EFFECT_SNAKE
+//# define RGBLIGHT_EFFECT_KNIGHT
+# define RGBLIGHT_EFFECT_CHRISTMAS
+# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+# define RGBLIGHT_EFFECT_RGB_TEST
+//# define RGBLIGHT_EFFECT_ALTERNATING
+/*== customize breathing effect ==*/
+ /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
+# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
+ /*==== use exp() and sin() ====*/
+// # define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
+// # define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
+#endif
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* 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
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+// #define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * 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 */
+/* defined by default; to change, uncomment and set to the combination you want */
+// #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
+
+/* 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_HELP H
+//#define MAGIC_KEY_HELP_ALT 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 0
+//#define MAGIC_KEY_LAYER0_ALT GRAVE
+//#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 B
+//#define MAGIC_KEY_BOOTLOADER_ALT ESC
+//#define MAGIC_KEY_LOCK CAPS
+//#define MAGIC_KEY_EEPROM E
+//#define MAGIC_KEY_EEPROM_CLEAR BSPACE
+//#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
+
+/* disable these deprecated features by default */
+#ifndef LINK_TIME_OPTIMIZATION_ENABLE
+ #define NO_ACTION_MACRO
+ #define NO_ACTION_FUNCTION
+#endif
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+ - MIDI notes can be sent when in Music mode is on
+*/
+//#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+ - MIDI notes can be added to the keymap
+ - Octave shift and transpose
+ - Virtual sustain, portamento, and modulation wheel
+ - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 1
+
+/*
+ * HD44780 LCD Display Configuration
+ */
+/*
+#define LCD_LINES 2 //< number of visible lines of the display
+#define LCD_DISP_LENGTH 16 //< visibles characters per line of the display
+
+#define LCD_IO_MODE 1 //< 0: memory mapped mode, 1: IO port mode
+
+#if LCD_IO_MODE
+#define LCD_PORT PORTB //< port for the LCD lines
+#define LCD_DATA0_PORT LCD_PORT //< port for 4bit data bit 0
+#define LCD_DATA1_PORT LCD_PORT //< port for 4bit data bit 1
+#define LCD_DATA2_PORT LCD_PORT //< port for 4bit data bit 2
+#define LCD_DATA3_PORT LCD_PORT //< port for 4bit data bit 3
+#define LCD_DATA0_PIN 4 //< pin for 4bit data bit 0
+#define LCD_DATA1_PIN 5 //< pin for 4bit data bit 1
+#define LCD_DATA2_PIN 6 //< pin for 4bit data bit 2
+#define LCD_DATA3_PIN 7 //< pin for 4bit data bit 3
+#define LCD_RS_PORT LCD_PORT //< port for RS line
+#define LCD_RS_PIN 3 //< pin for RS line
+#define LCD_RW_PORT LCD_PORT //< port for RW line
+#define LCD_RW_PIN 2 //< pin for RW line
+#define LCD_E_PORT LCD_PORT //< port for Enable line
+#define LCD_E_PIN 1 //< pin for Enable line
+#endif
+*/
+
+/* Bootmagic Lite key configuration */
+// #define BOOTMAGIC_LITE_ROW 0
+// #define BOOTMAGIC_LITE_COLUMN 0
diff --git a/keyboards/yushakobo/quick7/info.json b/keyboards/yushakobo/quick7/info.json
new file mode 100644
index 000000000..fd0f94a4e
--- /dev/null
+++ b/keyboards/yushakobo/quick7/info.json
@@ -0,0 +1,16 @@
+{
+ "keyboard_name": "quick7",
+ "url": "",
+ "maintainer": "yushakobo",
+ "width": 3,
+ "height": 2,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0},
+ {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1},
+ {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}
+ ]
+ }
+ }
+}
diff --git a/keyboards/yushakobo/quick7/keymaps/default/keymap.c b/keyboards/yushakobo/quick7/keymaps/default/keymap.c
new file mode 100644
index 000000000..3137f5853
--- /dev/null
+++ b/keyboards/yushakobo/quick7/keymaps/default/keymap.c
@@ -0,0 +1,72 @@
+/* Copyright 2020 yushakobo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+
+// Defines names for use in layer keycodes and the keymap
+enum layer_names {
+ _BASE,
+ _FUNC1
+};
+
+// Defines the keycodes used by our macros in process_record_user
+enum custom_keycodes {
+ YUSHAURL = SAFE_RANGE
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* Base */
+ [_BASE] = LAYOUT(
+ KC_MUTE, MO(_FUNC1), RGB_MOD,
+ S(KC_TAB), KC_UP, KC_TAB,
+ KC_LEFT, KC_DOWN, KC_RGHT
+ ),
+ [_FUNC1] = LAYOUT(
+ RESET, KC_TRNS, RGB_TOG,
+ KC_HOME, KC_VOLU, KC_END,
+ KC_MPRV, KC_VOLD, KC_MNXT
+ )
+};
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case YUSHAURL:
+ if (record->event.pressed) {
+ // when keycode QMKURL is pressed
+ SEND_STRING("https://yushakobo.jp/\n");
+ } else {
+ // when keycode QMKURL is released
+ }
+ break;
+ }
+ return true;
+}
+
+void encoder_update_user(uint8_t index, bool clockwise) {
+ if (index == 0) { // Left encoder
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ }
+ else if (index == 1) { // Right encoder
+ if (clockwise) {
+ rgblight_decrease_hue_noeeprom();
+ } else {
+ rgblight_increase_hue_noeeprom();
+ }
+ }
+}
diff --git a/keyboards/yushakobo/quick7/keymaps/default/readme.md b/keyboards/yushakobo/quick7/keymaps/default/readme.md
new file mode 100644
index 000000000..9db29d7ae
--- /dev/null
+++ b/keyboards/yushakobo/quick7/keymaps/default/readme.md
@@ -0,0 +1,25 @@
+# The default keymap for quick7
+
+### Base Layer
+```
+Left Encoder(CW: Vol+, CCW: Vol-)
+Right Encoder(CW: RGB HUE-, CCW: RGB HUE+)
+,----------- --------- ------------,
+| MUTE | Func1 | RGB MODE |
+ ----------- --------- ------------
+| Shift+Tab | UP | TAB |
+ ----------- --------- ------------
+| LEFT | DOWN | RIGHT |
+`----------- --------- ------------'
+```
+
+### Func1 Layer
+```
+,----------- --------- ------------,
+| RESET | Func1 | RGB TOGGLE |
+ ----------- --------- ------------
+| HOME | VOL+ | END |
+ ----------- --------- ------------
+| MEDIA << | VOL- | MEDIA >> |
+`----------- --------- ------------'
+``` \ No newline at end of file
diff --git a/keyboards/yushakobo/quick7/quick7.c b/keyboards/yushakobo/quick7/quick7.c
new file mode 100644
index 000000000..632bcf1ae
--- /dev/null
+++ b/keyboards/yushakobo/quick7/quick7.c
@@ -0,0 +1,17 @@
+/* Copyright 2020 yushakobo
+ *
+ * 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 "quick7.h"
diff --git a/keyboards/yushakobo/quick7/quick7.h b/keyboards/yushakobo/quick7/quick7.h
new file mode 100644
index 000000000..2e86487c7
--- /dev/null
+++ b/keyboards/yushakobo/quick7/quick7.h
@@ -0,0 +1,38 @@
+/* Copyright 2020 yushakobo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ */
+#define LAYOUT( \
+ k00, k01, k02, \
+ k10, k11, k12, \
+ k20, k21, k22 \
+) \
+{ \
+ { k00, k01, k02 }, \
+ { k10, k11, k12 }, \
+ { k20, k21, k22 } \
+}
diff --git a/keyboards/yushakobo/quick7/readme.md b/keyboards/yushakobo/quick7/readme.md
new file mode 100644
index 000000000..5e9f85c24
--- /dev/null
+++ b/keyboards/yushakobo/quick7/readme.md
@@ -0,0 +1,15 @@
+# quick7
+
+![quick7](https://cdn-ak.f.st-hatena.com/images/fotolife/s/segata24/20200329/20200329150121.jpg)
+
+A simple macropad for the beginners.
+
+* Keyboard Maintainer: [yushakobo](https://github.com/yushakobo)
+* Hardware Supported: quick7, Pro Micro (ATmega32U4)
+* Hardware Availability: (Under Preparation)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make yushakobo/quick7:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/yushakobo/quick7/rules.mk b/keyboards/yushakobo/quick7/rules.mk
new file mode 100644
index 000000000..3812422e1
--- /dev/null
+++ b/keyboards/yushakobo/quick7/rules.mk
@@ -0,0 +1,34 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+# Teensy halfkay
+# Pro Micro caterina
+# Atmel DFU atmel-dfu
+# LUFA DFU lufa-dfu
+# QMK DFU qmk-dfu
+# ATmega32A bootloadHID
+# ATmega328P USBasp
+BOOTLOADER = caterina
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = no # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+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
+RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
+MIDI_ENABLE = no # MIDI support
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = no # Audio output on port C6
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+HD44780_ENABLE = no # Enable support for HD44780 based LCDs
+
+ENCODER_ENABLE = yes # Enable support for Rotary Encoder
diff --git a/layouts/community/60_tsangan_hhkb/yanfali_wkl/keymap.c b/layouts/community/60_tsangan_hhkb/yanfali_wkl/keymap.c
new file mode 100644
index 000000000..697807bda
--- /dev/null
+++ b/layouts/community/60_tsangan_hhkb/yanfali_wkl/keymap.c
@@ -0,0 +1,25 @@
+#include QMK_KEYBOARD_H
+
+enum layer {
+ BASE,
+ FN,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_60_tsangan_hhkb(
+ 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_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,
+ LCTL_T(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_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_LALT, KC_NO, KC_LGUI, KC_SPC, KC_RGUI, KC_NO, KC_RALT
+ ),
+
+ [FN] = LAYOUT_60_tsangan_hhkb(
+ _______, 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_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, EEP_RST, RESET,
+ KC_CAPS, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______
+ ),
+
+};
diff --git a/layouts/community/75_ansi/spidey3/keymap.c b/layouts/community/75_ansi/spidey3/keymap.c
index 511fea28d..fbb6a9806 100644
--- a/layouts/community/75_ansi/spidey3/keymap.c
+++ b/layouts/community/75_ansi/spidey3/keymap.c
@@ -1,33 +1,44 @@
#include "spidey3.h"
-#define SETTINGS A(S(KC_S))
+#define CH_MENU A(S(KC_S))
+#define OSX_PSC G(S(KC_4))
+#define FN_MENU LT(_FN,KC_APP)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Linux / Win layout
[_BASE] = LAYOUT_75_ansi(
- 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, SETTINGS, KC_INS, KC_DEL,
+ 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_INS, KC_DEL,
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
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_PGUP,
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_PGDN,
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_END,
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MENU, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
// OSX layout
[_OSX] = LAYOUT_75_ansi(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_EJCT, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, OSX_PSC, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, KC_LALT, KC_LGUI, _______, _______, _______, _______, _______, _______, _______
),
+ // Numpad
+ [_NUMPAD] = LAYOUT_75_ansi(
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_NUMLOCK, KC_PEQL, KC_PSLS, KC_PAST, XXXXXXX, XXXXXXX, _______, _______, _______,
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_NUMLOCK, XXXXXXX, XXXXXXX, XXXXXXX, KC_KP_7, KC_KP_8, KC_KP_9, KC_PSLS, KC_PMNS, KC_PEQL, _______, _______,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_KP_4, KC_KP_5, KC_KP_6, KC_PAST, _______, _______, _______, _______,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_KP_1, KC_KP_2, KC_KP_3, KC_PMNS, KC_SCLN, KC_PENT, _______,
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_KP_0, KC_PDOT, KC_PCMM, KC_PPLS, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
// FN
[_FN] = LAYOUT_75_ansi(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PWR,
- _______, _______, _______, _______, _______, _______, _______, _______, X_BUL, _______, _______, X_DASH, _______, RESET, EEP_RST,
- _______, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, RGB_SPD, RGB_SPI, VLK_TOG, _______, _______, KC_VOLU,
- _______, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN, RGB_M_K, RGB_M_G, RGB_M_T, SPI_LNX, _______, _______, _______, KC_VOLD,
- _______, SPI_GLO, _______, SPI_WIN, _______, _______, _______, SPI_OSX, X(LARR), X(RARR), DEBUG, _______, KC_BRIU, KC_MUTE,
- _______, _______, _______, _______, _______, _______, _______, _______, KC_BRID, _______
+ RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_SLEP, KC_WAKE, KC_PWR,
+ EEP_RST, _______, _______, _______, _______, _______, _______, _______, X_BUL, KC_MPRV, KC_MNXT, X_DASH, _______, KC_PAUS, KC_SLCK,
+ _______, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, RGB_SPD, RGB_SPI, VLK_TOG, _______, _______, KC_BRIU,
+ _______, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN, RGB_M_K, RGB_M_G, RGB_M_T, SPI_LNX, _______, _______, _______, KC_BRID,
+ _______, SPI_GLO, _______, SPI_WIN, _______, NK_TOGG, TG(_NUMPAD),SPI_OSX, X(LARR), X(RARR), DEBUG, _______, KC_VOLU, KC_MUTE,
+ _______, _______, _______, KC_MPLY, KC_APP, _______, CH_MENU, KC_MPRV, KC_VOLD, KC_MNXT
)
};
diff --git a/layouts/community/75_ansi/spidey3/rules.mk b/layouts/community/75_ansi/spidey3/rules.mk
index d9ac1126c..fdb44b3ea 100644
--- a/layouts/community/75_ansi/spidey3/rules.mk
+++ b/layouts/community/75_ansi/spidey3/rules.mk
@@ -13,3 +13,6 @@ AUDIO_ENABLE = no
RGBLIGHT_ENABLE = yes
UNICODEMAP_ENABLE = yes
VELOCIKEY_ENABLE = yes
+
+# The following disabled to save space
+SPACE_CADET_ENABLE = no
diff --git a/lib/python/milc.py b/lib/python/milc.py
index 83edfc7f5..eb18984eb 100644
--- a/lib/python/milc.py
+++ b/lib/python/milc.py
@@ -242,15 +242,24 @@ class SubparserWrapper(object):
This also stores the default for the argument in `self.cli.default_arguments`.
"""
- if 'action' in kwargs and kwargs['action'] == 'store_boolean':
+ if kwargs.get('action') == 'store_boolean':
# Store boolean will call us again with the enable/disable flag arguments
return handle_store_boolean(self, *args, **kwargs)
self.cli.acquire_lock()
+ argument_name = self.cli.get_argument_name(*args, **kwargs)
+
self.subparser.add_argument(*args, **kwargs)
+
+ if kwargs.get('action') == 'store_false':
+ self.cli._config_store_false.append(argument_name)
+
+ if kwargs.get('action') == 'store_true':
+ self.cli._config_store_true.append(argument_name)
+
if self.submodule not in self.cli.default_arguments:
self.cli.default_arguments[self.submodule] = {}
- self.cli.default_arguments[self.submodule][self.cli.get_argument_name(*args, **kwargs)] = kwargs.get('default')
+ self.cli.default_arguments[self.submodule][argument_name] = kwargs.get('default')
self.cli.release_lock()
@@ -268,11 +277,13 @@ class MILC(object):
# Define some basic info
self.acquire_lock()
+ self._config_store_true = []
+ self._config_store_false = []
self._description = None
self._entrypoint = None
self._inside_context_manager = False
self.ansi = ansi_colors
- self.arg_only = []
+ self.arg_only = {}
self.config = self.config_source = None
self.config_file = None
self.default_arguments = {}
@@ -377,7 +388,7 @@ class MILC(object):
self.add_argument('--log-file', help='File to write log messages to')
self.add_argument('--color', action='store_boolean', default=True, help='color in output')
self.add_argument('--config-file', help='The location for the configuration file')
- self.arg_only.append('config_file')
+ self.arg_only['config_file'] = ['general']
def add_subparsers(self, title='Sub-commands', **kwargs):
if self._inside_context_manager:
@@ -427,17 +438,20 @@ class MILC(object):
raise RuntimeError('You must run this before the with statement!')
def argument_function(handler):
- if 'arg_only' in kwargs and kwargs['arg_only']:
+ subcommand_name = handler.__name__.replace("_", "-")
+
+ if kwargs.get('arg_only'):
arg_name = self.get_argument_name(*args, **kwargs)
- self.arg_only.append(arg_name)
+ if arg_name not in self.arg_only:
+ self.arg_only[arg_name] = []
+ self.arg_only[arg_name].append(subcommand_name)
del kwargs['arg_only']
- name = handler.__name__.replace("_", "-")
if handler is self._entrypoint:
self.add_argument(*args, **kwargs)
- elif name in self.subcommands:
- self.subcommands[name].add_argument(*args, **kwargs)
+ elif subcommand_name in self.subcommands:
+ self.subcommands[subcommand_name].add_argument(*args, **kwargs)
else:
raise RuntimeError('Decorated function is not entrypoint or subcommand!')
@@ -511,35 +525,37 @@ class MILC(object):
if argument in ('subparsers', 'entrypoint'):
continue
- if argument not in self.arg_only:
- # Find the argument's section
- # Underscores in command's names are converted to dashes during initialization.
- # TODO(Erovia) Find a better solution
- entrypoint_name = self._entrypoint.__name__.replace("_", "-")
- if entrypoint_name in self.default_arguments and argument in self.default_arguments[entrypoint_name]:
- argument_found = True
- section = self._entrypoint.__name__
- if argument in self.default_arguments['general']:
- argument_found = True
- section = 'general'
-
- if not argument_found:
- raise RuntimeError('Could not find argument in `self.default_arguments`. This should be impossible!')
- exit(1)
+ # Find the argument's section
+ # Underscores in command's names are converted to dashes during initialization.
+ # TODO(Erovia) Find a better solution
+ entrypoint_name = self._entrypoint.__name__.replace("_", "-")
+ if entrypoint_name in self.default_arguments and argument in self.default_arguments[entrypoint_name]:
+ argument_found = True
+ section = self._entrypoint.__name__
+ if argument in self.default_arguments['general']:
+ argument_found = True
+ section = 'general'
+
+ if not argument_found:
+ raise RuntimeError('Could not find argument in `self.default_arguments`. This should be impossible!')
+ exit(1)
+
+ if argument not in self.arg_only or section not in self.arg_only[argument]:
+ # Determine the arg value and source
+ arg_value = getattr(self.args, argument)
+ if argument in self._config_store_true and arg_value:
+ passed_on_cmdline = True
+ elif argument in self._config_store_false and not arg_value:
+ passed_on_cmdline = True
+ elif arg_value is not None:
+ passed_on_cmdline = True
+ else:
+ passed_on_cmdline = False
# Merge this argument into self.config
- if argument in self.default_arguments['general'] or argument in self.default_arguments[entrypoint_name]:
- arg_value = getattr(self.args, argument)
- if arg_value is not None:
- self.config[section][argument] = arg_value
- self.config_source[section][argument] = 'argument'
- else:
- if argument not in self.config[entrypoint_name]:
- # Check if the argument exist for this section
- arg = getattr(self.args, argument)
- if arg is not None:
- self.config[section][argument] = arg
- self.config_source[section][argument] = 'argument'
+ if passed_on_cmdline and (argument in self.default_arguments['general'] or argument in self.default_arguments[entrypoint_name] or argument not in self.config[entrypoint_name]):
+ self.config[section][argument] = arg_value
+ self.config_source[section][argument] = 'argument'
self.release_lock()
diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py
index eb524217c..394a1353b 100644
--- a/lib/python/qmk/cli/__init__.py
+++ b/lib/python/qmk/cli/__init__.py
@@ -2,6 +2,8 @@
We list each subcommand here explicitly because all the reliable ways of searching for modules are slow and delay startup.
"""
+import sys
+
from milc import cli
from . import cformat
@@ -19,5 +21,6 @@ from . import new
from . import pyformat
from . import pytest
-if not hasattr(cli, 'config_source'):
- cli.log.warning("Your QMK CLI is out of date. Please upgrade with `pip3 install --upgrade qmk` or by using your package manager.")
+if sys.version_info[0] != 3 or sys.version_info[1] < 6:
+ cli.log.error('Your Python is too old! Please upgrade to Python 3.6 or later.')
+ exit(127)
diff --git a/lib/python/qmk/cli/cformat.py b/lib/python/qmk/cli/cformat.py
index 7e3a91dcf..0cd8b6192 100644
--- a/lib/python/qmk/cli/cformat.py
+++ b/lib/python/qmk/cli/cformat.py
@@ -22,9 +22,8 @@ def cformat_run(files, all_files):
cli.log.warn('No changes detected. Use "qmk cformat -a" to format all files')
return False
if files and all_files:
- cli.log.warning('Filenames passed with -a, only formatting: %s', ','.join(cli.args.files))
- # 3.6+: Can remove the str casting, python will cast implicitly
- subprocess.run(clang_format + [str(file) for file in files], check=True)
+ cli.log.warning('Filenames passed with -a, only formatting: %s', ','.join(files))
+ subprocess.run(clang_format + [file for file in files], check=True)
cli.log.info('Successfully formatted the C code.')
except subprocess.CalledProcessError:
@@ -35,7 +34,7 @@ def cformat_run(files, all_files):
@cli.argument('-a', '--all-files', arg_only=True, action='store_true', help='Format all core files.')
@cli.argument('-b', '--base-branch', default='origin/master', help='Branch to compare to diffs to.')
@cli.argument('files', nargs='*', arg_only=True, help='Filename(s) to format.')
-@cli.subcommand("Format C code according to QMK's style.")
+@cli.subcommand("Format C code according to QMK's style.", hidden=False if cli.config.user.developer else True)
def cformat(cli):
"""Format C code according to QMK's style.
"""
diff --git a/lib/python/qmk/cli/docs.py b/lib/python/qmk/cli/docs.py
index 163c8b801..581610650 100644
--- a/lib/python/qmk/cli/docs.py
+++ b/lib/python/qmk/cli/docs.py
@@ -7,7 +7,7 @@ from milc import cli
@cli.argument('-p', '--port', default=8936, type=int, help='Port number to use.')
-@cli.subcommand('Run a local webserver for QMK documentation.')
+@cli.subcommand('Run a local webserver for QMK documentation.', hidden=False if cli.config.user.developer else True)
def docs(cli):
"""Spin up a local HTTPServer instance for the QMK docs.
"""
diff --git a/lib/python/qmk/cli/doctor.py b/lib/python/qmk/cli/doctor.py
index 3e6f6fe54..3c4624837 100755
--- a/lib/python/qmk/cli/doctor.py
+++ b/lib/python/qmk/cli/doctor.py
@@ -135,16 +135,15 @@ def check_udev_rules():
}
if udev_dir.exists():
- udev_rules = [str(rule_file) for rule_file in udev_dir.glob('*.rules')]
+ udev_rules = [rule_file for rule_file in udev_dir.glob('*.rules')]
current_rules = set()
# Collect all rules from the config files
for rule_file in udev_rules:
- with open(rule_file, "r") as fd:
- for line in fd.readlines():
- line = line.strip()
- if not line.startswith("#") and len(line):
- current_rules.add(line)
+ for line in rule_file.read_text().split('\n'):
+ line = line.strip()
+ if not line.startswith("#") and len(line):
+ current_rules.add(line)
# Check if the desired rules are among the currently present rules
for bootloader, rules in desired_rules.items():
@@ -191,7 +190,7 @@ def is_executable(command):
cli.log.debug('Found {fg_cyan}%s', command)
return True
- cli.log.error("{fg_red}Can't run `%s %s`", (command, version_arg))
+ cli.log.error("{fg_red}Can't run `%s %s`", command, version_arg)
return False
diff --git a/lib/python/qmk/cli/hello.py b/lib/python/qmk/cli/hello.py
index bee28c301..5119188a0 100755
--- a/lib/python/qmk/cli/hello.py
+++ b/lib/python/qmk/cli/hello.py
@@ -6,7 +6,7 @@ from milc import cli
@cli.argument('-n', '--name', default='World', help='Name to greet.')
-@cli.subcommand('QMK Hello World.')
+@cli.subcommand('QMK Hello World.', hidden=False if cli.config.user.developer else True)
def hello(cli):
"""Log a friendly greeting.
"""
diff --git a/lib/python/qmk/cli/json2c.py b/lib/python/qmk/cli/json2c.py
index 46c4d04bb..521840507 100755
--- a/lib/python/qmk/cli/json2c.py
+++ b/lib/python/qmk/cli/json2c.py
@@ -10,29 +10,27 @@ import qmk.path
@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
-@cli.argument('filename', arg_only=True, help='Configurator JSON file')
+@cli.argument('filename', type=qmk.path.normpath, arg_only=True, help='Configurator JSON file')
@cli.subcommand('Creates a keymap.c from a QMK Configurator export.')
def json2c(cli):
"""Generate a keymap.c from a configurator export.
This command uses the `qmk.keymap` module to generate a keymap.c from a configurator export. The generated keymap is written to stdout, or to a file if -o is provided.
"""
- cli.args.filename = qmk.path.normpath(cli.args.filename)
-
# Error checking
if not cli.args.filename.exists():
cli.log.error('JSON file does not exist!')
cli.print_usage()
exit(1)
- if str(cli.args.filename) == '-':
+ if cli.args.filename.name == '-':
# TODO(skullydazed/anyone): Read file contents from STDIN
cli.log.error('Reading from STDIN is not (yet) supported.')
cli.print_usage()
exit(1)
# Environment processing
- if cli.args.output == ('-'):
+ if cli.args.output.name == ('-'):
cli.args.output = None
# Parse the configurator json
diff --git a/lib/python/qmk/cli/kle2json.py b/lib/python/qmk/cli/kle2json.py
index 00f63d362..5268462f9 100755
--- a/lib/python/qmk/cli/kle2json.py
+++ b/lib/python/qmk/cli/kle2json.py
@@ -26,7 +26,7 @@ class CustomJSONEncoder(json.JSONEncoder):
@cli.argument('filename', help='The KLE raw txt to convert')
@cli.argument('-f', '--force', action='store_true', help='Flag to overwrite current info.json')
-@cli.subcommand('Convert a KLE layout to a Configurator JSON')
+@cli.subcommand('Convert a KLE layout to a Configurator JSON', hidden=False if cli.config.user.developer else True)
def kle2json(cli):
"""Convert a KLE layout to QMK's layout format.
""" # If filename is a path
@@ -37,12 +37,12 @@ def kle2json(cli):
file_path = Path(os.environ['ORIG_CWD'], cli.args.filename)
# Check for valid file_path for more graceful failure
if not file_path.exists():
- return cli.log.error('File {fg_cyan}%s{style_reset_all} was not found.', str(file_path))
+ return cli.log.error('File {fg_cyan}%s{style_reset_all} was not found.', file_path)
out_path = file_path.parent
raw_code = file_path.open().read()
# Check if info.json exists, allow overwrite with force
if Path(out_path, "info.json").exists() and not cli.args.force:
- cli.log.error('File {fg_cyan}%s/info.json{style_reset_all} already exists, use -f or --force to overwrite.', str(out_path))
+ cli.log.error('File {fg_cyan}%s/info.json{style_reset_all} already exists, use -f or --force to overwrite.', out_path)
return False
try:
# Convert KLE raw to x/y coordinates (using kle2xy package from skullydazed)
@@ -69,7 +69,7 @@ def kle2json(cli):
# Replace layout in keyboard json
keyboard = keyboard.replace('"LAYOUT_JSON_HERE"', layout)
# Write our info.json
- file = open(str(out_path) + "/info.json", "w")
+ file = open(out_path + "/info.json", "w")
file.write(keyboard)
file.close()
- cli.log.info('Wrote out {fg_cyan}%s/info.json', str(out_path))
+ cli.log.info('Wrote out {fg_cyan}%s/info.json', out_path)
diff --git a/lib/python/qmk/cli/new/keymap.py b/lib/python/qmk/cli/new/keymap.py
index 5ae262856..474fe7974 100755
--- a/lib/python/qmk/cli/new/keymap.py
+++ b/lib/python/qmk/cli/new/keymap.py
@@ -40,7 +40,7 @@ def new_keymap(cli):
exit(1)
# create user directory with default keymap files
- shutil.copytree(str(keymap_path_default), str(keymap_path_new), symlinks=True)
+ shutil.copytree(keymap_path_default, keymap_path_new, symlinks=True)
# end message to user
cli.log.info("%s keymap directory created in: %s", keymap, keymap_path_new)
diff --git a/lib/python/qmk/cli/pyformat.py b/lib/python/qmk/cli/pyformat.py
index a53ba40c0..146444380 100755
--- a/lib/python/qmk/cli/pyformat.py
+++ b/lib/python/qmk/cli/pyformat.py
@@ -5,7 +5,7 @@ from milc import cli
import subprocess
-@cli.subcommand("Format python code according to QMK's style.")
+@cli.subcommand("Format python code according to QMK's style.", hidden=False if cli.config.user.developer else True)
def pyformat(cli):
"""Format python code according to QMK's style.
"""
diff --git a/lib/python/qmk/cli/pytest.py b/lib/python/qmk/cli/pytest.py
index 09611d750..5417a9cb3 100644
--- a/lib/python/qmk/cli/pytest.py
+++ b/lib/python/qmk/cli/pytest.py
@@ -7,7 +7,7 @@ import subprocess
from milc import cli
-@cli.subcommand('QMK Python Unit Tests')
+@cli.subcommand('QMK Python Unit Tests', hidden=False if cli.config.user.developer else True)
def pytest(cli):
"""Run several linting/testing commands.
"""
diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py
index 3424cdf08..5d2a03c9a 100644
--- a/lib/python/qmk/commands.py
+++ b/lib/python/qmk/commands.py
@@ -5,6 +5,7 @@ import os
import platform
import subprocess
import shlex
+import shutil
import qmk.keymap
@@ -28,11 +29,12 @@ def create_make_command(keyboard, keymap, target=None):
A command that can be run to make the specified keyboard and keymap
"""
make_args = [keyboard, keymap]
+ make_cmd = 'gmake' if shutil.which('gmake') else 'make'
if target:
make_args.append(target)
- return ['make', ':'.join(make_args)]
+ return [make_cmd, ':'.join(make_args)]
def compile_configurator_json(user_keymap, bootloader=None):
diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py
index b91ba89be..69cdc8d5b 100644
--- a/lib/python/qmk/keymap.py
+++ b/lib/python/qmk/keymap.py
@@ -1,6 +1,5 @@
"""Functions that help you work with QMK keymaps.
"""
-import os
from pathlib import Path
import qmk.path
@@ -11,7 +10,7 @@ DEFAULT_KEYMAP_C = """#include QMK_KEYBOARD_H
/* THIS FILE WAS GENERATED!
*
- * This file was generated by qmk-compile-json. You may or may not want to
+ * This file was generated by qmk json2c. You may or may not want to
* edit it directly.
*/
@@ -39,6 +38,15 @@ def template(keyboard):
return DEFAULT_KEYMAP_C
+def _strip_any(keycode):
+ """Remove ANY() from a keycode.
+ """
+ if keycode.startswith('ANY(') and keycode.endswith(')'):
+ keycode = keycode[4:-1]
+
+ return keycode
+
+
def generate(keyboard, layout, layers):
"""Returns a keymap.c for the specified keyboard, layout, and layers.
@@ -53,9 +61,12 @@ def generate(keyboard, layout, layers):
An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode.
"""
layer_txt = []
+
for layer_num, layer in enumerate(layers):
if layer_num != 0:
layer_txt[-1] = layer_txt[-1] + ','
+
+ layer = map(_strip_any, layer)
layer_keys = ', '.join(layer)
layer_txt.append('\t[%s] = %s(%s)' % (layer_num, layout, layer_keys))
@@ -115,7 +126,7 @@ def list_keymaps(keyboard_name):
while kb_path != keyboards_dir:
keymaps_dir = kb_path / "keymaps"
if keymaps_dir.exists():
- names = names.union([keymap for keymap in os.listdir(str(keymaps_dir)) if (keymaps_dir / keymap / "keymap.c").is_file()])
+ names = names.union([keymap for keymap in keymaps_dir.iterdir() if (keymaps_dir / keymap / "keymap.c").is_file()])
kb_path = kb_path.parent
# if community layouts are supported, get them
@@ -123,6 +134,6 @@ def list_keymaps(keyboard_name):
for layout in rules_mk["LAYOUTS"].split():
cl_path = Path.cwd() / "layouts" / "community" / layout
if cl_path.exists():
- names = names.union([keymap for keymap in os.listdir(str(cl_path)) if (cl_path / keymap / "keymap.c").is_file()])
+ names = names.union([keymap for keymap in cl_path.iterdir() if (cl_path / keymap / "keymap.c").is_file()])
return sorted(names)
diff --git a/quantum/debounce/eager_pk.c b/quantum/debounce/eager_pk.c
index 76b978d05..93a40ad44 100644
--- a/quantum/debounce/eager_pk.c
+++ b/quantum/debounce/eager_pk.c
@@ -27,13 +27,7 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred.
# define DEBOUNCE 5
#endif
-#if (MATRIX_COLS <= 8)
-# define ROW_SHIFTER ((uint8_t)1)
-#elif (MATRIX_COLS <= 16)
-# define ROW_SHIFTER ((uint16_t)1)
-#elif (MATRIX_COLS <= 32)
-# define ROW_SHIFTER ((uint32_t)1)
-#endif
+#define ROW_SHIFTER ((matrix_row_t)1)
#define debounce_counter_t uint8_t
@@ -44,6 +38,16 @@ static bool matrix_need_update;
#define DEBOUNCE_ELAPSED 251
#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
+static uint8_t wrapping_timer_read(void) {
+ static uint16_t time = 0;
+ static uint8_t last_result = 0;
+ uint16_t new_time = timer_read();
+ uint16_t diff = new_time - time;
+ time = new_time;
+ last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
+ return last_result;
+}
+
void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
@@ -59,7 +63,7 @@ void debounce_init(uint8_t num_rows) {
}
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint8_t current_time = timer_read() % MAX_DEBOUNCE;
+ uint8_t current_time = wrapping_timer_read();
if (counters_need_update) {
update_debounce_counters(num_rows, current_time);
}
diff --git a/quantum/debounce/eager_pr.c b/quantum/debounce/eager_pr.c
index 173ad15ee..d12931fdd 100644
--- a/quantum/debounce/eager_pr.c
+++ b/quantum/debounce/eager_pr.c
@@ -36,6 +36,16 @@ static bool counters_need_update;
#define DEBOUNCE_ELAPSED 251
#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
+static uint8_t wrapping_timer_read(void) {
+ static uint16_t time = 0;
+ static uint8_t last_result = 0;
+ uint16_t new_time = timer_read();
+ uint16_t diff = new_time - time;
+ time = new_time;
+ last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
+ return last_result;
+}
+
void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
@@ -48,7 +58,7 @@ void debounce_init(uint8_t num_rows) {
}
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint8_t current_time = timer_read() % MAX_DEBOUNCE;
+ uint8_t current_time = wrapping_timer_read();
bool needed_update = counters_need_update;
if (counters_need_update) {
update_debounce_counters(num_rows, current_time);
diff --git a/quantum/debounce/sym_pk.c b/quantum/debounce/sym_pk.c
new file mode 100644
index 000000000..f404cf9c4
--- /dev/null
+++ b/quantum/debounce/sym_pk.c
@@ -0,0 +1,111 @@
+/*
+Copyright 2017 Alex Ong<the.onga@gmail.com>
+Copyright 2020 Andrei Purdea<andrei@purdea.ro>
+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/>.
+*/
+
+/*
+Basic symmetric per-key algorithm. Uses an 8-bit counter per key.
+When no state changes have occured for DEBOUNCE milliseconds, we push the state.
+*/
+
+#include "matrix.h"
+#include "timer.h"
+#include "quantum.h"
+#include <stdlib.h>
+
+#ifndef DEBOUNCE
+# define DEBOUNCE 5
+#endif
+
+#define ROW_SHIFTER ((matrix_row_t)1)
+
+#define debounce_counter_t uint8_t
+
+static debounce_counter_t *debounce_counters;
+static bool counters_need_update;
+
+#define DEBOUNCE_ELAPSED 251
+#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
+
+static uint8_t wrapping_timer_read(void) {
+ static uint16_t time = 0;
+ static uint8_t last_result = 0;
+ uint16_t new_time = timer_read();
+ uint16_t diff = new_time - time;
+ time = new_time;
+ last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
+ return last_result;
+}
+
+void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
+void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
+
+// we use num_rows rather than MATRIX_ROWS to support split keyboards
+void debounce_init(uint8_t num_rows) {
+ debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t));
+ int i = 0;
+ for (uint8_t r = 0; r < num_rows; r++) {
+ for (uint8_t c = 0; c < MATRIX_COLS; c++) {
+ debounce_counters[i++] = DEBOUNCE_ELAPSED;
+ }
+ }
+}
+
+void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ uint8_t current_time = wrapping_timer_read();
+ if (counters_need_update) {
+ update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, current_time);
+ }
+
+ if (changed) {
+ start_debounce_counters(raw, cooked, num_rows, current_time);
+ }
+}
+
+void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
+ counters_need_update = false;
+ debounce_counter_t *debounce_pointer = debounce_counters;
+ for (uint8_t row = 0; row < num_rows; row++) {
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ if (*debounce_pointer != DEBOUNCE_ELAPSED) {
+ if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) {
+ *debounce_pointer = DEBOUNCE_ELAPSED;
+ cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col));
+ } else {
+ counters_need_update = true;
+ }
+ }
+ debounce_pointer++;
+ }
+ }
+}
+
+void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
+ debounce_counter_t *debounce_pointer = debounce_counters;
+ for (uint8_t row = 0; row < num_rows; row++) {
+ matrix_row_t delta = raw[row] ^ cooked[row];
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ if (delta & (ROW_SHIFTER << col)) {
+ if (*debounce_pointer == DEBOUNCE_ELAPSED) {
+ *debounce_pointer = current_time;
+ counters_need_update = true;
+ }
+ } else {
+ *debounce_pointer = DEBOUNCE_ELAPSED;
+ }
+ debounce_pointer++;
+ }
+ }
+}
+
+bool debounce_active(void) { return true; }
diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c
index ab74222d1..66c166ce4 100644
--- a/quantum/dip_switch.c
+++ b/quantum/dip_switch.c
@@ -52,13 +52,13 @@ void dip_switch_read(bool forced) {
for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
dip_switch_state[i] = !readPin(dip_switch_pad[i]);
dip_switch_mask |= dip_switch_state[i] << i;
- if (last_dip_switch_state[i] ^ dip_switch_state[i] || forced) {
+ if (last_dip_switch_state[i] != dip_switch_state[i] || forced) {
has_dip_state_changed = true;
dip_switch_update_kb(i, dip_switch_state[i]);
}
}
if (has_dip_state_changed) {
dip_switch_update_mask_kb(dip_switch_mask);
+ memcpy(last_dip_switch_state, dip_switch_state, sizeof(dip_switch_state));
}
- memcpy(last_dip_switch_state, dip_switch_state, sizeof(&dip_switch_state));
}
diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h
index 8da5ae6aa..02ee22a12 100644
--- a/quantum/keymap_extras/keymap_fr_ch.h
+++ b/quantum/keymap_extras/keymap_fr_ch.h
@@ -13,97 +13,226 @@
* 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 KEYMAP_FR_CH
-#define KEYMAP_FR_CH
-#include "keymap.h"
-
-// normal characters
-#define FR_CH_Z KC_Y
-#define FR_CH_Y KC_Z
-
-#define FR_CH_A KC_A
-#define FR_CH_B KC_B
-#define FR_CH_C KC_C
-#define FR_CH_D KC_D
-#define FR_CH_E KC_E
-#define FR_CH_F KC_F
-#define FR_CH_G KC_G
-#define FR_CH_H KC_H
-#define FR_CH_I KC_I
-#define FR_CH_J KC_J
-#define FR_CH_K KC_K
-#define FR_CH_L KC_L
-#define FR_CH_M KC_M
-#define FR_CH_N KC_N
-#define FR_CH_O KC_O
-#define FR_CH_P KC_P
-#define FR_CH_Q KC_Q
-#define FR_CH_R KC_R
-#define FR_CH_S KC_S
-#define FR_CH_T KC_T
-#define FR_CH_U KC_U
-#define FR_CH_V KC_V
-#define FR_CH_W KC_W
-#define FR_CH_X KC_X
-
-#define FR_CH_0 KC_0
-#define FR_CH_1 KC_1
-#define FR_CH_2 KC_2
-#define FR_CH_3 KC_3
-#define FR_CH_4 KC_4
-#define FR_CH_5 KC_5
-#define FR_CH_6 KC_6
-#define FR_CH_7 KC_7
-#define FR_CH_8 KC_8
-#define FR_CH_9 KC_9
+#pragma once
-#define FR_CH_DOT KC_DOT
-#define FR_CH_COMM KC_COMM
+#include "keymap.h"
-#define FR_CH_QUOT KC_MINS
-#define FR_CH_AE KC_QUOT
-#define FR_CH_UE KC_LBRC
-#define FR_CH_OE KC_SCLN
+// clang-format off
-#define FR_CH_CIRC KC_EQL // accent circumflex ^ and grave ` and ~
-#define FR_CH_LESS KC_NUBS // < and > and backslash
-#define FR_CH_MINS KC_SLSH // - and _
-#define FR_CH_DLR KC_BSLS // $, £ and }
-#define FR_CH_PARA KC_GRV // § and ring °
-#define FR_CH_DIAE KC_RBRC // accent ¨
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ ^ │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ è │ ¨ │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ é │ à │ $ │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_SECT KC_GRV // §
+#define CH_1 KC_1 // 1
+#define CH_2 KC_2 // 2
+#define CH_3 KC_3 // 3
+#define CH_4 KC_4 // 4
+#define CH_5 KC_5 // 5
+#define CH_6 KC_6 // 6
+#define CH_7 KC_7 // 7
+#define CH_8 KC_8 // 8
+#define CH_9 KC_9 // 9
+#define CH_0 KC_0 // 0
+#define CH_QUOT KC_MINS // '
+#define CH_CIRC KC_EQL // ^ (dead)
+// Row 2
+#define CH_Q KC_Q // Q
+#define CH_W KC_W // W
+#define CH_E KC_E // E
+#define CH_R KC_R // R
+#define CH_T KC_T // T
+#define CH_Z KC_Y // Z
+#define CH_U KC_U // U
+#define CH_I KC_I // I
+#define CH_O KC_O // O
+#define CH_P KC_P // P
+#define CH_EGRV KC_LBRC // è
+#define CH_DIAE KC_RBRC // ¨ (dead)
+// Row 3
+#define CH_A KC_A // A
+#define CH_S KC_S // S
+#define CH_D KC_D // D
+#define CH_F KC_F // F
+#define CH_G KC_G // G
+#define CH_H KC_H // H
+#define CH_J KC_J // J
+#define CH_K KC_K // K
+#define CH_L KC_L // L
+#define CH_EACU KC_SCLN // é
+#define CH_AGRV KC_QUOT // à
+#define CH_DLR KC_NUHS // $
+// Row 4
+#define CH_LABK KC_NUBS // <
+#define CH_Y KC_Z // Y
+#define CH_X KC_X // X
+#define CH_C KC_C // C
+#define CH_V KC_V // V
+#define CH_B KC_B // B
+#define CH_N KC_N // N
+#define CH_M KC_M // M
+#define CH_COMM KC_COMM // ,
+#define CH_DOT KC_DOT // .
+#define CH_MINS KC_SLSH // -
-// shifted characters
-#define FR_CH_RING LSFT(KC_GRV) // °
-#define FR_CH_EXLM LSFT(KC_RBRC) // !
-#define FR_CH_PLUS LSFT(KC_1) // +
-#define FR_CH_DQOT LSFT(KC_2) // "
-#define FR_CH_ASTR LSFT(KC_3) // *
-#define FR_CH_PERC LSFT(KC_5) // %
-#define FR_CH_AMPR LSFT(KC_6) // &
-#define FR_CH_SLSH LSFT(KC_7) // /
-#define FR_CH_LPRN LSFT(KC_8) // (
-#define FR_CH_RPRN LSFT(KC_9) // )
-#define FR_CH_EQL LSFT(KC_0) // =
-#define FR_CH_QST LSFT(FR_CH_QUOT) // ?
-#define FR_CH_MORE LSFT(FR_CH_LESS) // >
-#define FR_CH_COLN LSFT(KC_DOT) // :
-#define FR_CH_SCLN LSFT(KC_COMM) // ;
-#define FR_CH_UNDS LSFT(FR_CH_MINS) // _
-#define FR_CH_CCED LSFT(KC_4) // ç
-#define FR_CH_GRV LSFT(FR_CH_CIRC) // accent grave `
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ ° │ + │ " │ * │ ç │ % │ & │ / │ ( │ ) │ = │ ? │ ` │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │   │   │   │   │   │   │   │   │   │   │ ü │ ! │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │   │   │   │   │   │   │   │   │   │ ö │ ä │ £ │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ > │   │   │   │   │   │   │   │ ; │ : │ _ │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_DEG S(CH_SECT) // °
+#define CH_PLUS S(CH_1) // +
+#define CH_DQUO S(CH_2) // "
+#define CH_ASTR S(CH_3) // *
+#define CH_CCED S(CH_4) // ç
+#define CH_PERC S(CH_5) // %
+#define CH_AMPR S(CH_6) // &
+#define CH_SLSH S(CH_7) // /
+#define CH_LPRN S(CH_8) // (
+#define CH_RPRN S(CH_9) // )
+#define CH_EQL S(CH_0) // =
+#define CH_QUES S(CH_QUOT) // ?
+#define CH_GRV S(CH_CIRC) // ` (dead)
+// Row 2
+#define CH_UDIA S(CH_EGRV) // ü
+#define CH_EXLM S(CH_DIAE) // !
+// Row 3
+#define CH_ODIA S(CH_EACU) // ö
+#define CH_ADIA S(CH_AGRV) // ä
+#define CH_PND S(CH_DLR) // £
+// Row 4
+#define CH_RABK S(CH_LABK) // >
+#define CH_SCLN S(CH_COMM) // ;
+#define CH_COLN S(CH_DOT) // :
+#define CH_UNDS S(CH_MINS) // _
-// Alt Gr-ed characters
-#define FR_CH_LCBR ALGR(KC_QUOT) // {
-#define FR_CH_LBRC ALGR(KC_LBRC) // [
-#define FR_CH_RBRC ALGR(KC_9) // ]
-#define FR_CH_RCBR ALGR(KC_0) // }
-#define FR_CH_BSLS ALGR(FR_CH_LESS) // backslash
-#define FR_CH_AT ALGR(KC_2) // @
-#define FR_CH_EURO ALGR(KC_E) // €
-#define FR_CH_TILD ALGR(FR_CH_CIRC) // ~
-#define FR_CH_PIPE ALGR(KC_1) // |
-#define FR_CH_HASH ALGR(KC_3) // #
-#define FR_CH_ACUT ALGR(FR_CH_QUOT) // accent acute ´
+/* AltGr symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │   │ ¦ │ @ │ # │   │   │ ¬ │ | │ ¢ │   │   │ ´ │ ~ │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │   │   │ € │   │   │   │   │   │   │   │ [ │ ] │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │   │   │   │   │   │   │   │   │   │   │ { │ } │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ \ │   │   │   │   │   │   │   │   │   │   │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_BRKP ALGR(CH_1) // ¦
+#define CH_AT ALGR(CH_2) // @
+#define CH_HASH ALGR(CH_3) // #
+#define CH_NOT ALGR(CH_6) // ¬
+#define CH_PIPE ALGR(CH_7) // |
+#define CH_CENT ALGR(CH_8) // ¢
+#define CH_ACUT ALGR(CH_QUOT) // ´ (dead)
+#define CH_TILD ALGR(CH_CIRC) // ~ (dead)
+// Row 2
+#define CH_EURO ALGR(CH_E) // €
+#define CH_LBRC ALGR(CH_EGRV) // [
+#define CH_RBRC ALGR(CH_DIAE) // ]
+// Row 3
+#define CH_LCBR ALGR(CH_AGRV) // {
+#define CH_RCBR ALGR(CH_DLR) // }
+// Row 4
+#define CH_BSLS ALGR(CH_LABK) // (backslash)
-#endif
+// DEPRECATED
+#define FR_CH_Z CH_Z
+#define FR_CH_Y CH_Y
+#define FR_CH_A CH_A
+#define FR_CH_B CH_B
+#define FR_CH_C CH_C
+#define FR_CH_D CH_D
+#define FR_CH_E CH_E
+#define FR_CH_F CH_F
+#define FR_CH_G CH_G
+#define FR_CH_H CH_H
+#define FR_CH_I CH_I
+#define FR_CH_J CH_J
+#define FR_CH_K CH_K
+#define FR_CH_L CH_L
+#define FR_CH_M CH_M
+#define FR_CH_N CH_N
+#define FR_CH_O CH_O
+#define FR_CH_P CH_P
+#define FR_CH_Q CH_Q
+#define FR_CH_R CH_R
+#define FR_CH_S CH_S
+#define FR_CH_T CH_T
+#define FR_CH_U CH_U
+#define FR_CH_V CH_V
+#define FR_CH_W CH_W
+#define FR_CH_X CH_X
+#define FR_CH_0 CH_0
+#define FR_CH_1 CH_1
+#define FR_CH_2 CH_2
+#define FR_CH_3 CH_3
+#define FR_CH_4 CH_4
+#define FR_CH_5 CH_5
+#define FR_CH_6 CH_6
+#define FR_CH_7 CH_7
+#define FR_CH_8 CH_8
+#define FR_CH_9 CH_9
+#define FR_CH_DOT CH_DOT
+#define FR_CH_COMM CH_COMM
+#define FR_CH_QUOT CH_QUOT
+#define FR_CH_AE CH_AGRV
+#define FR_CH_UE CH_EGRV
+#define FR_CH_OE CH_EACU
+#define FR_CH_CIRC CH_CIRC
+#define FR_CH_LESS CH_LABK
+#define FR_CH_MINS CH_MINS
+#define FR_CH_DLR CH_DLR
+#define FR_CH_PARA CH_SECT
+#define FR_CH_DIAE CH_DIAE
+#define FR_CH_RING CH_DEG
+#define FR_CH_EXLM CH_EXLM
+#define FR_CH_PLUS CH_PLUS
+#define FR_CH_DQOT CH_DQUO
+#define FR_CH_ASTR CH_ASTR
+#define FR_CH_PERC CH_PERC
+#define FR_CH_AMPR CH_AMPR
+#define FR_CH_SLSH CH_SLSH
+#define FR_CH_LPRN CH_LPRN
+#define FR_CH_RPRN CH_RPRN
+#define FR_CH_EQL CH_EQL
+#define FR_CH_QST CH_QUES
+#define FR_CH_MORE CH_RABK
+#define FR_CH_COLN CH_COLN
+#define FR_CH_SCLN CH_SCLN
+#define FR_CH_UNDS CH_UNDS
+#define FR_CH_CCED CH_CCED
+#define FR_CH_GRV CH_GRV
+#define FR_CH_LCBR CH_LCBR
+#define FR_CH_LBRC CH_LBRC
+#define FR_CH_RBRC CH_RBRC
+#define FR_CH_RCBR CH_RCBR
+#define FR_CH_BSLS CH_BSLS
+#define FR_CH_AT CH_AT
+#define FR_CH_EURO CH_EURO
+#define FR_CH_TILD CH_TILD
+#define FR_CH_PIPE CH_PIPE
+#define FR_CH_HASH CH_HASH
+#define FR_CH_ACUT CH_ACUT
diff --git a/quantum/keymap_extras/keymap_french_osx.h b/quantum/keymap_extras/keymap_french_osx.h
index 3a231874a..d0132a2d8 100644
--- a/quantum/keymap_extras/keymap_french_osx.h
+++ b/quantum/keymap_extras/keymap_french_osx.h
@@ -13,80 +13,248 @@
* 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 KEYMAP_FRENCH_OSX_H
-#define KEYMAP_FRENCH_OSX_H
-#include "keymap.h"
-
-// Normal characters
-#define FR_AT KC_GRV
-#define FR_AMP KC_1
-#define FR_EACU KC_2
-#define FR_QUOT KC_3
-#define FR_APOS KC_4
-#define FR_LPRN KC_5
-#define FR_SECT KC_6
-#define FR_EGRV KC_7
-#define FR_EXLM KC_8
-#define FR_CCED KC_9
-#define FR_AGRV KC_0
-#define FR_RPRN KC_MINS
-#define FR_MINS KC_EQL
-
-#define FR_A KC_Q
-#define FR_Z KC_W
-#define FR_CIRC KC_LBRC
-#define FR_DLR KC_RBRC
-
-#define FR_Q KC_A
-#define FR_M KC_SCLN
-#define FR_UGRV KC_QUOT
-#define FR_GRV KC_NUHS
-
-#define FR_LESS KC_NUBS
-#define FR_W KC_Z
-#define FR_COMM KC_M
-#define FR_SCLN KC_COMM
-#define FR_COLN KC_DOT
-#define FR_EQL KC_SLSH
+#pragma once
-// Shifted characters
-#define FR_HASH LSFT(KC_GRV)
-#define FR_1 LSFT(KC_1)
-#define FR_2 LSFT(KC_2)
-#define FR_3 LSFT(KC_3)
-#define FR_4 LSFT(KC_4)
-#define FR_5 LSFT(KC_5)
-#define FR_6 LSFT(KC_6)
-#define FR_7 LSFT(KC_7)
-#define FR_8 LSFT(KC_8)
-#define FR_9 LSFT(KC_9)
-#define FR_0 LSFT(KC_0)
-#define FR_UNDS LSFT(FR_MINS)
+#include "keymap.h"
-#define FR_UMLT LSFT(FR_CIRC)
-#define FR_ASTR LSFT(FR_DLR)
+// clang-format off
-#define FR_PERC LSFT(FR_UGRV)
-#define FR_PND LSFT(FR_GRV)
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ @ │ & │ é │ " │ ' │ ( │ § │ è │ ! │ ç │ à │ ) │ - │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ $ │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ ù │ ` │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ < │ W │ X │ C │ V │ B │ N │ , │ ; │ : │ = │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define FR_AT KC_GRV // @
+#define FR_AMPR KC_1 // &
+#define FR_LEAC KC_2 // é
+#define FR_DQUO KC_3 // "
+#define FR_QUOT KC_4 // '
+#define FR_LPRN KC_5 // (
+#define FR_SECT KC_6 // §
+#define FR_LEGR KC_7 // è
+#define FR_EXLM KC_8 // !
+#define FR_LCCE KC_9 // ç
+#define FR_LAGR KC_0 // à
+#define FR_RPRN KC_MINS // )
+#define FR_MINS KC_EQL // -
+// Row 2
+#define FR_A KC_Q // A
+#define FR_Z KC_W // Z
+#define FR_E KC_E // E
+#define FR_R KC_R // R
+#define FR_T KC_T // T
+#define FR_Y KC_Y // Y
+#define FR_U KC_U // U
+#define FR_I KC_I // I
+#define FR_O KC_O // O
+#define FR_P KC_P // P
+#define FR_CIRC KC_LBRC // ^
+#define FR_DLR KC_RBRC // $
+// Row 3
+#define FR_Q KC_A // Q
+#define FR_S KC_S // S
+#define FR_D KC_D // D
+#define FR_F KC_F // F
+#define FR_G KC_G // G
+#define FR_H KC_H // H
+#define FR_J KC_J // J
+#define FR_K KC_K // K
+#define FR_L KC_L // L
+#define FR_M KC_SCLN // M
+#define FR_LUGR KC_QUOT // ù
+#define FR_GRV KC_NUHS // `
+// Row 4
+#define FR_LABK KC_NUBS // <
+#define FR_W KC_Z // W
+#define FR_X KC_X // X
+#define FR_C KC_C // C
+#define FR_V KC_V // V
+#define FR_B KC_B // B
+#define FR_N KC_N // N
+#define FR_COMM KC_M // ,
+#define FR_SCLN KC_COMM // ;
+#define FR_COLN KC_DOT // :
+#define FR_EQL KC_SLSH // =
-#define FR_GRTR LSFT(FR_LESS)
-#define FR_QUES LSFT(FR_COMM)
-#define FR_DOT LSFT(FR_SCLN)
-#define FR_SLSH LSFT(FR_COLN)
-#define FR_PLUS LSFT(FR_EQL)
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ # │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ° │ _ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │ ¨ │ * │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │   │   │   │   │   │   │   │   │   │   │ % │ £ │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ > │   │   │   │   │   │   │ ? │ . │ / │ + │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define FR_HASH S(FR_AT) // #
+#define FR_1 S(FR_AMPR) // 1
+#define FR_2 S(FR_LEAC) // 2
+#define FR_3 S(FR_DQUO) // 3
+#define FR_4 S(FR_QUOT) // 4
+#define FR_5 S(FR_LPRN) // 5
+#define FR_6 S(FR_SECT) // 6
+#define FR_7 S(FR_LEGR) // 7
+#define FR_8 S(FR_EXLM) // 8
+#define FR_9 S(FR_LCCE) // 9
+#define FR_0 S(FR_LAGR) // 0
+#define FR_DEG S(FR_RPRN) // °
+#define FR_UNDS S(FR_MINS) // _
+// Row 2
+#define FR_DIAE S(FR_CIRC) // ¨ (dead)
+#define FR_ASTR S(FR_DLR) // *
+// Row 3
+#define FR_PERC S(FR_LUGR) // %
+#define FR_PND S(FR_GRV) // £
+// Row 4
+#define FR_RABK S(FR_LABK) // >
+#define FR_QUES S(FR_COMM) // ?
+#define FR_DOT S(FR_SCLN) // .
+#define FR_SLSH S(FR_COLN) // /
+#define FR_PLUS S(FR_EQL) // +
-// Alted characters
-#define FR_LCBR LALT(KC_5)
-#define FR_RCBR LALT(FR_RPRN)
-#define FR_EURO LALT(KC_E)
-#define FR_BULT LALT(FR_DLR)
-#define FR_TILD LALT(KC_N)
+/* Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ • │  │ ë │ “ │ ‘ │ { │ ¶ │ « │ ¡ │ Ç │ Ø │ } │ — │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ Æ │ Â │ Ê │ ® │ † │ Ú │ º │ î │ Œ │ π │ Ô │ € │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ ‡ │ Ò │ ∂ │ ƒ │ fi │ Ì │ Ï │ È │ ¬ │ µ │ Ù │   │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≤ │ ‹ │ ≈ │ © │ ◊ │ ß │ ~ │ ∞ │ … │ ÷ │ ≠ │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define FR_BULT A(FR_AT) // •
+#define FR_APPL A(FR_AMPR) //  (Apple logo)
+#define FR_LEDI A(FR_LEAC) // ë
+#define FR_LDQU A(FR_DQUO) // “
+#define FR_LSQU A(FR_QUOT) // ‘
+#define FR_LCBR A(FR_LPRN) // {
+#define FR_PILC A(FR_SECT) // ¶
+#define FR_LDAQ A(FR_LEGR) // «
+#define FR_IEXL A(FR_EXLM) // ¡
+#define FR_CCCE A(FR_LCCE) // Ç
+#define FR_OSTR A(FR_LAGR) // Ø
+#define FR_RCBR A(FR_RPRN) // }
+#define FR_MDSH A(FR_MINS) // —
+// Row 2
+#define FR_AE A(FR_A) // Æ
+#define FR_CACI A(FR_Z) // Â
+#define FR_ECIR A(FR_E) // Ê
+#define FR_REGD A(FR_R) // ®
+#define FR_DAGG A(FR_T) // †
+#define FR_CUAC A(FR_Y) // Ú
+#define FR_MORD A(FR_U) // º
+#define FR_LICI A(FR_I) // î
+#define FR_OE A(FR_O) // Œ
+#define FR_PI A(FR_P) // π
+#define FR_OCIR A(FR_CIRC) // Ô
+#define FR_EURO A(FR_DLR) // €
+// Row 3
+#define FR_DDAG A(FR_Q) // ‡
+#define FR_COGR A(FR_S) // Ò
+#define FR_PDIF A(FR_D) // ∂
+#define FR_FHK A(FR_F) // ƒ
+#define FR_FI A(FR_G) // fi
+#define FR_CIGR A(FR_H) // Ì
+#define FR_CIDI A(FR_J) // Ï
+#define FR_CEGR A(FR_K) // È
+#define FR_NOT A(FR_L) // ¬
+#define FR_MICR A(FR_M) // µ
+#define FR_CUGR A(FR_LUGR) // Ù
+// Row 4
+#define FR_LTEQ A(FR_LABK) // ≤
+#define FR_LSAQ A(FR_W) // ‹
+#define FR_AEQL A(FR_X) // ≈
+#define FR_COPY A(FR_C) // ©
+#define FR_LOZN A(FR_V) // ◊
+#define FR_SS A(FR_B) // ß
+#define FR_TILD A(FR_N) // ~ (dead)
+#define FR_INFN A(FR_COMM) // ∞
+#define FR_ELLP A(FR_SCLN) // …
+#define FR_DIV A(FR_COLN) // ÷
+#define FR_NEQL A(FR_EQL) // ≠
-// Shift+Alt-ed characters
-#define FR_LBRC LSFT(LALT(KC_5))
-#define FR_RBRC LSFT(LALT(FR_RPRN))
-#define FR_PIPE LSFT(LALT(KC_L))
-#define FR_BSLS LSFT(LALT(FR_COLN))
+/* Shift+Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ Ÿ │ ´ │ „ │   │   │ [ │ å │ » │ Û │ Á │   │ ] │ – │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │   │ Å │   │ ‚ │ ™ │   │ ª │ ï │   │ ∏ │   │ ¥ │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ Ω │ ∑ │ ∆ │ · │ fl │ Î │ Í │ Ë │ | │ Ó │ ‰ │   │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≥ │ › │ ⁄ │ ¢ │ √ │ ∫ │ ı │ ¿ │   │ \ │ ± │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define FR_CYDI S(A(FR_AT)) // Ÿ
+#define FR_ACUT S(A(FR_AMPR)) // ´ (dead)
+#define FR_DLQU S(A(FR_LEAC)) // „
+#define FR_LBRC S(A(FR_LPRN)) // [
+#define FR_LARI S(A(FR_SECT)) // å
+#define FR_RDAQ S(A(FR_LEGR)) // »
+#define FR_CUCI S(A(FR_EXLM)) // Û
+#define FR_CAAC S(A(FR_LCCE)) // Á
+#define FR_RBRC S(A(FR_RPRN)) // ]
+#define FR_NDSH S(A(FR_MINS)) // –
+// Row 2
+#define FR_CARI S(A(FR_Z)) // Å
+#define FR_SLQU S(A(FR_R)) // ‚
+#define FR_TM S(A(FR_T)) // ™
+#define FR_FORD S(A(FR_U)) // ª
+#define FR_LIDI S(A(FR_I)) // ï
+#define FR_NARP S(A(FR_P)) // ∏
+#define FR_YEN S(A(FR_DLR)) // ¥
+// Row 3
+#define FR_OMEG S(A(FR_Q)) // Ω
+#define FR_NARS S(A(FR_S)) // ∑
+#define FR_INCR S(A(FR_D)) // ∆
+#define FR_MDDT S(A(FR_F)) // ·
+#define FR_FL S(A(FR_G)) // fl
+#define FR_CICI S(A(FR_H)) // Î
+#define FR_CIAC S(A(FR_J)) // Í
+#define FR_CEDI S(A(FR_K)) // Ë
+#define FR_PIPE S(A(FR_L)) // |
+#define FR_COAC S(A(FR_M)) // Ó
+#define FR_PERM S(A(FR_LUGR)) // ‰
+// Row 4
+#define FR_GTEQ S(A(FR_LABK)) // ≥
+#define FR_LSAQ S(A(FR_W)) // ›
+#define FR_FRSL S(A(FR_X)) // ⁄
+#define FR_CENT S(A(FR_C)) // ¢
+#define FR_SQRT S(A(FR_V)) // √
+#define FR_INTG S(A(FR_B)) // ∫
+#define FR_DLSI S(A(FR_N)) // ı
+#define FR_IQUE S(A(FR_COMM)) // ¿
+#define FR_BSLS S(A(FR_COLN)) // (backslash)
+#define FR_PLMN S(A(FR_EQL)) // ±
-#endif
+// DEPRECATED
+#define FR_AMP FR_AMPR
+#define FR_EACU FR_LEAC
+#define FR_APOS FR_QUOT
+#define FR_EGRV FR_LEGR
+#define FR_CCED FR_LCCE
+#define FR_AGRV FR_LAGR
+#define FR_UGRV FR_LUGR
+#define FR_LESS FR_LABK
+#define FR_UMLT FR_DIAE
+#define FR_GRTR FR_RABK
diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h
index 19b362758..07f4503a1 100644
--- a/quantum/keymap_extras/keymap_german_ch.h
+++ b/quantum/keymap_extras/keymap_german_ch.h
@@ -13,105 +13,170 @@
* 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 KEYMAP_SWISS_GERMAN
-#define KEYMAP_SWISS_GERMAN
+
+#pragma once
#include "keymap.h"
-// normal characters
-#define CH_Z KC_Y
-#define CH_Y KC_Z
+// clang-format off
-#define CH_A KC_A
-#define CH_B KC_B
-#define CH_C KC_C
-#define CH_D KC_D
-#define CH_E KC_E
-#define CH_F KC_F
-#define CH_G KC_G
#ifdef CH_H
// The ChibiOS ch.h file defines this...
# undef CH_H
#endif
-#define CH_H KC_H
-#define CH_I KC_I
-#define CH_J KC_J
-#define CH_K KC_K
-#define CH_L KC_L
-#define CH_M KC_M
-#define CH_N KC_N
-#define CH_O KC_O
-#define CH_P KC_P
-#define CH_Q KC_Q
-#define CH_R KC_R
-#define CH_S KC_S
-#define CH_T KC_T
-#define CH_U KC_U
-#define CH_V KC_V
-#define CH_W KC_W
-#define CH_X KC_X
-
-#define CH_0 KC_0
-#define CH_1 KC_1
-#define CH_2 KC_2
-#define CH_3 KC_3
-#define CH_4 KC_4
-#define CH_5 KC_5
-#define CH_6 KC_6
-#define CH_7 KC_7
-#define CH_8 KC_8
-#define CH_9 KC_9
-
-#define CH_DOT KC_DOT
-#define CH_COMM KC_COMM
-
-#define CH_QUOT KC_MINS // ' ? ´
-#define CH_AE KC_QUOT
-#define CH_UE KC_LBRC
-#define CH_OE KC_SCLN
-#define CH_PARA KC_GRAVE // secction sign § and °
-#define CH_CARR KC_EQL // carret ^ ` ~
-#define CH_DIER KC_RBRC // dieresis ¨ ! ]
-#define CH_DLR KC_BSLS // $ £ }
-#define CH_LESS KC_NUBS // < and > and backslash
-#define CH_MINS KC_SLSH // - and _
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ ^ │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ ü │ ¨ │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ö │ ä │ $ │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_SECT KC_GRV // §
+#define CH_1 KC_1 // 1
+#define CH_2 KC_2 // 2
+#define CH_3 KC_3 // 3
+#define CH_4 KC_4 // 4
+#define CH_5 KC_5 // 5
+#define CH_6 KC_6 // 6
+#define CH_7 KC_7 // 7
+#define CH_8 KC_8 // 8
+#define CH_9 KC_9 // 9
+#define CH_0 KC_0 // 0
+#define CH_QUOT KC_MINS // '
+#define CH_CIRC KC_EQL // ^ (dead)
+// Row 2
+#define CH_Q KC_Q // Q
+#define CH_W KC_W // W
+#define CH_E KC_E // E
+#define CH_R KC_R // R
+#define CH_T KC_T // T
+#define CH_Z KC_Y // Z
+#define CH_U KC_U // U
+#define CH_I KC_I // I
+#define CH_O KC_O // O
+#define CH_P KC_P // P
+#define CH_UDIA KC_LBRC // ü
+#define CH_DIAE KC_RBRC // ¨ (dead)
+// Row 3
+#define CH_A KC_A // A
+#define CH_S KC_S // S
+#define CH_D KC_D // D
+#define CH_F KC_F // F
+#define CH_G KC_G // G
+#define CH_H KC_H // H
+#define CH_J KC_J // J
+#define CH_K KC_K // K
+#define CH_L KC_L // L
+#define CH_ODIA KC_SCLN // ö
+#define CH_ADIA KC_QUOT // ä
+#define CH_DLR KC_NUHS // $
+// Row 4
+#define CH_LABK KC_NUBS // <
+#define CH_Y KC_Z // Y
+#define CH_X KC_X // X
+#define CH_C KC_C // C
+#define CH_V KC_V // V
+#define CH_B KC_B // B
+#define CH_N KC_N // N
+#define CH_M KC_M // M
+#define CH_COMM KC_COMM // ,
+#define CH_DOT KC_DOT // .
+#define CH_MINS KC_SLSH // -
-// shifted characters
-#define CH_RING LSFT(CH_PARA) // °
-#define CH_PLUS LSFT(KC_1) // +
-#define CH_DQOT LSFT(KC_2) // "
-#define CH_PAST LSFT(KC_3) // *
-#define CH_CELA LSFT(KC_4) // ç
-#define CH_PERC LSFT(KC_5) // %
-#define CH_AMPR LSFT(KC_6) // &
-#define CH_SLSH LSFT(KC_7) // /
-#define CH_LPRN LSFT(KC_8) // (
-#define CH_RPRN LSFT(KC_9) // )
-#define CH_EQL LSFT(KC_0) // =
-#define CH_QST LSFT(CH_QUOT) // ?
-#define CH_GRV LSFT(CH_CARR) // `
-#define CH_EXLM LSFT(CH_DIER) // !
-#define CH_POND LSFT(CH_DLR) // £
-#define CH_MORE LSFT(CH_LESS) // >
-#define CH_COLN LSFT(KC_DOT) // :
-#define CH_SCLN LSFT(KC_COMM) // ;
-#define CH_UNDS LSFT(CH_MINS) // _
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ ° │ + │ " │ * │ ç │ % │ & │ / │ ( │ ) │ = │ ? │ ` │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │   │   │   │   │   │   │   │   │   │   │ è │ ! │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │   │   │   │   │   │   │   │   │   │ é │ à │ £ │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ > │   │   │   │   │   │   │   │ ; │ : │ _ │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_DEG S(CH_SECT) // °
+#define CH_PLUS S(CH_1) // +
+#define CH_DQUO S(CH_2) // "
+#define CH_ASTR S(CH_3) // *
+#define CH_CCED S(CH_4) // ç
+#define CH_PERC S(CH_5) // %
+#define CH_AMPR S(CH_6) // &
+#define CH_SLSH S(CH_7) // /
+#define CH_LPRN S(CH_8) // (
+#define CH_RPRN S(CH_9) // )
+#define CH_EQL S(CH_0) // =
+#define CH_QUES S(CH_QUOT) // ?
+#define CH_GRV S(CH_CIRC) // ` (dead)
+// Row 2
+#define CH_EGRV S(CH_UDIA) // è
+#define CH_EXLM S(CH_DIAE) // !
+// Row 3
+#define CH_EACU S(CH_ODIA) // é
+#define CH_AGRV S(CH_ADIA) // à
+#define CH_PND S(CH_DLR) // £
+// Row 4
+#define CH_RABK S(CH_LABK) // >
+#define CH_SCLN S(CH_COMM) // ;
+#define CH_COLN S(CH_DOT) // :
+#define CH_UNDS S(CH_MINS) // _
-// Alt Gr-ed characters
-#define CH_BRBR ALGR(KC_1) // ¦ brocken bar
-#define CH_AT ALGR(KC_2) // @
-#define CH_HASH ALGR(KC_3) // #
-#define CH_NOTL ALGR(KC_6) // ¬ negative logic
-#define CH_PIPE ALGR(KC_7) // |
-#define CH_CENT ALGR(KC_8) // ¢ cent
-#define CH_ACUT ALGR(CH_QUOT) // ´
-#define CH_TILD ALGR(CH_CARR) // ~
-#define CH_EURO ALGR(KC_E) // €
-#define CH_LBRC ALGR(CH_UE) // [
-#define CH_RBRC ALGR(CH_DIER) // ]
-#define CH_LCBR ALGR(CH_AE) // {
-#define CH_RCBR ALGR(CH_DLR) // }
-#define CH_BSLS ALGR(CH_LESS) // backslash
+/* AltGr symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │   │ ¦ │ @ │ # │   │   │ ¬ │ | │ ¢ │   │   │ ´ │ ~ │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │   │   │ € │   │   │   │   │   │   │   │ [ │ ] │     │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
+ * │      │   │   │   │   │   │   │   │   │   │   │ { │ } │    │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
+ * │    │ \ │   │   │   │   │   │   │   │   │   │   │          │
+ * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define CH_BRKP ALGR(CH_1) // ¦
+#define CH_AT ALGR(CH_2) // @
+#define CH_HASH ALGR(CH_3) // #
+#define CH_NOT ALGR(CH_6) // ¬
+#define CH_PIPE ALGR(CH_7) // |
+#define CH_CENT ALGR(CH_8) // ¢
+#define CH_ACUT ALGR(CH_QUOT) // ´ (dead)
+#define CH_TILD ALGR(CH_CIRC) // ~ (dead)
+// Row 2
+#define CH_EURO ALGR(CH_E) // €
+#define CH_LBRC ALGR(CH_UDIA) // [
+#define CH_RBRC ALGR(CH_DIAE) // ]
+// Row 3
+#define CH_LCBR ALGR(CH_ADIA) // {
+#define CH_RCBR ALGR(CH_DLR) // }
+// Row 4
+#define CH_BSLS ALGR(CH_LABK) // (backslash)
-#endif
+// DEPRECATED
+#define CH_AE CH_ADIA
+#define CH_UE CH_UDIA
+#define CH_OE CH_ODIA
+#define CH_PARA CH_SECT
+#define CH_CARR CH_CIRC
+#define CH_DIER CH_DIAE
+#define CH_LESS CH_LABK
+#define CH_RING CH_DEG
+#define CH_DQOT CH_DQUO
+#define CH_PAST CH_ASTR
+#define CH_CELA CH_CCED
+#define CH_QST CH_QUES
+#define CH_POND CH_PND
+#define CH_MORE CH_RABK
+#define CH_BRBR CH_BRKP
+#define CH_NOTL CH_NOT
diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h
index 29dee07ee..0d15532e4 100644
--- a/quantum/keymap_extras/keymap_german_osx.h
+++ b/quantum/keymap_extras/keymap_german_osx.h
@@ -13,100 +13,311 @@
* 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 KEYMAP_GERMAN_OSX
-#define KEYMAP_GERMAN_OSX
-#include "keymap.h"
-
-// Alt gr
+#pragma once
-// normal characters
-#define DE_OSX_Z KC_Y
-#define DE_OSX_Y KC_Z
+#include "keymap.h"
-#define DE_OSX_A KC_A
-#define DE_OSX_B KC_B
-#define DE_OSX_C KC_C
-#define DE_OSX_D KC_D
-#define DE_OSX_E KC_E
-#define DE_OSX_F KC_F
-#define DE_OSX_G KC_G
-#define DE_OSX_H KC_H
-#define DE_OSX_I KC_I
-#define DE_OSX_J KC_J
-#define DE_OSX_K KC_K
-#define DE_OSX_L KC_L
-#define DE_OSX_M KC_M
-#define DE_OSX_N KC_N
-#define DE_OSX_O KC_O
-#define DE_OSX_P KC_P
-#define DE_OSX_Q KC_Q
-#define DE_OSX_R KC_R
-#define DE_OSX_S KC_S
-#define DE_OSX_T KC_T
-#define DE_OSX_U KC_U
-#define DE_OSX_V KC_V
-#define DE_OSX_W KC_W
-#define DE_OSX_X KC_X
+// clang-format off
-#define DE_OSX_0 KC_0
-#define DE_OSX_1 KC_1
-#define DE_OSX_2 KC_2
-#define DE_OSX_3 KC_3
-#define DE_OSX_4 KC_4
-#define DE_OSX_5 KC_5
-#define DE_OSX_6 KC_6
-#define DE_OSX_7 KC_7
-#define DE_OSX_8 KC_8
-#define DE_OSX_9 KC_9
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ß │ ´ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ Q │ W │ E │ R │ T │ Z │ U │ I │ O │ P │ Ü │ + │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ö │ Ä │ # │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ < │ Y │ X │ C │ V │ B │ N │ M │ , │ . │ - │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define DE_CIRC KC_GRV // ^ (dead)
+#define DE_1 KC_1 // 1
+#define DE_2 KC_2 // 2
+#define DE_3 KC_3 // 3
+#define DE_4 KC_4 // 4
+#define DE_5 KC_5 // 5
+#define DE_6 KC_6 // 6
+#define DE_7 KC_7 // 7
+#define DE_8 KC_8 // 8
+#define DE_9 KC_9 // 9
+#define DE_0 KC_0 // 0
+#define DE_SS KC_MINS // ß
+#define DE_ACUT KC_EQL // ´ (dead)
+// Row 2
+#define DE_Q KC_Q // Q
+#define DE_W KC_W // W
+#define DE_E KC_E // E
+#define DE_R KC_R // R
+#define DE_T KC_T // T
+#define DE_Z KC_Y // Z
+#define DE_U KC_U // U
+#define DE_I KC_I // I
+#define DE_O KC_O // O
+#define DE_P KC_P // P
+#define DE_UDIA KC_LBRC // Ü
+#define DE_PLUS KC_RBRC // +
+// Row 3
+#define DE_A KC_A // A
+#define DE_S KC_S // S
+#define DE_D KC_D // D
+#define DE_F KC_F // F
+#define DE_G KC_G // G
+#define DE_H KC_H // H
+#define DE_J KC_J // J
+#define DE_K KC_K // K
+#define DE_L KC_L // L
+#define DE_ODIA KC_SCLN // Ö
+#define DE_ADIA KC_QUOT // Ä
+#define DE_HASH KC_NUHS // #
+// Row 4
+#define DE_LABK KC_NUBS // <
+#define DE_Y KC_Z // Y
+#define DE_X KC_X // X
+#define DE_C KC_C // C
+#define DE_V KC_V // V
+#define DE_B KC_B // B
+#define DE_N KC_N // N
+#define DE_M KC_M // M
+#define DE_COMM KC_COMM // ,
+#define DE_DOT KC_DOT // .
+#define DE_MINS KC_SLSH // -
-#define DE_OSX_DOT KC_DOT
-#define DE_OSX_COMM KC_COMM
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ° │ ! │ " │ § │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ` │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │   │ * │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │   │   │   │   │   │   │   │   │   │   │   │ ' │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ > │   │   │   │   │   │   │   │ ; │ : │ _ │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define DE_DEG S(DE_CIRC) // °
+#define DE_EXLM S(DE_1) // !
+#define DE_DQUO S(DE_2) // "
+#define DE_SECT S(DE_3) // §
+#define DE_DLR S(DE_4) // $
+#define DE_PERC S(DE_5) // %
+#define DE_AMPR S(DE_6) // &
+#define DE_SLSH S(DE_7) // /
+#define DE_LPRN S(DE_8) // (
+#define DE_RPRN S(DE_9) // )
+#define DE_EQL S(DE_0) // =
+#define DE_QUES S(DE_SS) // ?
+#define DE_GRV S(DE_ACUT) // ` (dead)
+// Row 2
+#define DE_ASTR S(DE_PLUS) // *
+// Row 3
+#define DE_QUOT S(DE_HASH) // '
+// Row 4
+#define DE_RABK S(DE_LABK) // >
+#define DE_SCLN S(DE_COMM) // ;
+#define DE_COLN S(DE_DOT) // :
+#define DE_UNDS S(DE_MINS) // _
-#define DE_OSX_SS KC_MINS
-#define DE_OSX_AE KC_QUOT
-#define DE_OSX_UE KC_LBRC
-#define DE_OSX_OE KC_SCLN
+/* Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ „ │ ¡ │ “ │ ¶ │ ¢ │ [ │ ] │ | │ { │ } │ ≠ │ ¿ │   │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ « │ ∑ │ € │ ® │ † │ Ω │ ¨ │ ⁄ │ Ø │ π │ • │ ± │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ Å │ ‚ │ ∂ │ ƒ │ © │ ª │ º │ ∆ │ @ │ Œ │ Æ │ ‘ │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≤ │ ¥ │ ≈ │ Ç │ √ │ ∫ │ ~ │ µ │ ∞ │ … │ – │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define DE_DLQU A(DE_CIRC) // „
+#define DE_IEXL A(DE_1) // ¡
+#define DE_LDQU A(DE_2) // “
+#define DE_PILC A(DE_3) // ¶
+#define DE_CENT A(DE_4) // ¢
+#define DE_LBRC A(DE_5) // [
+#define DE_RBRC A(DE_6) // ]
+#define DE_PIPE A(DE_7) // |
+#define DE_LCBR A(DE_8) // {
+#define DE_RCBR A(DE_9) // }
+#define DE_NEQL A(DE_0) // ≠
+#define DE_IQUE A(DE_SS) // ¿
+// Row 2
+#define DE_LDAQ A(DE_Q) // «
+#define DE_NARS A(DE_W) // ∑
+#define DE_EURO A(DE_E) // €
+#define DE_REGD A(DE_R) // ®
+#define DE_DAGG A(DE_T) // †
+#define DE_OMEG A(DE_Z) // Ω
+#define DE_DIAE A(DE_U) // ¨ (dead)
+#define DE_FRSL A(DE_I) // ⁄
+#define DE_OSTR A(DE_O) // Ø
+#define DE_PI A(DE_P) // π
+#define DE_BULT A(DE_UDIA) // •
+#define DE_PLMN A(DE_PLUS) // ±
+// Row 3
+#define DE_ARNG A(DE_A) // Å
+#define DE_SLQU A(DE_S) // ‚
+#define DE_PDIF A(DE_D) // ∂
+#define DE_FHK A(DE_F) // ƒ
+#define DE_COPY A(DE_G) // ©
+#define DE_FORD A(DE_H) // ª
+#define DE_MORD A(DE_J) // º
+#define DE_INCR A(DE_K) // ∆
+#define DE_AT A(DE_L) // @
+#define DE_OE A(DE_ODIA) // Œ
+#define DE_AE A(DE_ADIA) // Æ
+#define DE_LSQU A(DE_HASH) // ‘
+// Row 4
+#define DE_LTEQ A(DE_LABK) // ≤
+#define DE_YEN A(DE_Y) // ¥
+#define DE_AEQL A(DE_X) // ≈
+#define DE_CCCE A(DE_C) // Ç
+#define DE_SQRT A(DE_V) // √
+#define DE_INTG A(DE_B) // ∫
+#define DE_TILD A(DE_N) // ~ (dead)
+#define DE_MICR A(DE_M) // µ
+#define DE_INFN A(DE_COMM) // ∞
+#define DE_ELLP A(DE_DOT) // …
+#define DE_NDSH A(DE_MINS) // –
-#define DE_OSX_CIRC KC_NUBS // accent circumflex ^ and ring °
-#define DE_OSX_ACUT KC_EQL // accent acute ´ and grave `
-#define DE_OSX_PLUS KC_RBRC // + and * and ~
-#define DE_OSX_HASH KC_BSLS // # and '
-#define DE_OSX_LESS KC_GRV // < and > and |
-#define DE_OSX_MINS KC_SLSH // - and _
+/* Shift+Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │   │ ¬ │ ” │   │ £ │ fi │   │ \ │ ˜ │ · │ ¯ │ ˙ │ ˚ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ » │   │ ‰ │ ¸ │ ˝ │ ˇ │ Á │ Û │   │ ∏ │   │  │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │   │ Í │ ™ │ Ï │ Ì │ Ó │ ı │   │ fl │   │   │   │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≥ │ ‡ │ Ù │   │ ◊ │ ‹ │ › │ ˘ │ ˛ │ ÷ │ — │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define DE_NOT S(A(DE_1)) // ¬
+#define DE_RDQU S(A(DE_2)) // ”
+#define DE_PND S(A(DE_4)) // £
+#define DE_FI S(A(DE_5)) // fi
+#define DE_BSLS S(A(DE_7)) // (backslash)
+#define DE_STIL S(A(DE_8)) // ˜
+#define DE_MDDT S(A(DE_9)) // ·
+#define DE_MACR S(A(DE_0)) // ¯
+#define DE_DOTA S(A(DE_SS)) // ˙
+#define DE_RNGA S(A(DE_ACUT)) // ˚
+// Row 2
+#define DE_RDAQ S(A(DE_Q)) // »
+#define DE_PERM S(A(DE_E)) // ‰
+#define DE_CEDL S(A(DE_R)) // ¸
+#define DE_DACU S(A(DE_T)) // ˝
+#define DE_CARN S(A(DE_Z)) // ˇ
+#define DE_AACU S(A(DE_U)) // Á
+#define DE_UCIR S(A(DE_I)) // Û
+#define DE_NARP S(A(DE_P)) // ∏
+#define DE_APPL S(A(DE_PLUS)) //  (Apple logo)
+// Row 3
+#define DE_IACU S(A(DE_S)) // Í
+#define DE_TM S(A(DE_D)) // ™
+#define DE_IDIA S(A(DE_F)) // Ï
+#define DE_IGRV S(A(DE_G)) // Ì
+#define DE_OACU S(A(DE_H)) // Ó
+#define DE_DLSI S(A(DE_J)) // ı
+#define DE_FL S(A(DE_L)) // fl
+// Row 4
+#define DE_GTEQ S(A(DE_LABK)) // ≥
+#define DE_DDAG S(A(DE_Y)) // ‡
+#define DE_UGRV S(A(DE_X)) // Ù
+#define DE_LOZN S(A(DE_V)) // ◊
+#define DE_LSAQ S(A(DE_B)) // ‹
+#define DE_RSAQ S(A(DE_N)) // ›
+#define DE_BREV S(A(DE_M)) // ˘
+#define DE_OGON S(A(DE_COMM)) // ˛
+#define DE_DIV S(A(DE_DOT)) // ÷
+#define DE_MDSH S(A(DE_MINS)) // —
-// shifted characters
-#define DE_OSX_RING LSFT(DE_OSX_CIRC) // °
-#define DE_OSX_EXLM LSFT(KC_1) // !
-#define DE_OSX_DQOT LSFT(KC_2) // "
-#define DE_OSX_PARA LSFT(KC_3) // §
-#define DE_OSX_DLR LSFT(KC_4) // $
-#define DE_OSX_PERC LSFT(KC_5) // %
-#define DE_OSX_AMPR LSFT(KC_6) // &
-#define DE_OSX_SLSH LSFT(KC_7) // /
-#define DE_OSX_LPRN LSFT(KC_8) // (
-#define DE_OSX_RPRN LSFT(KC_9) // )
-#define DE_OSX_EQL LSFT(KC_0) // =
-#define DE_OSX_QST LSFT(DE_OSX_SS) // ?
-#define DE_OSX_GRV LSFT(DE_OSX_ACUT) // `
-#define DE_OSX_ASTR LSFT(DE_OSX_PLUS) // *
-#define DE_OSX_QUOT LSFT(DE_OSX_HASH) // '
-#define DE_OSX_MORE LSFT(DE_OSX_LESS) // >
-#define DE_OSX_COLN LSFT(KC_DOT) // :
-#define DE_OSX_SCLN LSFT(KC_COMM) // ;
-#define DE_OSX_UNDS LSFT(DE_OSX_MINS) // _
+// DEPRECATED
+#define DE_OSX_CIRC DE_CIRC
+#define DE_OSX_1 DE_1
+#define DE_OSX_2 DE_2
+#define DE_OSX_3 DE_3
+#define DE_OSX_4 DE_4
+#define DE_OSX_5 DE_5
+#define DE_OSX_6 DE_6
+#define DE_OSX_7 DE_7
+#define DE_OSX_8 DE_8
+#define DE_OSX_9 DE_9
+#define DE_OSX_0 DE_0
+#define DE_OSX_SS DE_SS
+#define DE_OSX_ACUT DE_ACUT
+#define DE_OSX_Q DE_Q
+#define DE_OSX_W DE_W
+#define DE_OSX_E DE_E
+#define DE_OSX_R DE_R
+#define DE_OSX_T DE_T
+#define DE_OSX_Z DE_Z
+#define DE_OSX_U DE_U
+#define DE_OSX_I DE_I
+#define DE_OSX_O DE_O
+#define DE_OSX_P DE_P
+#define DE_OSX_UE DE_UDIA
+#define DE_OSX_PLUS DE_PLUS
+#define DE_OSX_A DE_A
+#define DE_OSX_S DE_S
+#define DE_OSX_D DE_D
+#define DE_OSX_F DE_F
+#define DE_OSX_G DE_G
+#define DE_OSX_H DE_H
+#define DE_OSX_J DE_J
+#define DE_OSX_K DE_K
+#define DE_OSX_L DE_L
+#define DE_OSX_OE DE_ODIA
+#define DE_OSX_AE DE_ADIA
+#define DE_OSX_HASH DE_HASH
+#define DE_OSX_LESS DE_LABK
+#define DE_OSX_Y DE_Y
+#define DE_OSX_X DE_X
+#define DE_OSX_C DE_C
+#define DE_OSX_V DE_V
+#define DE_OSX_B DE_B
+#define DE_OSX_N DE_N
+#define DE_OSX_M DE_M
+#define DE_OSX_COMM DE_COMM
+#define DE_OSX_DOT DE_DOT
+#define DE_OSX_MINS DE_MINS
-// Alt-ed characters
-//#define DE_OSX_SQ2 LALT(KC_2) // ²
-//#define DE_OSX_SQ3 LALT(KC_3) // ³
-#define DE_OSX_LCBR LALT(KC_8) // {
-#define DE_OSX_LBRC LALT(KC_5) // [
-#define DE_OSX_RBRC LALT(KC_6) // ]
-#define DE_OSX_RCBR LALT(KC_9) // }
-#define DE_OSX_BSLS LALT(LSFT(KC_7)) // backslash
-#define DE_OSX_AT LALT(DE_OSX_L) // @
-#define DE_OSX_EURO LALT(KC_E) // €
-#define DE_OSX_TILD LALT(DE_OSX_N) // ~
-#define DE_OSX_PIPE LALT(DE_OSX_7) // |
+#define DE_OSX_RING DE_DEG
+#define DE_OSX_EXLM DE_EXLM
+#define DE_OSX_DQOT DE_DQUO
+#define DE_OSX_PARA DE_SECT
+#define DE_OSX_DLR DE_DLR
+#define DE_OSX_PERC DE_PERC
+#define DE_OSX_AMPR DE_AMPR
+#define DE_OSX_SLSH DE_SLSH
+#define DE_OSX_LPRN DE_LPRN
+#define DE_OSX_RPRN DE_RPRN
+#define DE_OSX_EQL DE_EQL
+#define DE_OSX_QST DE_QUES
+#define DE_OSX_GRV DE_GRV
+#define DE_OSX_ASTR DE_ASTR
+#define DE_OSX_QUOT DE_QUOT
+#define DE_OSX_MORE DE_RABK
+#define DE_OSX_COLN DE_COLN
+#define DE_OSX_SCLN DE_SCLN
+#define DE_OSX_UNDS DE_UNDS
-#endif
+#define DE_OSX_LBRC DE_LBRC
+#define DE_OSX_RBRC DE_RBRC
+#define DE_OSX_PIPE DE_PIPE
+#define DE_OSX_LCBR DE_LCBR
+#define DE_OSX_RCBR DE_RCBR
+#define DE_OSX_AT DE_AT
+#define DE_OSX_EURO DE_EURO
+#define DE_OSX_TILD DE_TILD
+#define DE_OSX_BSLS DE_BSLS
diff --git a/quantum/keymap_extras/keymap_italian_osx_ansi.h b/quantum/keymap_extras/keymap_italian_osx_ansi.h
index fa12d05dc..1f7fe8afc 100644
--- a/quantum/keymap_extras/keymap_italian_osx_ansi.h
+++ b/quantum/keymap_extras/keymap_italian_osx_ansi.h
@@ -14,100 +14,255 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// This is a clone of quantum/keymap_extra/keymap_italian.h intended to be used with Apple devices
-
-#ifndef KEYMAP_ITALIAN
-#define KEYMAP_ITALIAN
+#pragma once
#include "keymap.h"
-// normal characters
-#define IT_A KC_A
-#define IT_B KC_B
-#define IT_C KC_C
-#define IT_D KC_D
-#define IT_E KC_E
-#define IT_F KC_F
-#define IT_G KC_G
-#define IT_H KC_H
-#define IT_I KC_I
-#define IT_J KC_J
-#define IT_K KC_K
-#define IT_L KC_L
-#define IT_M KC_M
-#define IT_N KC_N
-#define IT_O KC_O
-#define IT_P KC_P
-#define IT_Q KC_Q
-#define IT_R KC_R
-#define IT_S KC_S
-#define IT_T KC_T
-#define IT_U KC_U
-#define IT_V KC_V
-#define IT_W KC_W
-#define IT_X KC_X
-#define IT_Y KC_Y
-#define IT_Z KC_Z
-
-#define IT_0 KC_0
-#define IT_1 KC_1
-#define IT_2 KC_2
-#define IT_3 KC_3
-#define IT_4 KC_4
-#define IT_5 KC_5
-#define IT_6 KC_6
-#define IT_7 KC_7
-#define IT_8 KC_8
-#define IT_9 KC_9
+// clang-format off
-// punctuation
-#define IT_DOT KC_DOT // . and :
-#define IT_COMM KC_COMM // , and ;
-#define IT_APOS KC_MINS // ' and ?
-#define IT_BSLS KC_NUBS // \ and |
-#define IT_LESS KC_GRV // < and >
-#define IT_MINS KC_SLSH // - and _
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ < │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ ì │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ è │ + │ ù │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴───┤
+ * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ò │ à │      │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴──────┤
+ * │        │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │        │
+ * ├─────┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_LABK KC_GRV // <
+#define IT_1 KC_1 // 1
+#define IT_2 KC_2 // 2
+#define IT_3 KC_3 // 3
+#define IT_4 KC_4 // 4
+#define IT_5 KC_5 // 5
+#define IT_6 KC_6 // 6
+#define IT_7 KC_7 // 7
+#define IT_8 KC_8 // 8
+#define IT_9 KC_9 // 9
+#define IT_0 KC_0 // 0
+#define IT_QUOT KC_MINS // '
+#define IT_IGRV KC_EQL // ì
+// Row 2
+#define IT_Q KC_Q // Q
+#define IT_W KC_W // W
+#define IT_E KC_E // E
+#define IT_R KC_R // R
+#define IT_T KC_T // T
+#define IT_Y KC_Y // Y
+#define IT_U KC_U // U
+#define IT_I KC_I // I
+#define IT_O KC_O // O
+#define IT_P KC_P // P
+#define IT_EGRV KC_LBRC // è
+#define IT_PLUS KC_RBRC // +
+#define IT_UGRV KC_BSLS // ù
+// Row 3
+#define IT_A KC_A // A
+#define IT_S KC_S // S
+#define IT_D KC_D // D
+#define IT_F KC_F // F
+#define IT_G KC_G // G
+#define IT_H KC_H // H
+#define IT_J KC_J // J
+#define IT_K KC_K // K
+#define IT_L KC_L // L
+#define IT_OGRV KC_SCLN // ò
+#define IT_AGRV KC_QUOT // à
+// Row 4
+#define IT_BSLS KC_NUBS // (backslash, not physically present)
+#define IT_Z KC_Z // Z
+#define IT_X KC_X // X
+#define IT_C KC_C // C
+#define IT_V KC_V // V
+#define IT_B KC_B // B
+#define IT_N KC_N // N
+#define IT_M KC_M // M
+#define IT_COMM KC_COMM // ,
+#define IT_DOT KC_DOT // .
+#define IT_MINS KC_SLSH // -
-// accented vowels (regular, with shift, with option, with option and shift)
-#define IT_EACC KC_LBRC // è, é, [, {
-#define IT_PLUS KC_RBRC // +, *, ], }
-#define IT_OACC KC_SCLN // ò, ç, @, Ç
-#define IT_AACC KC_QUOT // à, °, #, ∞
-#define IT_UACC KC_BSLS // ù, §, ¶, ◊
-#define IT_IACC KC_EQL // ì, ^, ˆ, ±
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ > │ ! │ " │ £ │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ^ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │ é │ * │ § │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴───┤
+ * │      │   │   │   │   │   │   │   │   │   │ ç │ ° │      │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴──────┤
+ * │        │   │   │   │   │   │   │   │ ; │ : │ _ │        │
+ * ├─────┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_RABK S(IT_LABK) // >
+#define IT_EXLM S(IT_1) // !
+#define IT_DQUO S(IT_2) // "
+#define IT_PND S(IT_3) // £
+#define IT_DLR S(IT_4) // $
+#define IT_PERC S(IT_5) // %
+#define IT_AMPR S(IT_6) // &
+#define IT_SLSH S(IT_7) // /
+#define IT_LPRN S(IT_8) // (
+#define IT_RPRN S(IT_9) // )
+#define IT_EQL S(IT_0) // =
+#define IT_QUES S(IT_QUOT) // ?
+#define IT_CIRC S(IT_IGRV) // ^
+// Row 2
+#define IT_EACU S(IT_EGRV) // é
+#define IT_ASTR S(IT_PLUS) // *
+#define IT_SECT S(IT_UGRV) // §
+// Row 3
+#define IT_LCCE S(IT_OGRV) // ç
+#define IT_DEG S(IT_AGRV) // °
+// Row 4
+#define IT_PIPE S(IT_BSLS) // | (not physically present)
+#define IT_SCLN S(IT_COMM) // ;
+#define IT_COLN S(IT_DOT) // :
+#define IT_UNDS S(IT_MINS) // _
-// shifted characters
-#define IT_EXLM LSFT(KC_1) // !
-#define IT_DQOT LSFT(KC_2) // "
-#define IT_STRL LSFT(KC_3) // £
-#define IT_DLR LSFT(KC_4) // $
-#define IT_PERC LSFT(KC_5) // %
-#define IT_AMPR LSFT(KC_6) // &
-#define IT_SLSH LSFT(KC_7) // /
-#define IT_LPRN LSFT(KC_8) // (
-#define IT_RPRN LSFT(KC_9) // )
-#define IT_EQL LSFT(KC_0) // =
-#define IT_DEGR LSFT(IT_AACC) // °
-#define IT_QST LSFT(IT_APOS) // ?
-#define IT_CRC LSFT(IT_IACC) // ^
-#define IT_ASTR LSFT(IT_PLUS) // *
-#define IT_MORE LSFT(IT_LESS) // >
-#define IT_COLN LSFT(IT_DOT) // :
-#define IT_SCLN LSFT(IT_COMM) // ;
-#define IT_UNDS LSFT(IT_MINS) // _
-#define IT_LCBR LSFT(IT_LBRC) // {
-#define IT_RCBR LSFT(IT_RBRC) // }
-#define IT_PIPE LSFT(IT_BSLS) // |
+/* Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ≤ │ « │ “ │ ‘ │ ¥ │ ~ │ ‹ │ ÷ │ ´ │ ` │ ≠ │ ¡ │ ˆ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ „ │ Ω │ € │ ® │ ™ │ Æ │ ¨ │ Œ │ Ø │ π │ [ │ ] │ ¶ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴───┤
+ * │      │ Å │ ß │ ∂ │ ƒ │ ∞ │ ∆ │ ª │ º │ ¬ │ @ │ # │      │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴──────┤
+ * │        │ ∑ │ † │ © │ √ │ ∫ │ ˜ │ µ │ … │ • │ – │        │
+ * ├─────┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_LTEQ A(IT_LABK) // ≤
+#define IT_LDAQ A(IT_1) // «
+#define IT_LDQU A(IT_2) // “
+#define IT_LSQU A(IT_3) // ‘
+#define IT_YEN A(IT_4) // ¥
+#define IT_TILD A(IT_5) // ~
+#define IT_LSAQ A(IT_6) // ‹
+#define IT_DIV A(IT_7) // ÷
+#define IT_ACUT A(IT_8) // ´ (dead)
+#define IT_DGRV A(IT_9) // ` (dead)
+#define IT_NEQL A(IT_0) // ≠
+#define IT_IEXL A(IT_QUOT) // ¡
+#define IT_DCIR A(IT_IGRV) // ˆ (dead)
+// Row 2
+#define IT_DLQU A(IT_Q) // „
+#define IT_OMEG A(IT_W) // Ω
+#define IT_EURO A(IT_E) // €
+#define IT_REGD A(IT_R) // ®
+#define IT_TM A(IT_T) // ™
+#define IT_AE A(IT_Y) // Æ
+#define IT_DIAE A(IT_U) // ¨ (dead)
+#define IT_OE A(IT_I) // Œ
+#define IT_OSTR A(IT_O) // Ø
+#define IT_PI A(IT_P) // π
+#define IT_LBRC A(IT_EGRV) // [
+#define IT_RBRC A(IT_PLUS) // ]
+// Row 3
+#define IT_ARNG A(IT_A) // Å
+#define IT_SS A(IT_S) // ß
+#define IT_PDIF A(IT_D) // ∂
+#define IT_FHK A(IT_F) // ƒ
+#define IT_INFN A(IT_G) // ∞
+#define IT_INCR A(IT_H) // ∆
+#define IT_FORD A(IT_J) // ª
+#define IT_MORD A(IT_K) // º
+#define IT_NOT A(IT_L) // ¬
+#define IT_AT A(IT_OGRV) // @
+#define IT_HASH A(IT_AGRV) // #
+#define IT_PILC A(IT_UGRV) // ¶
+// Row 4
+#define IT_GRV A(IT_BSLS) // ` (not physically present)
+#define IT_NARS A(IT_Z) // ∑
+#define IT_DAGG A(IT_X) // †
+#define IT_COPY A(IT_C) // ©
+#define IT_SQRT A(IT_V) // √
+#define IT_INTG A(IT_B) // ∫
+#define IT_STIL A(IT_N) // ˜ (dead)
+#define IT_MICR A(IT_M) // µ
+#define IT_ELLP A(IT_COMM) // …
+#define IT_BULT A(IT_DOT) // •
+#define IT_NDSH A(IT_MINS) // –
-// Alt -ed characters
-#define IT_LBRC LALT(IT_EACC) // [
-#define IT_RBRC LALT(IT_PLUS) // ]
-#define IT_AT LALT(IT_OACC) // @
-#define IT_EURO LALT(KC_E) // €
-#define IT_SHRP LALT(IT_AACC) // #
-#define IT_ACUT LALT(KC_8) // ´
-#define IT_GRAVE LALT(KC_9) // `
-#define IT_TILDE LALT(KC_5) // ~
-#define IT_PLMN LALT(LSFT(IT_IACC)) // ±
+/* Shift+Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ≥ │ » │ ” │ ’ │ ¢ │ ‰ │ › │ ⁄ │  │   │ ≈ │ ¿ │ ± │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ ‚ │ À │ È │ Ì │ Ò │   │ Ù │   │   │ ∏ │ { │ } │ ◊ │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴───┤
+ * │      │   │ ¯ │ ˘ │ ˙ │ ˚ │ ¸ │ ˝ │ ˛ │ ˇ │ Ç │ ∞ │      │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴──────┤
+ * │        │   │ ‡ │ Á │ É │ Í │ Ó │ Ú │   │ · │ — │        │
+ * ├─────┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_GTEQ S(A(IT_LABK)) // ≥
+#define IT_RDAQ S(A(IT_1)) // »
+#define IT_RDQU S(A(IT_2)) // ”
+#define IT_RSQU S(A(IT_3)) // ’
+#define IT_CENT S(A(IT_4)) // ¢
+#define IT_PERM S(A(IT_5)) // ‰
+#define IT_RSAQ S(A(IT_6)) // ›
+#define IT_FRSL S(A(IT_7)) // ⁄
+#define IT_APPL S(A(IT_8)) //  (Apple logo)
+#define IT_AEQL S(A(IT_0)) // ≈
+#define IT_IQUE S(A(IT_QUOT)) // ¿
+#define IT_PLMN S(A(IT_IGRV)) // ±
+// Row 2
+#define IT_SLQU S(A(IT_Q)) // ‚
+#define IT_CAGR S(A(IT_W)) // À
+#define IT_CEGR S(A(IT_E)) // È
+#define IT_CIGR S(A(IT_R)) // Ì
+#define IT_COGR S(A(IT_T)) // Ò
+#define IT_CUGR S(A(IT_U)) // Ù
+#define IT_NARP S(A(IT_P)) // ∏
+#define IT_LCBR S(A(IT_EGRV)) // {
+#define IT_RCBR S(A(IT_PLUS)) // }
+#define IT_LOZN S(A(IT_UGRV)) // ◊
+// Row 3
+#define IT_MACR S(A(IT_S)) // ¯
+#define IT_BREV S(A(IT_D)) // ˘
+#define IT_DOTA S(A(IT_F)) // ˙
+#define IT_RGNA S(A(IT_G)) // ˚
+#define IT_CEDL S(A(IT_H)) // ¸
+#define IT_DACU S(A(IT_J)) // ˝
+#define IT_OGON S(A(IT_K)) // ˛
+#define IT_CARN S(A(IT_L)) // ˇ
+#define IT_CCCE S(A(IT_OGRV)) // Ç
+// Row 4
+#define IT_DDAG S(A(IT_X)) // ‡
+#define IT_CAAC S(A(IT_C)) // Á
+#define IT_CEAC S(A(IT_V)) // É
+#define IT_CIAC S(A(IT_B)) // Í
+#define IT_COAC S(A(IT_N)) // Ó
+#define IT_CUAC S(A(IT_M)) // Ú
+#define IT_MDDT S(A(IT_DOT)) // ·
+#define IT_MDSH S(A(IT_MINS)) // —
-#endif
+// DEPRECATED
+#define IT_LESS IT_LABK
+#define IT_APOS IT_QUOT
+#define IT_IACC IT_IGRV
+#define IT_EACC IT_EGRV
+#define IT_UACC IT_UGRV
+#define IT_OACC IT_OGRV
+#define IT_AACC IT_AGRV
+#define IT_MORE IT_RABK
+#define IT_DQOT IT_DQUO
+#define IT_STRL IT_PND
+#define IT_QST IT_QUES
+#define IT_CRC IT_CIRC
+#define IT_DEGR IT_DEG
+#define IT_TILDE IT_TILD
+#define IT_GRAVE IT_GRV
+#define IT_SHRP IT_HASH
diff --git a/quantum/keymap_extras/keymap_italian_osx_iso.h b/quantum/keymap_extras/keymap_italian_osx_iso.h
index a9b36f16e..5ed1e3abd 100644
--- a/quantum/keymap_extras/keymap_italian_osx_iso.h
+++ b/quantum/keymap_extras/keymap_italian_osx_iso.h
@@ -14,100 +14,256 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// This is a clone of quantum/keymap_extra/keymap_italian.h intended to be used with Apple devices
-
-#ifndef KEYMAP_ITALIAN
-#define KEYMAP_ITALIAN
+#pragma once
#include "keymap.h"
-// normal characters
-#define IT_A KC_A
-#define IT_B KC_B
-#define IT_C KC_C
-#define IT_D KC_D
-#define IT_E KC_E
-#define IT_F KC_F
-#define IT_G KC_G
-#define IT_H KC_H
-#define IT_I KC_I
-#define IT_J KC_J
-#define IT_K KC_K
-#define IT_L KC_L
-#define IT_M KC_M
-#define IT_N KC_N
-#define IT_O KC_O
-#define IT_P KC_P
-#define IT_Q KC_Q
-#define IT_R KC_R
-#define IT_S KC_S
-#define IT_T KC_T
-#define IT_U KC_U
-#define IT_V KC_V
-#define IT_W KC_W
-#define IT_X KC_X
-#define IT_Y KC_Y
-#define IT_Z KC_Z
-
-#define IT_0 KC_0
-#define IT_1 KC_1
-#define IT_2 KC_2
-#define IT_3 KC_3
-#define IT_4 KC_4
-#define IT_5 KC_5
-#define IT_6 KC_6
-#define IT_7 KC_7
-#define IT_8 KC_8
-#define IT_9 KC_9
+// clang-format off
-// punctuation
-#define IT_DOT KC_DOT // . and :
-#define IT_COMM KC_COMM // , and ;
-#define IT_APOS KC_MINS // ' and ?
-#define IT_BSLS KC_GRV // \ and |
-#define IT_LESS KC_NUBS // < and >
-#define IT_MINS KC_SLSH // - and _
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ \ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ ì │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ è │ + │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ò │ à │ ù │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_BSLS KC_GRV // (backslash)
+#define IT_1 KC_1 // 1
+#define IT_2 KC_2 // 2
+#define IT_3 KC_3 // 3
+#define IT_4 KC_4 // 4
+#define IT_5 KC_5 // 5
+#define IT_6 KC_6 // 6
+#define IT_7 KC_7 // 7
+#define IT_8 KC_8 // 8
+#define IT_9 KC_9 // 9
+#define IT_0 KC_0 // 0
+#define IT_QUOT KC_MINS // '
+#define IT_IGRV KC_EQL // ì
+// Row 2
+#define IT_Q KC_Q // Q
+#define IT_W KC_W // W
+#define IT_E KC_E // E
+#define IT_R KC_R // R
+#define IT_T KC_T // T
+#define IT_Y KC_Y // Y
+#define IT_U KC_U // U
+#define IT_I KC_I // I
+#define IT_O KC_O // O
+#define IT_P KC_P // P
+#define IT_EGRV KC_LBRC // è
+#define IT_PLUS KC_RBRC // +
+// Row 3
+#define IT_A KC_A // A
+#define IT_S KC_S // S
+#define IT_D KC_D // D
+#define IT_F KC_F // F
+#define IT_G KC_G // G
+#define IT_H KC_H // H
+#define IT_J KC_J // J
+#define IT_K KC_K // K
+#define IT_L KC_L // L
+#define IT_OGRV KC_SCLN // ò
+#define IT_AGRV KC_QUOT // à
+#define IT_UGRV KC_NUHS // ù
+// Row 4
+#define IT_LABK KC_NUBS // <
+#define IT_Z KC_Z // Z
+#define IT_X KC_X // X
+#define IT_C KC_C // C
+#define IT_V KC_V // V
+#define IT_B KC_B // B
+#define IT_N KC_N // N
+#define IT_M KC_M // M
+#define IT_COMM KC_COMM // ,
+#define IT_DOT KC_DOT // .
+#define IT_MINS KC_SLSH // -
-// accented vowels (regular, with shift, with option, with option and shift)
-#define IT_EACC KC_LBRC // è, é, [, {
-#define IT_PLUS KC_RBRC // +, *, ], }
-#define IT_OACC KC_SCLN // ò, ç, @, Ç
-#define IT_AACC KC_QUOT // à, °, #, ∞
-#define IT_UACC KC_BSLS // ù, §, ¶, ◊
-#define IT_IACC KC_EQL // ì, ^, ˆ, ±
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ | │ ! │ " │ £ │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ ^ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │   │   │   │   │   │   │   │   │   │   │ é │ * │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │   │   │   │   │   │   │   │   │   │ ç │ ° │ § │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ > │   │   │   │   │   │   │   │ ; │ : │ _ │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_PIPE S(IT_BSLS) // |
+#define IT_EXLM S(IT_1) // !
+#define IT_DQUO S(IT_2) // "
+#define IT_PND S(IT_3) // £
+#define IT_DLR S(IT_4) // $
+#define IT_PERC S(IT_5) // %
+#define IT_AMPR S(IT_6) // &
+#define IT_SLSH S(IT_7) // /
+#define IT_LPRN S(IT_8) // (
+#define IT_RPRN S(IT_9) // )
+#define IT_EQL S(IT_0) // =
+#define IT_QUES S(IT_QUOT) // ?
+#define IT_CIRC S(IT_IGRV) // ^
+// Row 2
+#define IT_EACU S(IT_EGRV) // é
+#define IT_ASTR S(IT_PLUS) // *
+// Row 3
+#define IT_LCCE S(IT_OGRV) // ç
+#define IT_DEG S(IT_AGRV) // °
+#define IT_SECT S(IT_UGRV) // §
+// Row 4
+#define IT_RABK S(IT_LABK) // >
+#define IT_SCLN S(IT_COMM) // ;
+#define IT_COLN S(IT_DOT) // :
+#define IT_UNDS S(IT_MINS) // _
-// shifted characters
-#define IT_EXLM LSFT(KC_1) // !
-#define IT_DQOT LSFT(KC_2) // "
-#define IT_STRL LSFT(KC_3) // £
-#define IT_DLR LSFT(KC_4) // $
-#define IT_PERC LSFT(KC_5) // %
-#define IT_AMPR LSFT(KC_6) // &
-#define IT_SLSH LSFT(KC_7) // /
-#define IT_LPRN LSFT(KC_8) // (
-#define IT_RPRN LSFT(KC_9) // )
-#define IT_EQL LSFT(KC_0) // =
-#define IT_DEGR LSFT(IT_AACC) // °
-#define IT_QST LSFT(IT_APOS) // ?
-#define IT_CRC LSFT(IT_IACC) // ^
-#define IT_ASTR LSFT(IT_PLUS) // *
-#define IT_MORE LSFT(IT_LESS) // >
-#define IT_COLN LSFT(IT_DOT) // :
-#define IT_SCLN LSFT(IT_COMM) // ;
-#define IT_UNDS LSFT(IT_MINS) // _
-#define IT_LCBR LSFT(IT_LBRC) // {
-#define IT_RCBR LSFT(IT_RBRC) // }
-#define IT_PIPE LSFT(IT_BSLS) // |
+/* Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ` │ « │ “ │ ‘ │ ¥ │ ~ │ ‹ │ ÷ │ ´ │ ` │ ≠ │ ¡ │ ˆ │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ „ │ Ω │ € │ ® │ ™ │ Æ │ ¨ │ Œ │ Ø │ π │ [ │ ] │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │ Å │ ß │ ∂ │ ƒ │ ∞ │ ∆ │ ª │ º │ ¬ │ @ │ # │ ¶ │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≤ │ ∑ │ † │ © │ √ │ ∫ │ ˜ │ µ │ … │ • │ – │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_GRV A(IT_BSLS) // `
+#define IT_LDAQ A(IT_1) // «
+#define IT_LDQU A(IT_2) // “
+#define IT_LSQU A(IT_3) // ‘
+#define IT_YEN A(IT_4) // ¥
+#define IT_TILD A(IT_5) // ~
+#define IT_LSAQ A(IT_6) // ‹
+#define IT_DIV A(IT_7) // ÷
+#define IT_ACUT A(IT_8) // ´ (dead)
+#define IT_DGRV A(IT_9) // ` (dead)
+#define IT_NEQL A(IT_0) // ≠
+#define IT_IEXL A(IT_QUOT) // ¡
+#define IT_DCIR A(IT_IGRV) // ˆ (dead)
+// Row 2
+#define IT_DLQU A(IT_Q) // „
+#define IT_OMEG A(IT_W) // Ω
+#define IT_EURO A(IT_E) // €
+#define IT_REGD A(IT_R) // ®
+#define IT_TM A(IT_T) // ™
+#define IT_AE A(IT_Y) // Æ
+#define IT_DIAE A(IT_U) // ¨ (dead)
+#define IT_OE A(IT_I) // Œ
+#define IT_OSTR A(IT_O) // Ø
+#define IT_PI A(IT_P) // π
+#define IT_LBRC A(IT_EGRV) // [
+#define IT_RBRC A(IT_PLUS) // ]
+// Row 3
+#define IT_ARNG A(IT_A) // Å
+#define IT_SS A(IT_S) // ß
+#define IT_PDIF A(IT_D) // ∂
+#define IT_FHK A(IT_F) // ƒ
+#define IT_INFN A(IT_G) // ∞
+#define IT_INCR A(IT_H) // ∆
+#define IT_FORD A(IT_J) // ª
+#define IT_MORD A(IT_K) // º
+#define IT_NOT A(IT_L) // ¬
+#define IT_AT A(IT_OGRV) // @
+#define IT_HASH A(IT_AGRV) // #
+#define IT_PILC A(IT_UGRV) // ¶
+// Row 4
+#define IT_LTEQ A(IT_LABK) // ≤
+#define IT_NARS A(IT_Z) // ∑
+#define IT_DAGG A(IT_X) // †
+#define IT_COPY A(IT_C) // ©
+#define IT_SQRT A(IT_V) // √
+#define IT_INTG A(IT_B) // ∫
+#define IT_STIL A(IT_N) // ˜ (dead)
+#define IT_MICR A(IT_M) // µ
+#define IT_ELLP A(IT_COMM) // …
+#define IT_BULT A(IT_DOT) // •
+#define IT_NDSH A(IT_MINS) // –
-// Alt -ed characters
-#define IT_LBRC LALT(IT_EACC) // [
-#define IT_RBRC LALT(IT_PLUS) // ]
-#define IT_AT LALT(IT_OACC) // @
-#define IT_EURO LALT(KC_E) // €
-#define IT_SHRP LALT(IT_AACC) // #
-#define IT_ACUT LALT(KC_8) // ´
-#define IT_GRAVE LALT(KC_9) // `
-#define IT_TILDE LALT(KC_5) // ~
-#define IT_PLMN LALT(LSFT(IT_IACC)) // ±
+/* Shift+Alted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
+ * │ ı │ » │ ” │ ’ │ ¢ │ ‰ │ › │ ⁄ │  │   │ ≈ │ ¿ │ ± │     │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
+ * │     │ ‚ │ À │ È │ Ì │ Ò │   │ Ù │   │   │ ∏ │ { │ } │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
+ * │      │   │ ¯ │ ˘ │ ˙ │ ˚ │ ¸ │ ˝ │ ˛ │ ˇ │ Ç │   │ ◊ │  │
+ * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
+ * │    │ ≥ │   │ ‡ │ Á │ É │ Í │ Ó │ Ú │   │ · │ — │        │
+ * ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
+ * │     │    │     │                       │     │    │     │
+ * └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
+ */
+// Row 1
+#define IT_DLSI S(A(IT_BSLS)) // ı
+#define IT_RDAQ S(A(IT_1)) // »
+#define IT_RDQU S(A(IT_2)) // ”
+#define IT_RSQU S(A(IT_3)) // ’
+#define IT_CENT S(A(IT_4)) // ¢
+#define IT_PERM S(A(IT_5)) // ‰
+#define IT_RSAQ S(A(IT_6)) // ›
+#define IT_FRSL S(A(IT_7)) // ⁄
+#define IT_APPL S(A(IT_8)) //  (Apple logo)
+#define IT_AEQL S(A(IT_0)) // ≈
+#define IT_IQUE S(A(IT_QUOT)) // ¿
+#define IT_PLMN S(A(IT_IGRV)) // ±
+// Row 2
+#define IT_SLQU S(A(IT_Q)) // ‚
+#define IT_CAGR S(A(IT_W)) // À
+#define IT_CEGR S(A(IT_E)) // È
+#define IT_CIGR S(A(IT_R)) // Ì
+#define IT_COGR S(A(IT_T)) // Ò
+#define IT_CUGR S(A(IT_U)) // Ù
+#define IT_NARP S(A(IT_P)) // ∏
+#define IT_LCBR S(A(IT_EGRV)) // {
+#define IT_RCBR S(A(IT_PLUS)) // }
+// Row 3
+#define IT_MACR S(A(IT_S)) // ¯
+#define IT_BREV S(A(IT_D)) // ˘
+#define IT_DOTA S(A(IT_F)) // ˙
+#define IT_RNGA S(A(IT_G)) // ˚
+#define IT_CEDL S(A(IT_H)) // ¸
+#define IT_DACU S(A(IT_J)) // ˝
+#define IT_OGON S(A(IT_K)) // ˛
+#define IT_CARN S(A(IT_L)) // ˇ
+#define IT_CCCE S(A(IT_OGRV)) // Ç
+#define IT_LOZN S(A(IT_UGRV)) // ◊
+// Row 4
+#define IT_GTEQ S(A(IT_LABK)) // ≥
+#define IT_DDAG S(A(IT_X)) // ‡
+#define IT_CAAC S(A(IT_C)) // Á
+#define IT_CEAC S(A(IT_V)) // É
+#define IT_CIAC S(A(IT_B)) // Í
+#define IT_COAC S(A(IT_N)) // Ó
+#define IT_CUAC S(A(IT_M)) // Ú
+#define IT_MDDT S(A(IT_DOT)) // ·
+#define IT_MDSH S(A(IT_MINS)) // —
-#endif
+// DEPRECATED
+#define IT_APOS IT_QUOT
+#define IT_IACC IT_IGRV
+#define IT_EACC IT_EGRV
+#define IT_OACC IT_OGRV
+#define IT_AACC IT_AGRV
+#define IT_UACC IT_UGRV
+#define IT_LESS IT_LABK
+#define IT_DQOT IT_DQUO
+#define IT_STRL IT_PND
+#define IT_QST IT_QUES
+#define IT_CRC IT_CIRC
+#define IT_DEGR IT_DEG
+#define IT_MORE IT_RABK
+#define IT_TILDE IT_TILD
+#define IT_GRAVE IT_GRV
+#define IT_SHRP IT_HASH
diff --git a/quantum/keymap_extras/keymap_workman_zxcvm.h b/quantum/keymap_extras/keymap_workman_zxcvm.h
new file mode 100644
index 000000000..4ba2ada9e
--- /dev/null
+++ b/quantum/keymap_extras/keymap_workman_zxcvm.h
@@ -0,0 +1,125 @@
+/* Copyright 2018 Jacob Jerrell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "keymap.h"
+
+// clang-format off
+
+/*
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │ Q │ D │ R │ W │ B │ J │ F │ U │ P │ ; │ [ │ ] │  \  │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
+ * │      │ A │ S │ H │ T │ G │ Y │ N │ E │ O │ I │ ' │        │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤
+ * │        │ Z │ X │ C │ V │ M │ K │ L │ , │ . │ / │          │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define WK_GRV KC_GRV // `
+#define WK_1 KC_1 // 1
+#define WK_2 KC_2 // 2
+#define WK_3 KC_3 // 3
+#define WK_4 KC_4 // 4
+#define WK_5 KC_5 // 5
+#define WK_6 KC_6 // 6
+#define WK_7 KC_7 // 7
+#define WK_8 KC_8 // 8
+#define WK_9 KC_9 // 9
+#define WK_0 KC_0 // 0
+#define WK_MINS KC_MINS // -
+#define WK_EQL KC_EQL // =
+// Row 2
+#define WK_Q KC_Q // Q
+#define WK_D KC_W // D
+#define WK_R KC_E // R
+#define WK_W KC_R // W
+#define WK_B KC_T // B
+#define WK_J KC_Y // J
+#define WK_F KC_U // F
+#define WK_U KC_I // U
+#define WK_P KC_O // P
+#define WK_SCLN KC_P // ;
+#define WK_LBRC KC_LBRC // [
+#define WK_RBRC KC_RBRC // ]
+#define WK_BSLS KC_BSLS // (backslash)
+// Row 3
+#define WK_A KC_A // A
+#define WK_S KC_S // S
+#define WK_H KC_D // H
+#define WK_T KC_F // T
+#define WK_G KC_G // G
+#define WK_Y KC_H // Y
+#define WK_N KC_J // N
+#define WK_E KC_K // E
+#define WK_O KC_L // O
+#define WK_I KC_SCLN // I
+#define WK_QUOT KC_QUOT // '
+// Row 4
+#define WK_Z KC_Z // Z
+#define WK_X KC_X // X
+#define WK_C KC_C // C
+#define WK_V KC_V // V
+#define WK_M KC_B // M
+#define WK_K KC_N // K
+#define WK_L KC_M // L
+#define WK_COMM KC_COMM // ,
+#define WK_DOT KC_DOT // .
+#define WK_SLSH KC_SLSH // /
+
+/* Shifted symbols
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
+ * │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │       │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
+ * │     │   │   │   │   │   │   │   │   │   │ : │ { │ } │  |  │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤
+ * │      │   │   │   │   │   │   │   │   │   │   │ " │        │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤
+ * │        │   │   │   │   │   │   │   │ < │ > │ ? │          │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
+ * │    │    │    │                        │    │    │    │    │
+ * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+ */
+// Row 1
+#define WK_TILD S(WK_GRV) // ~
+#define WK_EXLM S(WK_1) // !
+#define WK_AT S(WK_2) // @
+#define WK_HASH S(WK_3) // #
+#define WK_DLR S(WK_4) // $
+#define WK_PERC S(WK_5) // %
+#define WK_CIRC S(WK_6) // ^
+#define WK_AMPR S(WK_7) // &
+#define WK_ASTR S(WK_8) // *
+#define WK_LPRN S(WK_9) // (
+#define WK_RPRN S(WK_0) // )
+#define WK_UNDS S(WK_MINS) // _
+#define WK_PLUS S(WK_EQL) // +
+// Row 2
+#define WK_COLN S(WK_SCLN) // :
+#define WK_LCBR S(WK_LBRC) // {
+#define WK_RCBR S(WK_RBRC) // }
+#define WK_PIPE S(WK_BSLS) // |
+// Row 3
+#define WK_DQUO S(WK_QUOT) // "
+// Row 4
+#define WK_LABK S(WK_COMM) // <
+#define WK_RABK S(WK_DOT) // >
+#define WK_QUES S(WK_SLSH) // ?
diff --git a/quantum/keymap_extras/sendstring_fr_ch.h b/quantum/keymap_extras/sendstring_fr_ch.h
new file mode 100644
index 000000000..2acce5663
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_fr_ch.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for Swiss French layouts
+
+#pragma once
+
+#include "keymap_fr_ch.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, CH_DIAE, CH_2, CH_3, CH_DLR, CH_5, CH_6, CH_QUOT,
+ // ( ) * + , - . /
+ CH_8, CH_9, CH_3, CH_0, CH_COMM, CH_MINS, CH_DOT, CH_7,
+ // 0 1 2 3 4 5 6 7
+ CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7,
+ // 8 9 : ; < = > ?
+ CH_8, CH_9, CH_DOT, CH_COMM, CH_LABK, CH_0, CH_LABK, CH_QUOT,
+ // @ A B C D E F G
+ CH_2, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G,
+ // H I J K L M N O
+ CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O,
+ // P Q R S T U V W
+ CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W,
+ // X Y Z [ \ ] ^ _
+ CH_X, CH_Y, CH_Z, CH_EGRV, CH_LABK, CH_DIAE, CH_CIRC, CH_MINS,
+ // ` a b c d e f g
+ CH_CIRC, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G,
+ // h i j k l m n o
+ CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O,
+ // p q r s t u v w
+ CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W,
+ // x y z { | } ~ DEL
+ CH_X, CH_Y, CH_Z, CH_AGRV, CH_7, CH_DLR, CH_CIRC, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_french.h b/quantum/keymap_extras/sendstring_french.h
index a02f114b4..17ea3ed45 100644
--- a/quantum/keymap_extras/sendstring_french.h
+++ b/quantum/keymap_extras/sendstring_french.h
@@ -74,7 +74,7 @@ const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
- KC_SPC, FR_EXLM, FR_QUOT, FR_DQUO, FR_DLR, FR_UGRV, FR_AMP, FR_QUOT,
+ KC_SPC, FR_EXLM, FR_QUOT, FR_DQUO, FR_DLR, FR_UGRV, FR_AMPR, FR_QUOT,
// ( ) * + , - . /
FR_LPRN, FR_RPRN, FR_ASTR, FR_EQL, FR_COMM, FR_MINS, FR_SCLN, FR_COLN,
// 0 1 2 3 4 5 6 7
diff --git a/quantum/keymap_extras/sendstring_french_osx.h b/quantum/keymap_extras/sendstring_french_osx.h
new file mode 100644
index 000000000..6cadbac15
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_french_osx.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for macOS French (AZERTY) layouts
+
+#pragma once
+
+#include "keymap_french_osx.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 0, 0, 0, 0, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, FR_EXLM, FR_DQUO, FR_AT, FR_DLR, FR_LUGR, FR_AMPR, FR_QUOT,
+ // ( ) * + , - . /
+ FR_LPRN, FR_RPRN, FR_DLR, FR_EQL, FR_COMM, FR_MINS, FR_SCLN, FR_COLN,
+ // 0 1 2 3 4 5 6 7
+ FR_LAGR, FR_AMPR, FR_LEAC, FR_DQUO, FR_QUOT, FR_LPRN, FR_SECT, FR_LEGR,
+ // 8 9 : ; < = > ?
+ FR_EXLM, FR_LCCE, FR_COLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_COMM,
+ // @ A B C D E F G
+ FR_AT, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
+ // H I J K L M N O
+ FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
+ // P Q R S T U V W
+ FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
+ // X Y Z [ \ ] ^ _
+ FR_X, FR_Y, FR_Z, FR_LPRN, FR_COLN, FR_RPRN, FR_CIRC, FR_MINS,
+ // ` a b c d e f g
+ FR_GRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
+ // h i j k l m n o
+ FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
+ // p q r s t u v w
+ FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
+ // x y z { | } ~ DEL
+ FR_X, FR_Y, FR_Z, FR_LPRN, FR_L, FR_RPRN, FR_N, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_german_ch.h b/quantum/keymap_extras/sendstring_german_ch.h
new file mode 100644
index 000000000..1e1327c51
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_german_ch.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for Swiss German layouts
+
+#pragma once
+
+#include "keymap_german_ch.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, CH_DIAE, CH_2, CH_3, CH_DLR, CH_5, CH_6, CH_QUOT,
+ // ( ) * + , - . /
+ CH_8, CH_9, CH_3, CH_1, CH_COMM, CH_MINS, CH_DOT, CH_7,
+ // 0 1 2 3 4 5 6 7
+ CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7,
+ // 8 9 : ; < = > ?
+ CH_8, CH_9, CH_DOT, CH_COMM, CH_LABK, CH_0, CH_LABK, CH_QUOT,
+ // @ A B C D E F G
+ CH_2, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G,
+ // H I J K L M N O
+ CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O,
+ // P Q R S T U V W
+ CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W,
+ // X Y Z [ \ ] ^ _
+ CH_X, CH_Y, CH_Z, CH_UDIA, CH_LABK, CH_DIAE, CH_CIRC, CH_MINS,
+ // ` a b c d e f g
+ CH_CIRC, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G,
+ // h i j k l m n o
+ CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O,
+ // p q r s t u v w
+ CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W,
+ // x y z { | } ~ DEL
+ CH_X, CH_Y, CH_Z, CH_ADIA, CH_7, CH_DLR, CH_CIRC, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_german_osx.h b/quantum/keymap_extras/sendstring_german_osx.h
new file mode 100644
index 000000000..03f54da2a
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_german_osx.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for macOS German layouts
+
+#pragma once
+
+#include "keymap_german_osx.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 1),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, DE_1, DE_2, DE_HASH, DE_4, DE_5, DE_6, DE_HASH,
+ // ( ) * + , - . /
+ DE_8, DE_9, DE_PLUS, DE_PLUS, DE_COMM, DE_MINS, DE_DOT, DE_7,
+ // 0 1 2 3 4 5 6 7
+ DE_0, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7,
+ // 8 9 : ; < = > ?
+ DE_8, DE_9, DE_DOT, DE_COMM, DE_LABK, DE_0, DE_LABK, DE_SS,
+ // @ A B C D E F G
+ DE_L, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G,
+ // H I J K L M N O
+ DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O,
+ // P Q R S T U V W
+ DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W,
+ // X Y Z [ \ ] ^ _
+ DE_X, DE_Y, DE_Z, DE_5, DE_7, DE_6, DE_CIRC, DE_MINS,
+ // ` a b c d e f g
+ DE_ACUT, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G,
+ // h i j k l m n o
+ DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O,
+ // p q r s t u v w
+ DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W,
+ // x y z { | } ~ DEL
+ DE_X, DE_Y, DE_Z, DE_8, DE_7, DE_9, DE_N, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_italian_osx_ansi.h b/quantum/keymap_extras/sendstring_italian_osx_ansi.h
new file mode 100644
index 000000000..c61874015
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_italian_osx_ansi.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for macOS Italian ANSI layouts
+
+#pragma once
+
+#include "keymap_italian_osx_ansi.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, IT_1, IT_2, IT_AGRV, IT_4, IT_5, IT_6, IT_QUOT,
+ // ( ) * + , - . /
+ IT_8, IT_9, IT_PLUS, IT_PLUS, IT_COMM, IT_MINS, IT_DOT, IT_7,
+ // 0 1 2 3 4 5 6 7
+ IT_0, IT_1, IT_2, IT_3, IT_4, IT_5, IT_6, IT_7,
+ // 8 9 : ; < = > ?
+ IT_8, IT_9, IT_DOT, IT_COMM, IT_LABK, IT_0, IT_LABK, IT_QUOT,
+ // @ A B C D E F G
+ IT_OGRV, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G,
+ // H I J K L M N O
+ IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O,
+ // P Q R S T U V W
+ IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W,
+ // X Y Z [ \ ] ^ _
+ IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_IGRV, IT_MINS,
+ // ` a b c d e f g
+ IT_BSLS, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G,
+ // h i j k l m n o
+ IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O,
+ // p q r s t u v w
+ IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W,
+ // x y z { | } ~ DEL
+ IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_5, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_italian_osx_iso.h b/quantum/keymap_extras/sendstring_italian_osx_iso.h
new file mode 100644
index 000000000..eb5853b00
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_italian_osx_iso.h
@@ -0,0 +1,100 @@
+/* Copyright 2020
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for macOS Italian ISO layouts
+
+#pragma once
+
+#include "keymap_italian_osx_iso.h"
+#include "quantum.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, IT_1, IT_2, IT_AGRV, IT_4, IT_5, IT_6, IT_QUOT,
+ // ( ) * + , - . /
+ IT_8, IT_9, IT_PLUS, IT_PLUS, IT_COMM, IT_MINS, IT_DOT, IT_7,
+ // 0 1 2 3 4 5 6 7
+ IT_0, IT_1, IT_2, IT_3, IT_4, IT_5, IT_6, IT_7,
+ // 8 9 : ; < = > ?
+ IT_8, IT_9, IT_DOT, IT_COMM, IT_LABK, IT_0, IT_LABK, IT_QUOT,
+ // @ A B C D E F G
+ IT_OGRV, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G,
+ // H I J K L M N O
+ IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O,
+ // P Q R S T U V W
+ IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W,
+ // X Y Z [ \ ] ^ _
+ IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_IGRV, IT_MINS,
+ // ` a b c d e f g
+ IT_BSLS, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G,
+ // h i j k l m n o
+ IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O,
+ // p q r s t u v w
+ IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W,
+ // x y z { | } ~ DEL
+ IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_5, KC_DEL
+};
diff --git a/quantum/keymap_extras/sendstring_workman_zxcvm.h b/quantum/keymap_extras/sendstring_workman_zxcvm.h
new file mode 100644
index 000000000..e7605d7cc
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_workman_zxcvm.h
@@ -0,0 +1,59 @@
+/* Copyright 2018 Jacob Jerrell
+ *
+ * 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/>.
+ */
+
+// Sendstring lookup tables for Workman ZXCVM layouts
+
+#pragma once
+
+#include "keymap_workman_zxcvm.h"
+
+// clang-format off
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, WK_1, WK_QUOT, WK_3, WK_4, WK_5, WK_7, WK_QUOT,
+ // ( ) * + , - . /
+ WK_9, WK_0, WK_8, WK_EQL, WK_COMM, WK_MINS, WK_DOT, WK_SLSH,
+ // 0 1 2 3 4 5 6 7
+ WK_0, WK_1, WK_2, WK_3, WK_4, WK_5, WK_6, WK_7,
+ // 8 9 : ; < = > ?
+ WK_8, WK_9, WK_SCLN, WK_SCLN, WK_COMM, WK_EQL, WK_DOT, WK_SLSH,
+ // @ A B C D E F G
+ WK_2, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G,
+ // H I J K L M N O
+ WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O,
+ // P Q R S T U V W
+ WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W,
+ // X Y Z [ \ ] ^ _
+ WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_6, WK_MINS,
+ // ` a b c d e f g
+ WK_GRV, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G,
+ // h i j k l m n o
+ WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O,
+ // p q r s t u v w
+ WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W,
+ // x y z { | } ~ DEL
+ WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_GRV, KC_DEL
+};
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 76a48cc77..2053a1a5f 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -149,18 +149,21 @@ void reset_keyboard(void) {
}
/* Convert record into usable keycode via the contained event. */
-uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
+uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { return get_event_keycode(record->event, update_layer_cache); }
/* Convert event into usable keycode. Checks the layer cache to ensure that it
* retains the correct keycode after a layer change, if the key is still pressed.
+ * "update_layer_cache" is to ensure that it only updates the layer cache when
+ * appropriate, otherwise, it will update it and cause layer tap (and other keys)
+ * from triggering properly.
*/
-uint16_t get_event_keycode(keyevent_t event) {
+uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) {
#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
/* TODO: Use store_or_get_action() or a similar function. */
if (!disable_action_cache) {
uint8_t layer;
- if (event.pressed) {
+ if (event.pressed && update_layer_cache) {
layer = layer_switch_get_layer(event.key);
update_source_layers_cache(event.key, layer);
} else {
@@ -174,7 +177,7 @@ uint16_t get_event_keycode(keyevent_t event) {
/* Get keycode, and then call keyboard function */
void post_process_record_quantum(keyrecord_t *record) {
- uint16_t keycode = get_record_keycode(record);
+ uint16_t keycode = get_record_keycode(record, false);
post_process_record_kb(keycode, record);
}
@@ -182,7 +185,7 @@ void post_process_record_quantum(keyrecord_t *record) {
then processes internal quantum keycodes, and then processes
ACTIONs. */
bool process_record_quantum(keyrecord_t *record) {
- uint16_t keycode = get_record_keycode(record);
+ uint16_t keycode = get_record_keycode(record, true);
// This is how you use actions here
// if (keycode == KC_LEAD) {
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 4b94ebcc0..45f44f49a 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -252,8 +252,8 @@ void matrix_init_kb(void);
void matrix_scan_kb(void);
void matrix_init_user(void);
void matrix_scan_user(void);
-uint16_t get_record_keycode(keyrecord_t *record);
-uint16_t get_event_keycode(keyevent_t event);
+uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache);
+uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
bool process_action_kb(keyrecord_t *record);
bool process_record_kb(uint16_t keycode, keyrecord_t *record);
bool process_record_user(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index f6aac2234..0958c4f4e 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -521,13 +521,15 @@ enum quantum_keycodes {
#define LSFT(kc) (QK_LSFT | (kc))
#define LALT(kc) (QK_LALT | (kc))
#define LGUI(kc) (QK_LGUI | (kc))
+#define LOPT(kc) LALT(kc)
#define LCMD(kc) LGUI(kc)
#define LWIN(kc) LGUI(kc)
#define RCTL(kc) (QK_RCTL | (kc))
#define RSFT(kc) (QK_RSFT | (kc))
#define RALT(kc) (QK_RALT | (kc))
-#define ALGR(kc) RALT(kc)
#define RGUI(kc) (QK_RGUI | (kc))
+#define ALGR(kc) RALT(kc)
+#define ROPT(kc) RALT(kc)
#define RCMD(kc) RGUI(kc)
#define RWIN(kc) RGUI(kc)
@@ -736,8 +738,11 @@ enum quantum_keycodes {
#define LALT_T(kc) MT(MOD_LALT, kc)
#define RALT_T(kc) MT(MOD_RALT, kc)
-#define ALT_T(kc) LALT_T(kc)
+#define LOPT_T(kc) LALT_T(kc)
+#define ROPT_T(kc) RALT_T(kc)
#define ALGR_T(kc) RALT_T(kc)
+#define ALT_T(kc) LALT_T(kc)
+#define OPT_T(kc) LOPT_T(kc)
#define LGUI_T(kc) MT(MOD_LGUI, kc)
#define RGUI_T(kc) MT(MOD_RGUI, kc)
diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h
index 86dc8bf00..1e8a8e9ff 100644
--- a/quantum/send_string_keycodes.h
+++ b/quantum/send_string_keycodes.h
@@ -96,11 +96,13 @@
/* Modifiers */
#define X_LCTL X_LCTRL
#define X_LSFT X_LSHIFT
+#define X_LOPT X_LALT
#define X_LCMD X_LGUI
#define X_LWIN X_LGUI
#define X_RCTL X_RCTRL
#define X_RSFT X_RSHIFT
#define X_ALGR X_RALT
+#define X_ROPT X_RALT
#define X_RCMD X_RGUI
#define X_RWIN X_RGUI
diff --git a/quantum/template/avr/config.h b/quantum/template/avr/config.h
index 7e4a01449..88402fbdd 100644
--- a/quantum/template/avr/config.h
+++ b/quantum/template/avr/config.h
@@ -192,10 +192,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define NO_ACTION_ONESHOT
/* disable these deprecated features by default */
-#ifndef LINK_TIME_OPTIMIZATION_ENABLE
- #define NO_ACTION_MACRO
- #define NO_ACTION_FUNCTION
-#endif
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
+
/*
* MIDI options
*/
diff --git a/quantum/template/ps2avrgb/config.h b/quantum/template/ps2avrgb/config.h
index 2eb484422..3f3fd5fd7 100644
--- a/quantum/template/ps2avrgb/config.h
+++ b/quantum/template/ps2avrgb/config.h
@@ -43,10 +43,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLIGHT_ANIMATIONS
/* disable these deprecated features by default */
-#ifndef LINK_TIME_OPTIMIZATION_ENABLE
- #define NO_ACTION_MACRO
- #define NO_ACTION_FUNCTION
-#endif
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
/* key combination for magic key command */
/* defined by default; to change, uncomment and set to the combination you want */
diff --git a/requirements-dev.txt b/requirements-dev.txt
new file mode 100644
index 000000000..1db3b6d73
--- /dev/null
+++ b/requirements-dev.txt
@@ -0,0 +1,8 @@
+# Install the necessary requirements
+-r requirements.txt
+
+# Python development requirements
+nose2
+flake8
+pep8-naming
+yapf
diff --git a/requirements.txt b/requirements.txt
index 074b11a8c..aa6ee1ba3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,6 +4,3 @@ appdirs
argcomplete
colorama
hjson
-nose2
-flake8
-pep8-naming
diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk
index a8d01a9e8..f5c125771 100644
--- a/tmk_core/avr.mk
+++ b/tmk_core/avr.mk
@@ -105,13 +105,6 @@ endef
teensy: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
$(call EXEC_TEENSY)
-BATCHISP ?= batchisp
-
-flip: $(BUILD_DIR)/$(TARGET).hex check-size
- $(BATCHISP) -hardware usb -device $(MCU) -operation erase f
- $(BATCHISP) -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program
- $(BATCHISP) -hardware usb -device $(MCU) -operation start reset 0
-
DFU_PROGRAMMER ?= dfu-programmer
GREP ?= grep
@@ -146,13 +139,6 @@ dfu-start:
$(DFU_PROGRAMMER) $(MCU) reset
$(DFU_PROGRAMMER) $(MCU) start
-flip-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep
- $(COPY) $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET)eep.hex
- $(BATCHISP) -hardware usb -device $(MCU) -operation memory EEPROM erase
- $(BATCHISP) -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(BUILD_DIR)/$(TARGET)eep.hex program
- $(BATCHISP) -hardware usb -device $(MCU) -operation start reset 0
- $(REMOVE) $(BUILD_DIR)/$(TARGET)eep.hex
-
dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep
if $(DFU_PROGRAMMER) --version 2>&1 | $(GREP) -q 0.7 ; then\
$(DFU_PROGRAMMER) $(MCU) flash --eeprom $(BUILD_DIR)/$(TARGET).eep;\
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 4d4272d26..3d0b83a01 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -162,8 +162,6 @@ ifeq ($(strip $(LINK_TIME_OPTIMIZATION_ENABLE)), yes)
endif
EXTRAFLAGS += -flto
TMK_COMMON_DEFS += -DLINK_TIME_OPTIMIZATION_ENABLE
- TMK_COMMON_DEFS += -DNO_ACTION_MACRO
- TMK_COMMON_DEFS += -DNO_ACTION_FUNCTION
endif
# Search Path
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 74db245c1..27c0abe6f 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -324,7 +324,7 @@ void process_action(keyrecord_t *record, action_t action) {
# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
if (
# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
- !get_ignore_mod_tap_interrupt(get_event_keycode(record->event)) &&
+ !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false)) &&
# endif
record->tap.interrupted) {
dprint("mods_tap: tap: cancel: add_mods\n");
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index dd22023f9..c82c9c81b 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -28,6 +28,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern "C" {
#endif
+/* Disable macro and function features when LTO is enabled, since they break */
+#ifdef LINK_TIME_OPTIMIZATION_ENABLE
+# ifndef NO_ACTION_MACRO
+# define NO_ACTION_MACRO
+# endif
+# ifndef NO_ACTION_FUNCTION
+# define NO_ACTION_FUNCTION
+# endif
+#endif
+
/* tapping count and state */
typedef struct {
bool interrupted : 1;
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index acce3ee51..34f08d890 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -22,7 +22,7 @@
__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode) { return TAPPING_TERM; }
# ifdef TAPPING_TERM_PER_KEY
-# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event)))
+# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false)))
# else
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
# endif
@@ -122,10 +122,10 @@ bool process_tapping(keyrecord_t *keyp) {
# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
else if (
# ifdef TAPPING_TERM_PER_KEY
- (get_tapping_term(get_event_keycode(tapping_key.event)) >= 500) &&
+ (get_tapping_term(get_event_keycode(tapping_key.event, false)) >= 500) &&
# endif
# ifdef PERMISSIVE_HOLD_PER_KEY
- !get_permissive_hold(get_event_keycode(tapping_key.event), keyp) &&
+ !get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp) &&
# endif
IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
@@ -246,7 +246,7 @@ bool process_tapping(keyrecord_t *keyp) {
# if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY)
if (
# ifdef TAPPING_FORCE_HOLD_PER_KEY
- !get_tapping_force_hold(get_event_keycode(tapping_key.event), keyp) &&
+ !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) &&
# endif
!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h
index 509d5eabd..5eaef1c5f 100644
--- a/tmk_core/common/action_tapping.h
+++ b/tmk_core/common/action_tapping.h
@@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define WAITING_BUFFER_SIZE 8
#ifndef NO_ACTION_TAPPING
-uint16_t get_event_keycode(keyevent_t event);
+uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
uint16_t get_tapping_term(uint16_t keycode);
void action_tapping_process(keyrecord_t record);
#endif
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index e1059fadf..5c8ba8fe6 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -152,11 +152,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Modifiers */
#define KC_LCTL KC_LCTRL
#define KC_LSFT KC_LSHIFT
+#define KC_LOPT KC_LALT
#define KC_LCMD KC_LGUI
#define KC_LWIN KC_LGUI
#define KC_RCTL KC_RCTRL
#define KC_RSFT KC_RSHIFT
#define KC_ALGR KC_RALT
+#define KC_ROPT KC_RALT
#define KC_RCMD KC_RGUI
#define KC_RWIN KC_RGUI
diff --git a/tmk_core/common/timer.h b/tmk_core/common/timer.h
index bbaae109d..52bc1cc67 100644
--- a/tmk_core/common/timer.h
+++ b/tmk_core/common/timer.h
@@ -25,7 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "avr/timer_avr.h"
#endif
-#define TIMER_DIFF(a, b, max) ((a) >= (b) ? (a) - (b) : (max) - (b) + (a))
+#define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a)))))
#define TIMER_DIFF_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)
#define TIMER_DIFF_16(a, b) TIMER_DIFF(a, b, UINT16_MAX)
#define TIMER_DIFF_32(a, b) TIMER_DIFF(a, b, UINT32_MAX)
diff --git a/tmk_core/protocol/chibios/init_hooks.h b/tmk_core/protocol/chibios/init_hooks.h
new file mode 100644
index 000000000..fffced913
--- /dev/null
+++ b/tmk_core/protocol/chibios/init_hooks.h
@@ -0,0 +1,5 @@
+#pragma once
+
+// Override the initialisation functions inside the ChibiOS board.c files
+#define __early_init __chibios_override___early_init
+#define boardInit __chibios_override_boardInit
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 6479fd09d..61665eb6f 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -33,6 +33,11 @@
#include "debug.h"
#include "printf.h"
+#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP
+// Change this to be TRUE once we've migrated keyboards to the new init system
+# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE
+#endif
+
#ifdef SLEEP_LED_ENABLE
# include "sleep_led.h"
#endif
@@ -101,6 +106,39 @@ void midi_ep_task(void);
// }
// }
+/* Early initialisation
+ */
+__attribute__((weak)) void early_hardware_init_pre(void) {
+#if EARLY_INIT_PERFORM_BOOTLOADER_JUMP
+ void enter_bootloader_mode_if_requested(void);
+ enter_bootloader_mode_if_requested();
+#endif // EARLY_INIT_PERFORM_BOOTLOADER_JUMP
+}
+
+__attribute__((weak)) void early_hardware_init_post(void) {}
+
+__attribute__((weak)) void board_init(void) {}
+
+// This overrides what's normally in ChibiOS board definitions
+void __early_init(void) {
+ early_hardware_init_pre();
+
+ // This is the renamed equivalent of __early_init in the board.c file
+ void __chibios_override___early_init(void);
+ __chibios_override___early_init();
+
+ early_hardware_init_post();
+}
+
+// This overrides what's normally in ChibiOS board definitions
+void boardInit(void) {
+ // This is the renamed equivalent of boardInit in the board.c file
+ void __chibios_override_boardInit(void);
+ __chibios_override_boardInit();
+
+ board_init();
+}
+
/* Main thread
*/
int main(void) {
diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk
index d7d1d9ffc..d87802992 100644
--- a/tmk_core/protocol/lufa.mk
+++ b/tmk_core/protocol/lufa.mk
@@ -29,6 +29,7 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
+ LUFA_SRC += spi_master.c
LUFA_SRC += analog.c
LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
endif
diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble.cpp
index 7b3ffdef7..b07407f38 100644
--- a/tmk_core/protocol/lufa/adafruit_ble.cpp
+++ b/tmk_core/protocol/lufa/adafruit_ble.cpp
@@ -1,15 +1,15 @@
#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>
+#include "spi_master.h"
+#include "wait.h"
#include "analog.h"
// These are the pin assignments for the 32u4 boards.
@@ -27,6 +27,12 @@
# define AdafruitBleIRQPin E6
#endif
+#ifndef AdafruitBleSpiClockSpeed
+# define AdafruitBleSpiClockSpeed 4000000UL // SCK frequency
+#endif
+
+#define SCK_DIVISOR (F_CPU / AdafruitBleSpiClockSpeed)
+
#define SAMPLE_BATTERY
#define ConnectionUpdateInterval 1000 /* milliseconds */
@@ -130,10 +136,6 @@ enum ble_system_event_bits {
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 */
@@ -142,116 +144,32 @@ enum ble_system_event_bits {
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);
-#if F_CPU == 8000000
- // For MCUs running at 8MHz (such as Feather 32U4, or 3.3V Pro Micros) we set the SPI doublespeed bit
- spi->spsr = _BV(SPI2X);
-#endif
-
- 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);
+ spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
uint16_t timerStart = timer_read();
bool success = false;
bool ready = false;
do {
- ready = SPI_TransferByte(msg->type) != SdepSlaveNotReady;
+ ready = spi_write(msg->type) != SdepSlaveNotReady;
if (ready) {
break;
}
// Release it and let it initialize
- digitalWrite(AdafruitBleCSPin, PinLevelHigh);
- _delay_us(SdepBackOff);
- digitalWrite(AdafruitBleCSPin, PinLevelLow);
+ spi_stop();
+ wait_us(SdepBackOff);
+ spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
} 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);
+ spi_transmit(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len);
success = true;
}
- digitalWrite(AdafruitBleCSPin, PinLevelHigh);
+ spi_stop();
return success;
}
@@ -275,41 +193,39 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
bool ready = false;
do {
- ready = digitalRead(AdafruitBleIRQPin);
+ ready = readPin(AdafruitBleIRQPin);
if (ready) {
break;
}
- _delay_us(1);
+ wait_us(1);
} while (timer_elapsed(timerStart) < timeout);
if (ready) {
- SPI_begin(&spi);
-
- digitalWrite(AdafruitBleCSPin, PinLevelLow);
+ spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
do {
// Read the command type, waiting for the data to be ready
- msg->type = spi_read_byte();
+ msg->type = spi_read();
if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) {
// Release it and let it initialize
- digitalWrite(AdafruitBleCSPin, PinLevelHigh);
- _delay_us(SdepBackOff);
- digitalWrite(AdafruitBleCSPin, PinLevelLow);
+ spi_stop();
+ wait_us(SdepBackOff);
+ spi_start(AdafruitBleCSPin, false, 0, SCK_DIVISOR);
continue;
}
// Read the rest of the header
- spi_recv_bytes(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)));
+ spi_receive(&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);
+ spi_receive(msg->payload, msg->len);
}
success = true;
break;
} while (timer_elapsed(timerStart) < timeout);
- digitalWrite(AdafruitBleCSPin, PinLevelHigh);
+ spi_stop();
}
return success;
}
@@ -320,7 +236,7 @@ static void resp_buf_read_one(bool greedy) {
return;
}
- if (digitalRead(AdafruitBleIRQPin)) {
+ if (readPin(AdafruitBleIRQPin)) {
struct sdep_msg msg;
again:
@@ -331,7 +247,7 @@ static void resp_buf_read_one(bool greedy) {
dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send));
}
- if (greedy && resp_buf.peek(last_send) && digitalRead(AdafruitBleIRQPin)) {
+ if (greedy && resp_buf.peek(last_send) && readPin(AdafruitBleIRQPin)) {
goto again;
}
}
@@ -361,7 +277,7 @@ static void send_buf_send_one(uint16_t timeout = SdepTimeout) {
dprintf("send_buf_send_one: have %d remaining\n", (int)send_buf.size());
} else {
dprint("failed to send, will retry\n");
- _delay_ms(SdepTimeout);
+ wait_ms(SdepTimeout);
resp_buf_read_one(true);
}
}
@@ -382,20 +298,18 @@ static bool ble_init(void) {
state.configured = false;
state.is_connected = false;
- pinMode(AdafruitBleIRQPin, PinDirectionInput);
- pinMode(AdafruitBleCSPin, PinDirectionOutput);
- digitalWrite(AdafruitBleCSPin, PinLevelHigh);
+ setPinInput(AdafruitBleIRQPin);
- SPI_init(&spi);
+ spi_init();
// Perform a hardware reset
- pinMode(AdafruitBleResetPin, PinDirectionOutput);
- digitalWrite(AdafruitBleResetPin, PinLevelHigh);
- digitalWrite(AdafruitBleResetPin, PinLevelLow);
- _delay_ms(10);
- digitalWrite(AdafruitBleResetPin, PinLevelHigh);
+ setPinOutput(AdafruitBleResetPin);
+ writePinHigh(AdafruitBleResetPin);
+ writePinLow(AdafruitBleResetPin);
+ wait_ms(10);
+ writePinHigh(AdafruitBleResetPin);
- _delay_ms(1000); // Give it a second to initialize
+ wait_ms(1000); // Give it a second to initialize
state.initialized = true;
return state.initialized;
@@ -596,7 +510,7 @@ void adafruit_ble_task(void) {
resp_buf_read_one(true);
send_buf_send_one(SdepShortTimeout);
- if (resp_buf.empty() && (state.event_flags & UsingEvents) && digitalRead(AdafruitBleIRQPin)) {
+ if (resp_buf.empty() && (state.event_flags & UsingEvents) && readPin(AdafruitBleIRQPin)) {
// Must be an event update
if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) {
uint32_t mask = strtoul(resbuf, NULL, 16);
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index aa3a307eb..a0e52bc7c 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -157,6 +157,21 @@ static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report)
// invert coordinate of y to conform to USB HID mouse
mouse_report->y = -mouse_report->y;
#endif
+
+#ifdef PS2_MOUSE_ROTATE
+ int8_t x = mouse_report->x;
+ int8_t y = mouse_report->y;
+# if PS2_MOUSE_ROTATE == 90
+ mouse_report->x = y;
+ mouse_report->y = -x;
+# elif PS2_MOUSE_ROTATE == 180
+ mouse_report->x = -x;
+ mouse_report->y = -y;
+# elif PS2_MOUSE_ROTATE == 270
+ mouse_report->x = -y;
+ mouse_report->y = x;
+# endif
+#endif
}
static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk
index c1474a5c2..f45fd3792 100644
--- a/tmk_core/rules.mk
+++ b/tmk_core/rules.mk
@@ -223,6 +223,12 @@ $(foreach LOBJ, $(NO_LTO_OBJ), $(eval $(call NO_LTO,$(LOBJ))))
MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@)
+# For a ChibiOS build, ensure that the board files have the hook overrides injected
+define BOARDSRC_INJECT_HOOKS
+$(KEYBOARD_OUTPUT)/$(patsubst %.c,%.o,$(patsubst ./%,%,$1)): INIT_HOOK_CFLAGS += -include $(TOP_DIR)/tmk_core/protocol/chibios/init_hooks.h
+endef
+$(foreach LOBJ, $(BOARDSRC), $(eval $(call BOARDSRC_INJECT_HOOKS,$(LOBJ))))
+
# Add QMK specific flags
DFU_SUFFIX ?= dfu-suffix
DFU_SUFFIX_ARGS ?=
@@ -306,27 +312,27 @@ ifdef $1_CONFIG
$1_CONFIG_FLAGS += $$(patsubst %,-include %,$$($1_CONFIG))
endif
$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
-$1_CXXFLAGS= $$(ALL_CXXFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
-$1_ASFLAGS= $$(ALL_ASFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
+$1_CXXFLAGS = $$(ALL_CXXFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
+$1_ASFLAGS = $$(ALL_ASFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
# Compile: create object files from C source files.
$1/%.o : %.c $1/%.d $1/cflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING) $$<" | $$(AWK_CMD)
- $$(eval CMD := $$(CC) -c $$($1_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
+ $$(eval CMD := $$(CC) -c $$($1_CFLAGS) $$(INIT_HOOK_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
# Compile: create object files from C++ source files.
$1/%.o : %.cpp $1/%.d $1/cxxflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING_CXX) $$<" | $$(AWK_CMD)
- $$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
+ $$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(INIT_HOOK_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
$1/%.o : %.cc $1/%.d $1/cxxflags.txt $1/compiler.txt | $(BEGIN)
@mkdir -p $$(@D)
@$$(SILENT) || printf "$$(MSG_COMPILING_CXX) $$<" | $$(AWK_CMD)
- $$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
+ $$(eval CMD=$$(CC) -c $$($1_CXXFLAGS) $$(INIT_HOOK_CFLAGS) $$(GENDEPFLAGS) $$< -o $$@ && $$(MOVE_DEP))
@$$(BUILD_CMD)
# Assemble: create object files from assembler source files.
@@ -433,7 +439,7 @@ $(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null)))
.PHONY : all finish sizebefore sizeafter qmkversion \
gccversion build elf hex eep lss sym coff extcoff \
clean clean_list debug gdb-config show_path \
-program teensy dfu flip dfu-ee flip-ee dfu-start \
+program teensy dfu dfu-ee dfu-start \
flash dfu-split-left dfu-split-right \
avrdude-split-left avrdude-split-right \
avrdude-loop usbasp
diff --git a/users/dennytom/chording_engine/README.md b/users/dennytom/chording_engine/README.md
new file mode 100644
index 000000000..3610b190b
--- /dev/null
+++ b/users/dennytom/chording_engine/README.md
@@ -0,0 +1,376 @@
+# README
+
+## About
+
+This is a custom combo engine. I call it chording engine mostly to differentiate it from QMK's combos. It is useful even if you are not using chording as a main input method to replace combos.
+
+Why does this exist? Typing on tiny keyboards can be challenging and you will end up relying on dances and / or combos. Pure QMK combos can be insufficient as they do not really support overlapping combos. For example, if you define 3 combos `(KC_Q, KC_W)`, `(KC_Z, KC_X)` and `(KC_Q, KC_W, KC_Z, KC_X)` and press Q, W, Z and X at the same time, all three combos will activate. Steno engines (and g Board Industries' custom steno inspired engine) solve this, however, they don't allow for comfortable typing in the traditional way. The steno chord activates only when *all* keys are lifted and makes it difficult to implement some advanced features. This engine treats each chord independently to allow for more comfortable typing experience.
+
+## TOC
+
+- [README](#readme)
+ - [About](#about)
+ - [TOC](#toc)
+ - [Start here](#start-here)
+ - [Steps](#steps)
+ - [Features](#features)
+ - [Chords](#chords)
+ - [Tap-Dance](#tap-dance)
+ - [Pseudolayers](#pseudolayers)
+ - [Control chords](#control-chords)
+ - [Settings up JSON definition](#settings-up-json-definition)
+ - [Keyboard and engine parameters](#keyboard-and-engine-parameters)
+ - [Pseudolayers](#pseudolayers-1)
+ - [Supported keycodes](#supported-keycodes)
+ - [Leader Key](#leader-key)
+ - [Extra code](#extra-code)
+ - [Further details](#further-details)
+ - [Implementation](#implementation)
+ - [Internal keycodes](#internal-keycodes)
+ - [Chords](#chords-1)
+ - [Caveats](#caveats)
+
+## Start here
+
+This engine therefore uses python parser that translates a JSON definition of keyboard specific information and keymap definition and produces `keymap.c`. Every function on this keymap is a chord (combo). The resulting keymap file is long and I do not encourage you to edit it. All you should have to edit is the JSON file. To produce the keymap file, run
+
+```sh
+./parser.py keymap_def.json keymap.c
+```
+
+To prepare the keymap JSON definition, you can use on of my keymaps as a starting point. I have on for butterstick and for georgi. There is also a JSON schema that has some examples and sane defaults. All details are explained in the next section. The parser tries to validate some of the things that the JSON schema can not. Finally there is a JSON in the tests folder that has at least one example of every feature.
+
+Watch out, you can not name your JSON file `keymap.json` if you place in the keymap folder. QMK creates `keymap.json` as a part of compilation process and if you already have one, it gets confused.
+
+## Steps
+
+When setting up a new keyboard, follow the steps:
+
+1. Make a new directory for your keymap as QMK's documentation describes.
+2. Write your JSON. Name it anything but `keymap.json`.
+3. Depending on the keyboard / keymap, create `rules.mk` (follow QMK's documentation and note that if the keyboard's `rules.mk` include custom source files, this is the place you can remove them).
+4. Use my python parser to generate the `keymap.c`. Run it from the `/users/dennytom/chording_engine` directory as it is using relative paths to some extra files.
+5. Follow QMK's documentation to compile and flash your firmware.
+
+## Features
+
+### Chords
+
+Once again, *everything* on this keymap is a chord. Even sending `KC_Q` is done by pressing a single key chord. Chord gets activated after all it's keys get pressed. Only the longest chord gets activated. The order of the pressed keys *does not matter*, only the fact they have been pressed within the same time frame. An active chord gets deactivated if *any* of it's keys gets depressed. To activate the same single chord again, *all* it's keys have to be depressed and pressed again. With a few exceptions chords are independent of each other. No matter if some chords are currently active and some not, others can be activated or deactivated without affecting each other's state. *If you press keys to belonging to multiple different, non-overlapping chords, all get activated in the order they are defined in the keymap.*
+
+### Tap-Dance
+
+To make it even stranger, all chords are technically tap-dance chords. They are relatively simple state machines that execute a specific function every time they change state. For simplicity and optimization purposes, there are a few prewritten functions that implement common features like "send a single key" or "lock". Any number of chords can be "in dance" at any given moment without affecting each other's state. Custom dances can be easily added. Check out the `state_machine.png` to see all the states any chord can be in.
+
+### Pseudolayers
+
+Only one QMK layer is used. Following the butterstick's default keymap's example, the chording engine is using pseudolayers. The main difference to QMK's layers is that only one pseudolayer can be active at each time (meaning you can not use `KC_TRANS`, I actually don't know what will happen if you do). Chords can be activated only if they are on the currently active pseudolayer. Chords that are currently active do not get deactivated if the pseudolayer changes and will deactivate if any of their keys gets depressed even no matter the current pseudolayer. Locked chords (see below) and chords on the `ALWAYS_ON` pseudolayer can be activated anytime.
+
+### Control chords
+
+The engine implements a number of ways of changing how chords behave:
+
+* **Lock**: Similarly to QMK's lock, the next chord activated after the Lock chord will not deactivate on release of any of its keys, it will deactivate when all its keys get pressed again. Any number of chords can be locked at the same time. To make sure a locked chord can be unlocked, it can activate no matter the current pseudolayer. A chord can be locked mid dance.
+* **One shots**: Chords that send keycodes and chords that turn on pseudolayers can be one shots. If tapped, they will lock (stay active) until the next keycode gets sent, *not necessarily when the next chord gets activated*. If held, they will deactivate on release *even if no keycode got sent*.
+* **Tap-Hold**: Also called key-layer dance and key-key dance. Either sends a defined keycode on tap and temporarily switches pseudolayer on hold *or* sends two different keycodes on tap and hold.
+* **Command mode**: After getting activated for the first time, the keyboard switches to command mode. All *keycodes* that would get registered get buffered instead. After activating the Command mode chord for the second time, all buffered keycodes get released at the same time allowing for key combination that would be hard or impossible to press. The Command mode only affects keycodes. It is therefore possible to change pseudolayers or activate / deactivate other chords while in Command mode. While multiple Command mode chords can be defined, they would not be independent. The keyboard either is or is not in command mode and there is only one buffer.
+* **Leader key**: Just like pure QMK's Leader key, this allows you to add functions that get executed if the Leader key and a specific sequence of keycodes gets registered in a predefined order in a short timeframe. For example `:wq` can send `Ctrl+S` and `Ctrl+W` in a quick succession. While multiple Leader keys can be defined, they all would access the same list of sequences.
+* **Dynamic macro**: A sequence of keycodes can be recorded and stored in the RAM of the keyboard and replayed.
+
+## Settings up JSON definition
+
+The JSON definition has 3 main sections. The elements `keys`, `parameters` and `layers` teach the engine about the details of your keyboard and set its parameters. The elements `pseudolayers`, `leader_sequences` and `chord_sets` define your keymap. Finally, the elements `extra_code` and `extra_dependencies` allow you to include more code to extend the capabilities of the engine.
+
+### Keyboard and engine parameters
+
+I do not have experience with stenography, so the the steno keycodes are hard for me to remember. That is why the keymap is using new keycodes TOP1, TOP2, ... .
+
+```c
+ "keys": ["TOP1", "TOP2", "TOP3", ...]
+```
+
+You can name these however you like as long as they do not crash with QMK's keycodes.
+
+*The chording engine in it's current implementation can handle up to 64 keys. If you need to support more, contact me (email or u/DennyTom at Reddit).*
+
+All timings, maximum lengths for macros, command mode and leader function are defined in `keyboard_parameters` field. Almost all should be pretty self-explanatory.
+
+My keyboards are small, so I only use the engine, but you might want to use layers that combine chord-able keys and traditional QMK keys or layers with advanced keycodes, for example for stenography. The array `layers` defines all the parser needs to know:
+
+```json
+"layers": [
+ {
+ "type": "auto"
+ },
+ {
+ "type": "manual",
+ "keycodes": ["KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0",
+ "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P"
+ ]
+ },
+ {
+ "type": "manual",
+ "keycodes": ["KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0",
+ "BOT1", "BOT2", "BOT3", "BOT4", "BOT5", "BOT6", "BOT7", "BOT8", "BOT9", "BOT0"]
+ }
+ ]
+```
+
+This example defines 3 layers, one that is automatically populated with chording engine's internal keycodes, second that is populated with QMK's keycodes and third that uses both internal and QMK's keycodes. The layers do not have names, you have to access them with `TO(1)` and `TO(0)`.
+
+Some keyboards mangle the order of keycodes when registering them in the layers. For that fill up the `layout_function_name` with the name of function / macro. If your keyboard does not do it, leave that string empty.
+
+### Pseudolayers
+
+Array `pseudolayers` defines the keymap per pseudolayer. Each field has to contain the name for the layer and the list of chords.
+
+```JSON
+"pseudolayers": [
+ {
+ "name": "QWERTY",
+ "chords": [
+ {
+ "type": "simple",
+ "keycode": "SPACE",
+ "chord": ["BOT1", "BOT0"]
+ },
+ {
+ "type": "visual",
+ "keycode": "CLEAR_KB",
+ "chord": [
+ "X", "", "", "", "", "", "", "", "", "X",
+ "X", "", "", "", "", "", "", "", "", "X",
+ ]
+ },
+ {
+ "type": "visual_array",
+ "keys": ["TOP1", "TOP2", "TOP3"],
+ "dictionary": [
+ ["X", "X", " ", "ESC"],
+ [" ", "X", "X", "TAB"],
+ ["X", "X", "X", "ENTER"]
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+ "A", "S", "D", "F", "G", "H", "J", "K", "L", ";",
+ "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/"
+ ]
+ }
+ ]
+ }
+]
+```
+
+The array `chord` defines chords. You can either use simple chord and list all the keys that have to pressed at the same time, or use the visual chord and place `"X"` over keys that will be part of the chord. You can also use `visual_array` to define a number of chords in a visual way on a subset of keys defined in the `keys` array. Finally, you can use `chord_set` to define a number of chords following a pattern that was set in the `chord_sets` array in the root object like this:
+
+```json
+"chord_sets": [
+ {
+ "name": "rows",
+ "chords": [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP5"], ["TOP6"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP0"]
+ ["TOP1", "BOT1"], ["TOP2", "BOT2"], ["TOP3", "BOT3"], ["TOP4", "BOT4"], ["TOP5", "BOT5"], ["TOP6", "BOT6"], ["TOP7", "BOT7"], ["TOP8", "BOT8"], ["TOP9", "BOT9"], ["TOP0", "BOT0"],
+ ["BOT1"], ["BOT2"], ["BOT3"], ["BOT4"], ["BOT5"], ["BOT6"], ["BOT7"], ["BOT8"], ["BOT9"], ["BOT0"]
+ ]
+ },
+ {
+ "name": "cols",
+ "chords": [
+ ["TOP1", "TOP2"], ["TOP2", "TOP3"], ["TOP3", "TOP4"], ["TOP4", "TOP5"], ["TOP5", "TOP6"], ["TOP6", "TOP7"], ["TOP7", "TOP8"], ["TOP8", "TOP9"], ["TOP9", "TOP0"],
+ ["TOP1", "TOP2", "BOT1", "BOT2"], ["TOP2", "TOP3", "BOT2", "BOT3"], ["TOP3", "TOP4", "BOT3", "BOT4"], ["TOP4", "TOP5", "BOT4", "BOT5"], ["TOP5", "TOP6", "BOT5", "BOT6"], ["TOP6", "TOP7", "BOT6", "BOT7"], ["TOP7", "TOP8", "BOT7", "BOT8"], ["TOP8", "TOP9", "BOT8", "BOT9"], ["TOP9", "TOP0", "BOT9", "BOT0"],
+ ["BOT1", "BOT2"], ["BOT2", "BOT3"], ["BOT3", "BOT4"], ["BOT4", "BOT5"], ["BOT5", "BOT6"], ["BOT6", "BOT7"], ["BOT7", "BOT8"], ["BOT8", "BOT9"], ["BOT9", "BOT00"],
+ ]
+ }
+]
+```
+
+
+
+You might notice that the code tries to do a few clever things when parsing keycodes:
+
+* If the keycode would be just a character basic keycode, it tries to allow the use of shortcuts. `Q` will get replaced with `KC_Q`, `,` becomes `KC_COMMA`. This *should* work for all KC_ keycodes unless I missed some.
+* `MO()` and `DF()` macros work the same way for pseudolayers as they would for layers in pure QMK.
+* `O()` is a shortcut for `OSK()` or `OSL()`.
+* `STR('...')` sends a string. Careful with quoting.
+* Special chords like Command mode have their own codes like `CMD`.
+* The empty strings get ignored.
+
+### Supported keycodes
+
+* **`X`** or **`KC_X`**: Send code `KC_X` just like a normal keyboard.
+
+* **`STR("X")`**: Send string "x" on each activation of the chord. Once again, watch out for quoting and escaping characters. If you want special characters (especially quotes) in your string, look up Python reference for string literals and experiment. Also, because of how the string gets parsed, it is not possible to use `(` in the string.
+
+* **`MO(X)`**: Temporary switch to pseudolayer `X`. Because only one pseudolayer can be active at any moment, this works by switching back to the pseudolayer the chord lives on on deactivation. If you chain `MO()`s on multiple pseudolayers and deactivate them in a random order, you might end up stranded on a pseudolayer. I recommend adding `CLEAR` somewhere on `ALWAYS_ON` pseudolayer just in case.
+
+* **`MO(X,Y)`**: Temporary switch to pseudolayer `Y`. Switches to pseudolayer `X` on deactivation. Especially useful when you want to put the `MO()` chord on `ALWAYS_ON`.
+
+* **`DF(X)`**: Permanent switch to pseudolayer `X`.
+
+* **`TO(X)`**: Switches the QMK layer to `X`.
+
+* **`O(X)`**: One-shot key `X` (if `X` starts with `"KC_"`) or one-shot layer `X` (otherwise) . Both have retro tapping enabled.
+
+* **Tap-holds**
+
+ * **`KK(X, Y)`**: Pulses code `X` on tap and code `Y` on hold.
+ * **`KL(X, Y)`**: Pulses code `X` on tap and switches to pseudolayer `Y` on hold. If during the hold no key gets registered, the code `X` will get sent instead (similar to QMK's retro tapping).
+ * **`KM(X, Y)`**: Same as `KK()` but meant for modifiers on hold. Instead of a timer to figure out tap-hold, uses retro tapping like behavior just like `KL()`. This has issues with GUI and ALT as they often have a meaning.
+ * The chording engine determines if you are holding a chord based on a *global* timer. If you start holding a tap-hold chord and very quickly start tapping other chords, the hold might not activate until a short moment *after the last* chord when the timer expires. If you are running into this, adjust timeouts or wait a brief moment after pressing the chord to make sure it switches into the hold state before pressing other chords.
+
+* **Autoshift**
+
+ * **`AS(X)`**: Pulses code `X` on tap and Pulses left shift + `X` on hold.
+ * **`AT`** : Toggles autoshift for all autoshift chords. If off, all `AS` chords act like `KC` chords.
+
+* **`LOCK`**: The lock key. Since tap-dances of chords are independent, it is possible to lock a chord *anywhere in it's dance if you time it right!*. If that happens, use the `CLEAR` chord or restart your keeb.
+
+* **`CMD`**: The command mode. The number of keycodes that can be buffered is defined in in `command_max_length`.
+
+* **`LEAD`**: The leader key. The maximum length of the sequences needs to be defined in `keyboard_params`. You can use `leader_sequences` array to add sequences:
+
+ ```json
+ "leader_sequences": [
+ {
+ "name": "fn_L1",
+ "function": "void fn_L1(void) { SEND(KC_LCTL); SEND(KC_LALT); SEND(KC_DEL); }",
+ "sequence": ["KC_Q", "KC_Z"]
+ }
+ ]
+ ```
+
+ When the engine notices the sequence, it will call the function defined in the field `name`. You can either define it in the `function` field, in the field `extra_code` or in an external file that you then have to insert manually or using the `extra_dependencies` array. The parser copy-pastes the contents `extra_code` of all files specified in the `extra_dependencies` array in the `keymap.c`.
+
+* **`M(X, VALUE1, VALUE2)`**: A custom macro. Adds a chord that will use function `X` and with `chord.value1 = VALUE1; chord.value2 = VALUE2;`. The function `X` can be arbitrary C function, go crazy. Just like with the leader sequences, you have to insert the code into the generated `keymap.c` manually or through `extra_code` or `extra_dependencies`. The following example defines a macro that acts exactly like `KC_MEH` (the chording engine *should* support `KC_MEH`, this is just an example):
+
+ ```c
+ void fn_M1(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(KC_LCTL);
+ key_in(KC_LSFT);
+ key_in(KC_LALT);
+ break;
+ case DEACTIVATED:
+ key_out(KC_LCTL);
+ key_out(KC_LSFT);
+ key_out(KC_LALT);
+ break;
+ case FINISHED:
+ case FINISHED_FROM_ACTIVE:
+ break;
+ case RESTART:
+ key_out(KC_LCTL);
+ key_out(KC_LSFT);
+ key_out(KC_LALT);
+ break;
+ default:
+ break;
+ }
+ }
+ ```
+
+ Since this feels like it would be the most common way to use this feature, I wrote a macro for this:
+
+* **`MK(X1, X2, ...)`**: Acts like `KC()` except it registers / unregisters all `X1`, `X2`, ... codes at the same time.
+
+* **`D(X1, X2, ...)`**: A basic keycode dance. If tapped (or held), registers `X1`. If tapped and then tapped again (or held), registers `X2`, ... It *cannot* be combined with tap-hold, however holding will result in repeat. You can put in as many basic keycodes as you want, but the macro will break if you go beyond 256. It will try to expand shortened keycodes. Advanced keycodes are not supported.
+
+* **`DM_RECORD`, `DM_NEXT`, `DM_END`, `DM_PLAY`**: Start recording a dynamic macro. Once you start recording, basic keycodes will get stored. When replaying the macro, all keys you press before `DM_NEXT` or `DM_END` will get pressed at the same time. For example the sequence `DM_RECORD`, `KC_CTRL`, `KC_A`, `DM_NEXT`, `KC_BSPC`, `DM_END` will record a macro that when played will execute the sequence Ctrl+a, Backspace. `dynamic_macro_max_length` defines the maximum length of the macro to be recorded. You can increase it for the price of RAM. The example above requires 4 units of length to be saved (Ctrl, A, next, Backspace).
+
+* **`CLEAR_KB`**: clears keyboard, sets all chords to the default state and switches the pseudolayer to the default one. Basically the emergency stop button.
+
+* **`RESET`**: Go to the DFU flashing mode.
+
+**Caveat** of the current implementation is that the tap-hold, `MK` and `D` keycodes can not accept any of the keycodes that have some sort a function like dynamic macro specific chords, `CLEAR_KB`, `RESET`, `LOCK`, `AT`, ...
+
+### Leader Key
+
+The sequences are not defined by the *keys* you press but by the *keycodes* that get intercepted. The length of the sequence must be equal or shorter than the maximum (defined in `keyboard.inc`). Currently, the timeout for the leader sequence refreshes after each key pressed. If the sequence is not in the database, nothing will happen.
+
+### Extra code
+
+Extra C code needed to define custom chords can be added by quoting in in the `extra_code` element or by saving it in another header file and including it using the `extra_dependencies` element:
+
+```json
+{
+ "extra_code": "void double_dance(const struct Chord* self) { ... }\n",
+ "extra_dependencies": ["my_header.h"]
+}
+```
+
+
+
+## Further details
+
+### Implementation
+
+The source files are split into several files. `engine.part.1`, `engine.part.2` and `engine.part.3` contain C code that defines the Chord structure, implementations for all provided functions and the engine itself. `parser.py` generates keyboard and keymap dependent code. The file `chord.py` contains most of the logic required to properly translate chords from the JSON to the C code. I rarely write in python, if you have improvements, let me know, *please*.
+
+### Internal keycodes
+
+When `process_record_user()` gets one of the internal keycodes, it returns `true`, completely bypassing keyboard's and QMK's `process_record` functions. *All other* keycodes get passed down to QMK's standard processing.
+
+### Chords
+
+Each chord is defined by a constant structure, a function and two non-constant `int` variables keeping the track of the chord's state:
+
+```c
+struct Chord {
+ uint32_t keycodes_hash;
+ uint8_t pseudolayer;
+ uint8_t* state;
+ uint8_t* counter;
+ uint16_t value1;
+ uint8_t value2;
+ void (*function) (const struct Chord*);
+};
+
+uint8_t state_0 = IDLE;
+uint8_t counter_0 = 0;
+void function_0(struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ register_code(self->value1);
+ break;
+ case DEACTIVATED:
+ unregister_code(self->value1);
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ break;
+ case RESTART:
+ unregister_code(self->value1);
+ break;
+ default:
+ break;
+ }
+}
+const struct Chord chord_0 PROGMEM = {H_TOP1, QWERTY, &state_0, &counter_0, KC_Q, 0, function_0};
+```
+
+All chords have to be added to `list_of_chord` array that gets regularly scanned and processed. The function doesn't actually activate on all state changes, there are a few more like `IDLE` (nothing is currently happening to the chord) or `IN_ONE_SHOT` (the chord is one shot and is currently locked). Those are all necessary for internal use only. The ones you have to worry about are
+
+* `ACTIVATED`: Analogous to a key being pressed (this includes repeated presses for tap-dance)
+* `DEACTIVATED`: Analogous to a key being depressed (also can be repeated)
+* `FINISHED`: Happens if the chord got deactivated and then the dance timer expired.
+* `PRESS_FROM_ACTIVE`: Happens if the chord was active when the dance timer expired. Meaning you at least once activated the chord and then kept holding it down. Useful to recognize taps and holds.
+* `FINISHED_FROM_ACTIVE`: Happens *after* `PRESS_FROM_HOLD` if the chord is still active when the dance timer expires for the second time. Can be combined with the `counter` to recognize even longer presses. Useful if you want to recognize long presses, for example for autoshift functionality. In `keyboard.inc` you can set `LONG_PRESS_MULTIPLIER` to set how many times does dance timer have to expire for the autoshift to trigger.
+* `RESTART`: The dance is done. Happens immediately after `FINISHED` or on chord deactivation from `FINISHED_FROM_ACTIVE`. Anything you have to do to get the chord into `IDLE` mode happens here.
+
+The chords change states based on external and internal events. Anytime a chord's function is activated, it may change it's own state. Also, on certain events, the chording engine will trigger the functions of all chords in a specific state and *if the chords' state hasn't changed* it will then change it appropriately. The default behavior when a chord changes state is described by the following diagram:
+
+![state machine diagram](state_machine.png)
+The colors differentiate in which function the change happens, see `state_machine.dot` for a bit more detail. Black arrows happen in more than one function. Arrows without a label happen immediately.
+
+You can see that the diagram is not exhaustive. For example nothing leads into `IN_ONE_SHOT`. That is because the chord's function can change the chord's state. This is useful for some advanced chords that break the default behavir (one-shots) and for optimization (chords that just send `KC_X` do not need to ever go into dance).
+
+## Caveats
+
+Each chord stores as much as possible in `PROGMEM` and unless it needs it, doesn't allocate `counter`. However it still has to store it's `state` and sometimes the `counter` in RAM. If you keep adding more chords, at one point you will run out. If your firmware fits in the memory and your keyboard crashes, try optimizing your RAM usage.
+
+Also, the code is not perfect. I keep testing it, but can not guarantee that it is stable. Some functions take (very short but still) time and if you happen to create keypress event when the keyboard can not see it, a chord can get stuck in a funny state. That is especially fun if the pseudolayer changes and you can not immediately press it again. Just restart the keyboard or push the key a few times.
diff --git a/users/dennytom/chording_engine/chord.py b/users/dennytom/chording_engine/chord.py
new file mode 100644
index 000000000..707f36b82
--- /dev/null
+++ b/users/dennytom/chording_engine/chord.py
@@ -0,0 +1,466 @@
+from functools import reduce
+import re
+
+strings = []
+number_of_strings = -1
+
+def top_level_split(s):
+ """
+ Split `s` by top-level commas only. Commas within parentheses are ignored.
+ """
+
+ # Parse the string tracking whether the current character is within
+ # parentheses.
+ balance = 0
+ parts = []
+ part = ""
+
+ for i in range(len(s)):
+ c = s[i]
+ part += c
+ if c == '(':
+ balance += 1
+ elif c == ')':
+ balance -= 1
+ elif c == ',' and balance == 0 and not s[i+1] == ',':
+ part = part[:-1].strip()
+ parts.append(part)
+ part = ""
+
+ # Capture last part
+ if len(part):
+ parts.append(part.strip())
+
+ return parts
+
+def new_chord(on_pseudolayer, keycodes_hash, has_counter, value1, value2, function, output_buffer, index):
+ counter_link = "NULL"
+ output_buffer += "uint8_t state_" + str(index) + " = IDLE;\n"
+ if has_counter:
+ output_buffer += "uint8_t counter_" + str(index) + " = 0;\n"
+ counter_link = "&counter_" + str(index)
+ output_buffer += "const struct Chord chord_" + str(index) + " PROGMEM = {" + keycodes_hash + ", " + on_pseudolayer + ", &state_" + str(index) + ", " + counter_link + ", " + str(value1) + ", " + str(value2) + ", " + function + "};\n"
+ index += 1
+ return [output_buffer, index]
+
+def KC(on_pseudolayer, keycodes_hash, keycode, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, keycode, 0, "single_dance", output_buffer, index)
+
+def AS(on_pseudolayer, keycodes_hash, keycode, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, True, keycode, 0, "autoshift_dance", output_buffer, index)
+
+def AT(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "autoshift_toggle", output_buffer, index)
+
+def KL(on_pseudolayer, keycodes_hash, keycode, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, True, keycode, to_pseudolayer, "key_layer_dance", output_buffer, index)
+
+def KK(on_pseudolayer, keycodes_hash, keycode1, keycode2, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, True, keycode1, keycode2, "key_key_dance", output_buffer, index)
+
+def KM(on_pseudolayer, keycodes_hash, keycode, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, keycode, to_pseudolayer, "key_mod_dance", output_buffer, index)
+
+def MO(on_pseudolayer, keycodes_hash, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, to_pseudolayer, 0, "temp_pseudolayer", output_buffer, index)
+
+def MO_alt(on_pseudolayer, keycodes_hash, from_pseudolayer, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, to_pseudolayer, from_pseudolayer, "temp_pseudolayer_alt", output_buffer, index)
+
+def LOCK(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "lock", output_buffer, index)
+
+def DF(on_pseudolayer, keycodes_hash, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, to_pseudolayer, 0, "perm_pseudolayer", output_buffer, index)
+
+def TO(on_pseudolayer, keycodes_hash, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, to_pseudolayer, 0, "switch_layer", output_buffer, index)
+
+def OSK(on_pseudolayer, keycodes_hash, keycode, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, keycode, 0, "one_shot_key", output_buffer, index)
+
+def OSL(on_pseudolayer, keycodes_hash, to_pseudolayer, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, to_pseudolayer, 0, "one_shot_layer", output_buffer, index)
+
+def CMD(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "command", output_buffer, index)
+
+def DM_RECORD(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "dynamic_macro_record", output_buffer, index)
+
+def DM_NEXT(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "dynamic_macro_next", output_buffer, index)
+
+def DM_END(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "dynamic_macro_end", output_buffer, index)
+
+def DM_PLAY(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "dynamic_macro_play", output_buffer, index)
+
+def LEAD(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "leader", output_buffer, index)
+
+def CLEAR(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "clear", output_buffer, index)
+
+def RESET(on_pseudolayer, keycodes_hash, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, False, 0, 0, "reset", output_buffer, index)
+
+def STR(on_pseudolayer, keycodes_hash, string_input, output_buffer, index, number_of_strings, strings):
+ [a, b] = new_chord(on_pseudolayer, keycodes_hash, False, number_of_strings, 0, "string_in", output_buffer, index)
+ return [a, b, number_of_strings + 1, strings + [string_input]]
+
+def M(on_pseudolayer, keycodes_hash, value1, value2, fnc, output_buffer, index):
+ return new_chord(on_pseudolayer, keycodes_hash, True, value1, value2, fnc, output_buffer, index)
+
+def expand_keycode_fnc(DEFINITION):
+ if DEFINITION == "`":
+ DEFINITION = "GRAVE"
+ elif DEFINITION == "-":
+ DEFINITION = "MINUS"
+ elif DEFINITION == "=":
+ DEFINITION = "EQUAL"
+ elif DEFINITION == "[":
+ DEFINITION = "LBRACKET"
+ elif DEFINITION == "]":
+ DEFINITION = "RBRACKET"
+ elif DEFINITION == "\\":
+ DEFINITION = "BSLASH"
+ elif DEFINITION == ";":
+ DEFINITION = "SCOLON"
+ elif DEFINITION == "'":
+ DEFINITION = "QUOTE"
+ elif DEFINITION == ",":
+ DEFINITION = "COMMA"
+ elif DEFINITION == ".":
+ DEFINITION = "DOT"
+ elif DEFINITION == "/":
+ DEFINITION = "SLASH"
+ elif DEFINITION == "~":
+ DEFINITION = "TILDE"
+ elif DEFINITION == "*":
+ DEFINITION = "ASTERISK"
+ elif DEFINITION == "+":
+ DEFINITION = "PLUS"
+ elif DEFINITION == "(":
+ DEFINITION = "LEFT_PAREN"
+ elif DEFINITION == ")":
+ DEFINITION = "RIGHT_PAREN"
+ elif DEFINITION == "<":
+ DEFINITION = "LEFT_ANGLE_BRACKET"
+ elif DEFINITION == ">":
+ DEFINITION = "RIGHT_ANGLE_BRACKET"
+ elif DEFINITION == "{":
+ DEFINITION = "LEFT_CURLY_BRACE"
+ elif DEFINITION == "}":
+ DEFINITION = "RIGHT_CURLY_BRACE"
+ elif DEFINITION == "?":
+ DEFINITION = "QUESTION"
+ elif DEFINITION == "~":
+ DEFINITION = "TILDE"
+ elif DEFINITION == ":":
+ DEFINITION = "COLON"
+ elif DEFINITION == "_":
+ DEFINITION = "UNDERSCORE"
+ elif DEFINITION == '"':
+ DEFINITION = "DOUBLE_QUOTE"
+ elif DEFINITION == "@":
+ DEFINITION = "AT"
+ elif DEFINITION == "#":
+ DEFINITION = "HASH"
+ elif DEFINITION == "$":
+ DEFINITION = "DOLLAR"
+ elif DEFINITION == "!":
+ DEFINITION = "EXCLAIM"
+ elif DEFINITION == "%":
+ DEFINITION = "PERCENT"
+ elif DEFINITION == "^":
+ DEFINITION = "CIRCUMFLEX"
+ elif DEFINITION == "&":
+ DEFINITION = "AMPERSAND"
+ elif DEFINITION == "|":
+ DEFINITION = "PIPE"
+
+ if DEFINITION in [
+ "A", "a", "B", "b", "C", "c", "D", "d", "E", "e",
+ "F", "f", "G", "g", "H", "h", "I", "i", "J", "j",
+ "K", "k", "L", "l", "M", "m", "N", "n", "O", "o",
+ "P", "p", "Q", "q", "R", "r", "S", "s", "T", "t",
+ "U", "u", "V", "v", "W", "w", "X", "x", "Y", "y",
+ "Z", "z", "1", "2", "3", "4", "5", "6", "7", "8",
+ "9", "0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
+ "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
+ "F16", "F17", "F18", "F19", "F20", "F21", "F22",
+ "F23", "F24", "ENTER", "ENT", "ESCAPE", "ESC",
+ "BSPACE", "BSPC", "TAB", "SPACE", "SPC", "NONUS_HASH",
+ "NUHS", "NONUS_BSLASH", "NUBS", "COMMA", "COMM",
+ "DOT", "SLASH", "SLSH", "TILDE", "TILD", "EXCLAIM",
+ "EXLM", "AT", "HASH", "DOLLAR", "DLR", "PERCENT",
+ "PERC", "CIRCUMFLEX", "CIRC", "AMPERSAND", "AMPR",
+ "ASTERISK", "ASTR", "LEFT_PAREN", "LPRN", "RIGHT_PAREN",
+ "RPRN", "UNDERSCORE", "UNDS", "PLUS", "LEFT_CURLY_BRACE",
+ "LCBR", "RIGHT_CURLY_BRACE", "RCBR", "PIPE", "COLON",
+ "COLN", "DOUBLE_QUOTE", "DQUO", "DQT",
+ "LEFT_ANGLE_BRACKET", "LABK", "LT", "RIGHT_ANGLE_BRACKET",
+ "RABK", "GT", "QUESTION", "QUES", "SCOLON", "SCLN",
+ "QUOTE", "QUOT", "LBRACKET", "LBRC", "RBRACKET", "RBRC",
+ "BSLASH", "BSLS", "MINUS", "MINS", "EQUAL", "EQL",
+ "GRAVE", "GRV", "ZKHK", "CAPSLOCK", "CLCK", "CAPS",
+ "SCROLLOCK", "SLCK", "BRMD", "NUMLOCK", "NLCK",
+ "LOCKING_CAPS", "LCAP", "LOCKING_NUM", "LNUM",
+ "LOCKING_SCROLL", "LSCR", "LCTRL", "LCTL", "LSHIFT",
+ "LSFT", "LALT", "LGUI", "LCMD", "LWIN", "RCTRL",
+ "RCTL", "RSHIFT", "RSFT", "RALT", "RGUI", "RCMD",
+ "RWIN", "INT1", "RO", "INT2", "KANA", "INT3", "JYEN",
+ "INT4", "HENK", "INT5", "MHEN", "INT6", "INT7",
+ "INT8", "INT9", "LANG1", "HAEN", "LANG2", "HANJ",
+ "LANG3", "LANG4", "LANG5", "LANG6", "LANG7", "LANG8",
+ "LANG9", "PSCREEN", "PSCR", "PAUSE", "PAUS", "BRK",
+ "BRMU", "INSERT", "INS", "HOME", "PGUP", "DELETE",
+ "DEL", "END", "PGDOWN", "PGDN", "RIGHT", "RGHT",
+ "LEFT", "DOWN", "UP", "APPLICATION", "APP", "POWER",
+ "EXECUTE", "EXEC", "HELP", "MENU", "SELECT", "SLCT",
+ "STOP", "AGAIN", "AGIN", "UNDO", "CUT", "COPY",
+ "PASTE", "PSTE", "FIND", "MUTE", "VOLUP", "VOLDOWN",
+ "ALT_ERASE", "ERAS", "SYSREQ", "CANCEL", "CLEAR",
+ "CLR", "PRIOR", "RETURN", "SEPARATOR", "OUT", "OPER",
+ "CLEAR_AGAIN", "CRSEL", "EXSEL", "SYSTEM_POWER",
+ "PWR", "SYSTEM_SLEEP", "SLEP", "SYSTEM_WAKE", "WAKE",
+ "AUDIO_MUTE", "MUTE", "AUDIO_VOL_UP", "VOLU",
+ "AUDIO_VOL_DOWN", "VOLD", "MEDIA_NEXT_TRACK", "MNXT",
+ "MEDIA_PREV_TRACK", "MPRV", "CPRV", "MEDIA_STOP", "MSTP",
+ "MEDIA_PLAY_PAUSE", "MPLY", "MEDIA_SELECT", "MSEL",
+ "MEDIA_EJECT", "EJCT", "MAIL", "CALCULATOR", "CALC",
+ "MY_COMPUTER", "MYCM", "WWW_SEARCH", "WSCH", "WWW_HOME",
+ "WHOM", "WWW_BACK", "WBAK", "WWW_FORWARD", "WFWD",
+ "WWW_STOP", "WSTP", "WWW_REFRESH", "WREF",
+ "WWW_FAVORITES", "WFAV", "MEDIA_FAST_FORWARD", "MFFD",
+ "MEDIA_REWIND", "MRWD", "BRIGHTNESS_UP", "BRIU",
+ "BRIGHTNESS_DOWN", "BRID", "KP_SLASH", "PSLS",
+ "KP_ASTERISK", "PAST", "KP_MINUS", "PMNS", "KP_PLUS",
+ "PPLS", "KP_ENTER", "PENT", "KP_1", "P1", "KP_2", "P2",
+ "KP_3", "P3", "KP_4", "P4", "KP_5", "P5", "KP_6", "P6",
+ "KP_7", "P7", "KP_8", "P8", "KP_9", "P9", "KP_0", "P0",
+ "KP_DOT", "PDOT", "KP_EQUAL", "PEQL", "KP_COMMA", "PCMM",
+ "MS_BTN1", "BTN1", "MS_BTN2", "BTN2", "MS_BTN3", "BTN3",
+ "MS_BTN4", "BTN4", "MS_BTN5", "BTN5", "MS_BTN6", "BTN6",
+ "MS_LEFT", "MS_L", "MS_DOWN", "MS_D", "MS_UP", "MS_U",
+ "MS_RIGHT", "MS_R", "MS_WH_UP", "WH_U", "MS_WH_DOWN",
+ "WH_D", "MS_WH_LEFT", "MS_WH_L", "MS_WH_RIGHT", "MS_WH_R",
+ "KC_MS_ACCEL0", "ACL0", "KC_MS_ACCEL1", "ACL1",
+ "KC_MS_ACCEL2", "ACL2"
+ ]:
+ return "KC_" + DEFINITION
+ else:
+ return DEFINITION
+
+def MK(on_pseudolayer, keycodes_hash, definition, output_buffer, index):
+ l = len(definition.split(', '))
+ output_buffer += "void function_" + str(index) + "(const struct Chord* self) {\n"
+ output_buffer += " switch (*self->state) {\n"
+ output_buffer += " case ACTIVATED:\n"
+ for i in range(0, l):
+ val = definition.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " key_in(" + code + ");\n"
+ output_buffer += " break;\n"
+ output_buffer += " case DEACTIVATED:\n"
+ for i in range(0, l):
+ val = definition.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " key_out(" + code + ");\n"
+ output_buffer += " *self->state = IDLE;\n"
+ output_buffer += " break;\n"
+ output_buffer += " case RESTART:\n"
+ for i in range(0, l):
+ val = definition.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " key_out(" + code + ");\n"
+ output_buffer += " break;\n"
+ output_buffer += " default:\n"
+ output_buffer += " break;\n"
+ output_buffer += " };\n"
+ output_buffer += "}\n"
+ return new_chord(on_pseudolayer, keycodes_hash, True, 0, 0, "function_" + str(index), output_buffer, index)
+
+def D(on_pseudolayer, keycodes_hash, DEFINITION, output_buffer, index):
+ l = len(DEFINITION.split(','))
+ output_buffer += "void function_" + str(index) + "(const struct Chord* self) {\n"
+ output_buffer += " switch (*self->state) {\n"
+ output_buffer += " case ACTIVATED:\n"
+ output_buffer += " *self->counter = *self->counter + 1;\n"
+ output_buffer += " break;\n"
+ output_buffer += " case PRESS_FROM_ACTIVE:\n"
+ output_buffer += " switch (*self->counter) {\n"
+ for i in range(0, l):
+ val = DEFINITION.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " case " + str(i + 1) + ":\n"
+ output_buffer += " key_in( " + code + ");\n"
+ output_buffer += " break;\n"
+ output_buffer += " default:\n"
+ output_buffer += " break;\n"
+ output_buffer += " }\n"
+ output_buffer += " *self->state = FINISHED_FROM_ACTIVE;\n"
+ output_buffer += " break;\n"
+ output_buffer += " case FINISHED:\n"
+ output_buffer += " switch (*self->counter) {\n"
+ for i in range(0, l):
+ val = DEFINITION.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " case " + str(i + 1) + ":\n"
+ output_buffer += " tap_key( " + code + ");\n"
+ output_buffer += " break;\n"
+ output_buffer += " default:\n"
+ output_buffer += " break;\n"
+ output_buffer += " }\n"
+ output_buffer += " *self->counter = 0;\n"
+ output_buffer += " *self->state = IDLE;\n"
+ output_buffer += " break;\n"
+ output_buffer += " case RESTART:\n"
+ output_buffer += " switch (*self->counter) {\n"
+ for i in range(0, l):
+ val = DEFINITION.split(',')[i].strip()
+ code = expand_keycode_fnc(val)
+ output_buffer += " case " + str(i + 1) + ":\n"
+ output_buffer += " key_out( " + code + ");\n"
+ output_buffer += " break;\n"
+ output_buffer += " default:\n"
+ output_buffer += " break;\n"
+ output_buffer += " }\n"
+ output_buffer += " *self->counter = 0;\n"
+ output_buffer += " break;\n"
+ output_buffer += " default:\n"
+ output_buffer += " break;\n"
+ output_buffer += " }\n"
+ output_buffer += "}\n"
+ return new_chord(on_pseudolayer, keycodes_hash, True, 0, 0, "function_" + str(index), output_buffer, index)
+
+def O(on_pseudolayer, keycodes_hash, DEFINITION, output_buffer, index):
+ if DEFINITION[0:3] == "KC_":
+ return OSK(on_pseudolayer, keycodes_hash, DEFINITION, output_buffer, index)
+ else:
+ return OSL(on_pseudolayer, keycodes_hash, DEFINITION, output_buffer, index)
+
+def add_key(PSEUDOLAYER, KEYCODES_HASH, DEFINITION, output_buffer, index, number_of_strings, strings):
+ # if "= {" + KEYCODES_HASH + ", " + PSEUDOLAYER in output_buffer:
+ # KEYCODES_HASH = re.sub('H_', '', KEYCODES_HASH)
+ # raise Exception("You are trying to register a chord that you already registered (" + KEYCODES_HASH + ", " + PSEUDOLAYER + ")")
+
+ if DEFINITION == "":
+ return [output_buffer, index, number_of_strings, strings]
+ else:
+ split = DEFINITION.split("(")
+ type = split[0].strip()
+ if len(split) == 1:
+ if type == "LOCK":
+ [output_buffer, index] = LOCK(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "AT":
+ [output_buffer, index] = AT(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "CMD":
+ [output_buffer, index] = CMD(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "LEAD":
+ [output_buffer, index] = LEAD(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "DM_RECORD":
+ [output_buffer, index] = DM_RECORD(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "DM_NEXT":
+ [output_buffer, index] = DM_NEXT(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "DM_END":
+ [output_buffer, index] = DM_END(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "DM_PLAY":
+ [output_buffer, index] = DM_PLAY(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "CLEAR_KB":
+ [output_buffer, index] = CLEAR(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ elif type == "RESET":
+ [output_buffer, index] = RESET(PSEUDOLAYER, KEYCODES_HASH, output_buffer, index)
+ else:
+ code = expand_keycode_fnc(type)
+ [output_buffer, index] = KC(PSEUDOLAYER, KEYCODES_HASH, code, output_buffer, index)
+ else:
+ val = split[1][:-1].strip()
+ if type == "O":
+ code = expand_keycode_fnc(val)
+ [output_buffer, index] = O(PSEUDOLAYER, KEYCODES_HASH, code, output_buffer, index)
+ elif type == "D":
+ [output_buffer, index] = D(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index)
+ elif type == "MK":
+ [output_buffer, index] = MK(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index)
+ elif type == "M":
+ fnc = val.split(',')[0].strip()
+ val1 = val.split(',')[1].strip()
+ val2 = val.split(',')[2].strip()
+ [output_buffer, index] = M(PSEUDOLAYER, KEYCODES_HASH, val1, val2, fnc, output_buffer, index)
+ elif type == "KK":
+ val1 = val.split(',')[0].strip()
+ code1 = expand_keycode_fnc(val1)
+ val2 = val.split(',')[1].strip()
+ code2 = expand_keycode_fnc(val2)
+ [output_buffer, index] = KK(PSEUDOLAYER, KEYCODES_HASH, code1, code2, output_buffer, index)
+ elif type == "KL":
+ val1 = val.split(',')[0].strip()
+ code1 = expand_keycode_fnc(val1)
+ val2 = val.split(',')[1].strip()
+ [output_buffer, index] = KL(PSEUDOLAYER, KEYCODES_HASH, code1, val2, output_buffer, index)
+ elif type == "KM":
+ val1 = val.split(',')[0].strip()
+ code1 = expand_keycode_fnc(val1)
+ val2 = val.split(',')[1].strip()
+ code2 = expand_keycode_fnc(val2)
+ [output_buffer, index] = KM(PSEUDOLAYER, KEYCODES_HASH, code1, code2, output_buffer, index)
+ elif type == "AS":
+ code = expand_keycode_fnc(val)
+ [output_buffer, index] = AS(PSEUDOLAYER, KEYCODES_HASH, code, output_buffer, index)
+ elif type == "MO":
+ if not ',' in val:
+ [output_buffer, index] = MO(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index)
+ else:
+ val1 = val.split(',')[0].strip()
+ val2 = val.split(',')[1].strip()
+ [output_buffer, index] = MO_alt(PSEUDOLAYER, KEYCODES_HASH, val1, val2, output_buffer, index)
+ elif type == "DF":
+ [output_buffer, index] = DF(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index)
+ elif type == "TO":
+ [output_buffer, index] = TO(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index)
+ elif type == "STR":
+ [output_buffer, index, number_of_strings, strings] = STR(PSEUDOLAYER, KEYCODES_HASH, val, output_buffer, index, number_of_strings, strings)
+ return [output_buffer, index, number_of_strings, strings]
+
+def add_leader_combo(DEFINITION, FUNCTION):
+ return list_of_leader_combos.append([DEFINITION, FUNCTION])
+
+def add_chord_set(PSEUDOLAYER, INPUT_STRING, TYPE, data, output_buffer, index, number_of_strings, strings):
+ chord_set = {}
+ for set in data["chord_sets"]:
+ if set["name"] == TYPE:
+ chord_set = set["chords"]
+ break
+
+ separated_string = top_level_split(INPUT_STRING)
+ for word, chord in zip(separated_string, chord_set):
+ chord_hash = reduce((lambda x, y: str(x) + " + " + str(y)), ["H_" + key for key in chord])
+ [output_buffer, index, number_of_strings, strings] = add_key(PSEUDOLAYER, chord_hash, word, output_buffer, index, number_of_strings, strings)
+
+ return [output_buffer, index, number_of_strings, strings]
+
+def add_dictionary(PSEUDOLAYER, keycodes, array, output_buffer, index, number_of_strings, strings):
+ for chord in array:
+ hash = ""
+ for word, key in zip(chord[:-1], keycodes):
+ if word == "X":
+ hash = hash + " + H_" + key
+ hash = hash[3:]
+ if hash != "":
+ [output_buffer, index, number_of_strings, strings] = add_key(PSEUDOLAYER, hash, chord[-1], output_buffer, index, number_of_strings, strings)
+
+ return [output_buffer, index, number_of_strings, strings]
+
+def secret_chord(PSEUDOLAYER, ACTION, INPUT_STRING, data, output_buffer, index, number_of_strings, strings):
+ separated_string = top_level_split(INPUT_STRING)
+ hash = ""
+ for word, key in zip(separated_string, data["keys"]):
+ if word == "X":
+ hash = hash + " + H_" + key
+
+ hash = hash[3:]
+ if hash != "":
+ return add_key(PSEUDOLAYER, hash, ACTION, output_buffer, index, number_of_strings, strings) \ No newline at end of file
diff --git a/users/dennytom/chording_engine/engine.part.1 b/users/dennytom/chording_engine/engine.part.1
new file mode 100644
index 000000000..73df4cdea
--- /dev/null
+++ b/users/dennytom/chording_engine/engine.part.1
@@ -0,0 +1,163 @@
+enum chord_states {
+ IDLE,
+ READY,
+ ACTIVATED,
+ DEACTIVATED,
+ PRESS_FROM_ACTIVE,
+ FINISHED_FROM_ACTIVE,
+ IDLE_IN_DANCE,
+ READY_IN_DANCE,
+ FINISHED,
+ LOCKED,
+ READY_LOCKED,
+ RESTART,
+ IN_ONE_SHOT
+};
+
+struct Chord {
+ uint32_t keycodes_hash;
+ uint8_t pseudolayer;
+ uint8_t* state;
+ uint8_t* counter;
+ uint16_t value1;
+ uint8_t value2;
+ void (*function) (const struct Chord*);
+};
+
+uint8_t current_pseudolayer = DEFAULT_PSEUDOLAYER;
+bool lock_next = false;
+uint16_t chord_timer = 0;
+uint16_t dance_timer = 0;
+bool autoshift_mode = true;
+uint8_t keycode_index = 0;
+uint8_t command_mode = 0;
+uint8_t command_ind = 0;
+bool in_leader_mode = false;
+uint8_t leader_ind = 0;
+uint16_t leader_timer = 0;
+uint8_t dynamic_macro_mode = false;
+uint8_t dynamic_macro_ind = 0;
+bool a_key_went_through = false;
+struct Chord* last_chord = NULL;
+
+bool handle_US_ANSI_shifted_keys(int16_t keycode, bool in) {
+ bool is_US_ANSI_shifted = true;
+
+ int16_t regular_keycode = KC_NO;
+ switch (keycode) {
+ case KC_TILDE:
+ regular_keycode = KC_GRAVE;
+ break;
+ case KC_EXCLAIM:
+ regular_keycode = KC_1;
+ break;
+ case KC_AT:
+ regular_keycode = KC_2;
+ break;
+ case KC_HASH:
+ regular_keycode = KC_3;
+ break;
+ case KC_DOLLAR:
+ regular_keycode = KC_4;
+ break;
+ case KC_PERCENT:
+ regular_keycode = KC_5;
+ break;
+ case KC_CIRCUMFLEX:
+ regular_keycode = KC_6;
+ break;
+ case KC_AMPERSAND:
+ regular_keycode = KC_7;
+ break;
+ case KC_ASTERISK:
+ regular_keycode = KC_8;
+ break;
+ case KC_LEFT_PAREN:
+ regular_keycode = KC_9;
+ break;
+ case KC_RIGHT_PAREN:
+ regular_keycode = KC_0;
+ break;
+ case KC_UNDERSCORE:
+ regular_keycode = KC_MINUS;
+ break;
+ case KC_PLUS:
+ regular_keycode = KC_EQUAL;
+ break;
+ case KC_LEFT_CURLY_BRACE:
+ regular_keycode = KC_LBRACKET;
+ break;
+ case KC_RIGHT_CURLY_BRACE:
+ regular_keycode = KC_RBRACKET;
+ break;
+ case KC_PIPE:
+ regular_keycode = KC_BSLASH;
+ break;
+ case KC_COLON:
+ regular_keycode = KC_SCOLON;
+ break;
+ case KC_DOUBLE_QUOTE:
+ regular_keycode = KC_QUOTE;
+ break;
+ case KC_LEFT_ANGLE_BRACKET:
+ regular_keycode = KC_COMMA;
+ break;
+ case KC_RIGHT_ANGLE_BRACKET:
+ regular_keycode = KC_DOT;
+ break;
+ case KC_QUESTION:
+ regular_keycode = KC_SLASH;
+ break;
+ default:
+ is_US_ANSI_shifted = false;
+ }
+ if (is_US_ANSI_shifted) {
+ if (in) {
+ register_code(KC_LSFT);
+ register_code(regular_keycode);
+ } else {
+ unregister_code(regular_keycode);
+ unregister_code(KC_LSFT);
+ }
+ }
+ return is_US_ANSI_shifted;
+}
+
+void key_in(int16_t keycode) {
+ if (command_mode == 1 && command_ind < COMMAND_MAX_LENGTH) {
+ command_buffer[command_ind] = keycode;
+ command_ind++;
+ a_key_went_through = true;
+ } else if (in_leader_mode && leader_ind < LEADER_MAX_LENGTH) {
+ leader_buffer[leader_ind] = keycode;
+ leader_ind++;
+ a_key_went_through = true;
+ } else if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = keycode;
+ dynamic_macro_ind++;
+ a_key_went_through = true;
+ } else {
+ if (!handle_US_ANSI_shifted_keys(keycode, true)) {
+ register_code(keycode);
+ }
+ send_keyboard_report();
+ a_key_went_through = true;
+ }
+}
+
+void key_out(int16_t keycode) {
+ if (command_mode == 0) {
+ if (!handle_US_ANSI_shifted_keys(keycode, false)) {
+ if (command_mode == 0 && in_leader_mode == false && dynamic_macro_mode == false) {
+ unregister_code(keycode);
+ }
+ }
+ send_keyboard_report();
+ }
+}
+
+void tap_key(int16_t keycode) {
+ key_in(keycode);
+ wait_ms(TAP_TIMEOUT);
+ key_out(keycode);
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/engine.part.2 b/users/dennytom/chording_engine/engine.part.2
new file mode 100644
index 000000000..91dcbb750
--- /dev/null
+++ b/users/dennytom/chording_engine/engine.part.2
@@ -0,0 +1,323 @@
+void single_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value1);
+ break;
+ case DEACTIVATED:
+ key_out(self->value1);
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ key_out(self->value1);
+ break;
+ default:
+ break;
+ }
+}
+
+void key_layer_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value2;
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_mod_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ key_in(self->value2);
+ a_key_went_through = false;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ key_out(self->value2);
+ if (!a_key_went_through) {
+ tap_key(self->value1);
+ }
+ *self->state = IDLE; // does not have effect if the state was RESTART
+ break;
+ default:
+ break;
+ }
+}
+
+void key_key_dance(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value2);
+ break;
+ case RESTART:
+ key_out(self->value2);
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance_impl(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ *self->counter = 0;
+ break;
+ case DEACTIVATED:
+ case RESTART:
+ tap_key(self->value1);
+ *self->state = IDLE;
+ break;
+ case FINISHED_FROM_ACTIVE:
+ if (*self->counter == (LONG_PRESS_MULTIPLIER - 2)) {
+ key_in(KC_LSFT);
+ tap_key(self->value1);
+ key_out(KC_LSFT);
+ *self->state = IDLE;
+ // the skip to IDLE is usually just a lag optimization,
+ // in this case it has a logic function, on a short
+ // press (still longer than a tap) the key does not get shifted
+ } else {
+ *self->counter += 1;
+ *self->state = PRESS_FROM_ACTIVE;
+ dance_timer = timer_read();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void autoshift_dance(const struct Chord* self) {
+ if (autoshift_mode) {
+ autoshift_dance_impl(self);
+ } else {
+ single_dance(self);
+ }
+}
+
+void autoshift_toggle(const struct Chord* self){
+ if (*self->state == ACTIVATED) {
+ autoshift_mode = !autoshift_mode;
+ *self->state = IDLE;
+ }
+}
+
+void temp_pseudolayer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value1;
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->pseudolayer;
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ current_pseudolayer = self->pseudolayer;
+ break;
+ default:
+ break;
+ }
+}
+
+void temp_pseudolayer_alt(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ current_pseudolayer = self->value1;
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->value2;
+ *self->state = IDLE;
+ break;
+ case RESTART:
+ current_pseudolayer = self->value2;
+ break;
+ default:
+ break;
+ }
+}
+
+void perm_pseudolayer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ current_pseudolayer = self->value1;
+ *self->state = IDLE;
+ }
+}
+
+void switch_layer(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ layer_move(self->value1);
+ *self->state = IDLE;
+ }
+}
+
+void lock(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ lock_next = true;
+ *self->state = IDLE;
+ }
+}
+
+void one_shot_key(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ key_in(self->value1);
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ key_in(self->value1);
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ key_out(self->value1);
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void one_shot_layer(const struct Chord* self) {
+ switch (*self->state) {
+ case ACTIVATED:
+ break;
+ case DEACTIVATED:
+ current_pseudolayer = self->value1;
+ *self->state = IN_ONE_SHOT;
+ break;
+ case FINISHED:
+ case PRESS_FROM_ACTIVE:
+ current_pseudolayer = self->value1;
+ a_key_went_through = false;
+ break;
+ case RESTART:
+ if (a_key_went_through) {
+ current_pseudolayer = self->pseudolayer;
+ } else {
+ *self->state = IN_ONE_SHOT;
+ }
+ default:
+ break;
+ }
+}
+
+void command(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ command_mode++;
+ *self->state = IDLE;
+ }
+}
+
+bool identical(uint16_t* buffer1, uint16_t* buffer2) {
+ bool same = true;
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ same = same && (buffer1[i] == buffer2[i]);
+ }
+ return same;
+}
+
+void leader(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ in_leader_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_record(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ dynamic_macro_mode = true;
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_next(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode && dynamic_macro_ind < DYNAMIC_MACRO_MAX_LENGTH) {
+ dynamic_macro_buffer[dynamic_macro_ind] = 0;
+ dynamic_macro_ind++;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_end(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ if (dynamic_macro_mode) {
+ dynamic_macro_mode = false;
+ }
+ *self->state = IDLE;
+ }
+}
+
+void dynamic_macro_play(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ int ind_start = 0;
+ while (ind_start < DYNAMIC_MACRO_MAX_LENGTH) {
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ break;
+ }
+ register_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ wait_ms(TAP_TIMEOUT);
+ for (int i = ind_start; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ if (dynamic_macro_buffer[i] == 0) {
+ ind_start = i + 1;
+ break;
+ }
+ unregister_code(dynamic_macro_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ *self->state = IDLE;
+ }
+}
+
+void string_in(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ char buffer[STRING_MAX_LENGTH];
+ strcpy_P(buffer, (char*)pgm_read_word(&(strings[self->value1])));
+ send_string(buffer);
+ }
+}
+
+void clear(const struct Chord* self);
+
+void reset_keyboard_kb(void){
+#ifdef WATCHDOG_ENABLE
+ MCUSR = 0;
+ wdt_disable();
+ wdt_reset();
+#endif
+ reset_keyboard();
+}
+
+void reset(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ reset_keyboard_kb();
+ }
+}
diff --git a/users/dennytom/chording_engine/engine.part.3 b/users/dennytom/chording_engine/engine.part.3
new file mode 100644
index 000000000..cf19008ab
--- /dev/null
+++ b/users/dennytom/chording_engine/engine.part.3
@@ -0,0 +1,404 @@
+bool are_hashed_keycodes_in_sound(HASH_TYPE keycodes_hash, HASH_TYPE sound) {
+ return (keycodes_hash & sound) == keycodes_hash;
+}
+
+uint8_t keycode_to_index(uint16_t keycode) {
+ return keycode - FIRST_INTERNAL_KEYCODE;
+}
+
+void sound_keycode_array(uint16_t keycode) {
+ uint8_t index = keycode_to_index(keycode);
+ keycode_index++;
+ keycodes_buffer_array[index] = keycode_index;
+}
+
+void silence_keycode_hash_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ if (index_in_hash) {
+ uint8_t current_val = keycodes_buffer_array[i];
+ keycodes_buffer_array[i] = 0;
+ for (int j = 0; j < NUMBER_OF_KEYS; j++) {
+ if (keycodes_buffer_array[j] > current_val) {
+ keycodes_buffer_array[j]--;
+ }
+ }
+ keycode_index--;
+ }
+ }
+}
+
+bool are_hashed_keycodes_in_array(HASH_TYPE keycode_hash) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ bool index_in_hash = ((HASH_TYPE) 1 << i) & keycode_hash;
+ bool index_in_array = (bool) keycodes_buffer_array[i];
+ if (index_in_hash && !index_in_array) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void kill_one_shots(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == IN_ONE_SHOT) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ }
+}
+
+void process_finished_dances(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == ACTIVATED) {
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ } else if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = FINISHED;
+ chord->function(chord);
+ if (*chord->state == FINISHED) {
+ *chord->state = RESTART;
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ }
+ } else if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = FINISHED_FROM_ACTIVE;
+ chord->function(chord);
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ dance_timer = timer_read();
+ }
+ }
+}
+
+uint8_t keycodes_buffer_array_min(uint8_t* first_keycode_index) {
+ for (int i = 0; i < NUMBER_OF_KEYS; i++) {
+ if (keycodes_buffer_array[i] == 1) {
+ if (first_keycode_index != NULL) {
+ *first_keycode_index = (uint8_t) i;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void remove_subchords(void) {
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (!(*chord->state == READY || *chord->state == READY_IN_DANCE || *chord->state == READY_LOCKED)) {
+ continue;
+ }
+
+ struct Chord chord_storage_2;
+ struct Chord* chord_ptr_2;
+ struct Chord* chord_2;
+ for (int j = 0; j < NUMBER_OF_CHORDS; j++) {
+ if (i == j) {continue;}
+
+ chord_ptr_2 = (struct Chord*) pgm_read_word (&list_of_chords[j]);
+ memcpy_P(&chord_storage_2, chord_ptr_2, sizeof(struct Chord));
+ chord_2 = &chord_storage_2;
+
+ if (are_hashed_keycodes_in_sound(chord_2->keycodes_hash, chord->keycodes_hash)) {
+ if (*chord_2->state == READY) {
+ *chord_2->state = IDLE;
+ }
+ if (*chord_2->state == READY_IN_DANCE) {
+ *chord_2->state = IDLE_IN_DANCE;
+ }
+ if (*chord_2->state == READY_LOCKED) {
+ *chord_2->state = LOCKED;
+ }
+ }
+ }
+ }
+}
+
+void process_ready_chords(void) {
+ uint8_t first_keycode_index = 0;
+ while (keycodes_buffer_array_min(&first_keycode_index)) {
+ // find ready chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ // if the chord does not contain the first keycode
+ bool contains_first_keycode = ((uint32_t) 1 << first_keycode_index) & chord->keycodes_hash;
+ if (!contains_first_keycode) {
+ continue;
+ }
+
+ if (!are_hashed_keycodes_in_array(chord->keycodes_hash)){
+ continue;
+ }
+
+ if (*chord->state == LOCKED) {
+ *chord->state = READY_LOCKED;
+ continue;
+ }
+
+ if (!(chord->pseudolayer == current_pseudolayer || chord->pseudolayer == ALWAYS_ON)) {
+ continue;
+ }
+
+ if (*chord->state == IDLE) {
+ *chord->state = READY;
+ continue;
+ }
+
+ if (*chord->state == IDLE_IN_DANCE) {
+ *chord->state = READY_IN_DANCE;
+ }
+ }
+
+ // remove subchords
+ remove_subchords();
+
+ // execute logic
+ // this should be only one chord
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ if (*chord->state == READY_LOCKED) {
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ break;
+ }
+
+ if (*chord->state == READY || *chord->state == READY_IN_DANCE) {
+ if (last_chord && last_chord != chord) {
+ process_finished_dances();
+ }
+
+ bool lock_next_prev_state = lock_next;
+
+ *chord->state = ACTIVATED;
+ chord->function(chord);
+ dance_timer = timer_read();
+
+ if (lock_next && lock_next == lock_next_prev_state) {
+ lock_next = false;
+ *chord->state = PRESS_FROM_ACTIVE;
+ chord->function(chord);
+ if (*chord->state == PRESS_FROM_ACTIVE) {
+ *chord->state = LOCKED;
+ }
+ if (a_key_went_through) {
+ kill_one_shots();
+ }
+ }
+ break;
+ }
+ }
+
+ // silence notes
+ silence_keycode_hash_array(chord->keycodes_hash);
+ }
+}
+
+void deactivate_active_chords(uint16_t keycode) {
+ HASH_TYPE hash = (HASH_TYPE)1 << (keycode - SAFE_RANGE);
+ bool broken;
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ broken = are_hashed_keycodes_in_sound(hash, chord->keycodes_hash);
+ if (!broken) {
+ continue;
+ }
+
+ switch (*chord->state) {
+ case ACTIVATED:
+ *chord->state = DEACTIVATED;
+ chord->function(chord);
+
+ if (*chord->state == DEACTIVATED) {
+ dance_timer = timer_read();
+ *chord->state = IDLE_IN_DANCE;
+ }
+ if (*chord->state != IN_ONE_SHOT) {
+ kill_one_shots();
+ }
+ break;
+ case PRESS_FROM_ACTIVE:
+ case FINISHED_FROM_ACTIVE:
+ *chord->state = RESTART;
+ chord->function(chord);
+ if (*chord->state == RESTART) {
+ *chord->state = IDLE;
+ }
+ kill_one_shots();
+ break;
+ default:
+ break;
+ }
+ }
+
+}
+
+void process_command(void) {
+ command_mode = 0;
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ register_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ wait_ms(TAP_TIMEOUT);
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ if (command_buffer[i]) {
+ unregister_code(command_buffer[i]);
+ }
+ send_keyboard_report();
+ }
+ for (int i = 0; i < COMMAND_MAX_LENGTH; i++) {
+ command_buffer[i] = 0;
+ }
+ command_ind = 0;
+}
+
+void process_leader(void) {
+ in_leader_mode = false;
+ for (int i = 0; i < NUMBER_OF_LEADER_COMBOS; i++) {
+ uint16_t trigger[LEADER_MAX_LENGTH];
+ memcpy_P(trigger, leader_triggers[i], LEADER_MAX_LENGTH * sizeof(uint16_t));
+
+ if (identical(leader_buffer, trigger)) {
+ (*leader_functions[i])();
+ break;
+ }
+ }
+ for (int i = 0; i < LEADER_MAX_LENGTH; i++) {
+ leader_buffer[i] = 0;
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if (keycode < FIRST_INTERNAL_KEYCODE || keycode > LAST_INTERNAL_KEYCODE) {
+ return true;
+ }
+
+ if (record->event.pressed) {
+ sound_keycode_array(keycode);
+ } else {
+ process_ready_chords();
+ deactivate_active_chords(keycode);
+ }
+ chord_timer = timer_read();
+ leader_timer = timer_read();
+
+ return false;
+}
+
+void matrix_scan_user(void) {
+ bool chord_timer_expired = timer_elapsed(chord_timer) > CHORD_TIMEOUT;
+ if (chord_timer_expired && keycodes_buffer_array_min(NULL)) {
+ process_ready_chords();
+ }
+
+ bool dance_timer_expired = timer_elapsed(dance_timer) > DANCE_TIMEOUT;
+ if (dance_timer_expired) { // would love to have && in_dance but not sure how
+ process_finished_dances();
+ }
+
+ bool in_command_mode = command_mode == 2;
+ if (in_command_mode) {
+ process_command();
+ }
+
+ bool leader_timer_expired = timer_elapsed(leader_timer) > LEADER_TIMEOUT;
+ if (leader_timer_expired && in_leader_mode) {
+ process_leader();
+ }
+
+}
+
+void clear(const struct Chord* self) {
+ if (*self->state == ACTIVATED) {
+ // kill all chords
+ struct Chord chord_storage;
+ struct Chord* chord_ptr;
+ struct Chord* chord;
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ chord = &chord_storage;
+
+ *chord->state = IDLE;
+
+ if (chord->counter) {
+ *chord->counter = 0;
+ }
+ }
+
+ // clear keyboard
+ clear_keyboard();
+ send_keyboard_report();
+
+ // switch to default pseudolayer
+ current_pseudolayer = DEFAULT_PSEUDOLAYER;
+
+ // clear all keyboard states
+ lock_next = false;
+ autoshift_mode = true;
+ command_mode = 0;
+ in_leader_mode = false;
+ leader_ind = 0;
+ dynamic_macro_mode = false;
+ a_key_went_through = false;
+
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 0;
+ }
+ }
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/keymap_def.schema.json b/users/dennytom/chording_engine/keymap_def.schema.json
new file mode 100644
index 000000000..9f9a8c5cb
--- /dev/null
+++ b/users/dennytom/chording_engine/keymap_def.schema.json
@@ -0,0 +1,337 @@
+{
+ "definitions": {},
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "type": "object",
+ "title": "The Keymap definition",
+ "required": [
+ "keys",
+ "parameters",
+ "layers",
+ "chord_sets",
+ "pseudolayers",
+ "leader_sequences",
+ "extra_code",
+ "extra_dependencies"
+ ],
+ "properties": {
+ "keys": {
+ "type": "array",
+ "title": "The Internal Keycodes",
+ "description": "Name Keycodes for the Chording Engine. These can be any string except already valid QMK keycodes.",
+ "items": {
+ "type": "string",
+ "title": "Individual Keycode",
+ "examples": [
+ "L1",
+ "R1",
+ "TOP1",
+ "THUMB_3",
+ "Bottom_6"
+ ]
+ }
+ },
+ "parameters": {
+ "type": "object",
+ "title": "Keyboard Parameters",
+ "description": "Keyboard, user and layout specific parameters like timers, max length for buffers and default pseudolayer.",
+ "required": [
+ "layout_function_name",
+ "chord_timeout",
+ "dance_timeout",
+ "leader_timeout",
+ "tap_timeout",
+ "command_max_length",
+ "leader_max_length",
+ "dynamic_macro_max_length",
+ "string_max_length",
+ "long_press_multiplier",
+ "default_pseudolayer"
+ ],
+ "properties": {
+ "layout_function_name": {
+ "type": "string",
+ "examples": [
+ "LAYOUT_ginny",
+ ""
+ ]
+ },
+ "chord_timeout": {
+ "type": "integer",
+ "title": "The Chord Timeout",
+ "description": "The time in ms you have to press additional keys before the engine assumes you finished pressing keys that are part of a chord.",
+ "default": 100
+ },
+ "dance_timeout": {
+ "type": "integer",
+ "title": "The Dance Timeout",
+ "description": "The time in ms you have to repeatedly activate a chord before the engine assumes you finished a dance.",
+ "default": 200
+ },
+ "leader_timeout": {
+ "type": "integer",
+ "title": "The Leader Timeout",
+ "description": "The time in ms you have to activate additional chords before the engine assumes you finished adding chords to a leader sequence.",
+ "default": 750
+ },
+ "tap_timeout": {
+ "type": "integer",
+ "title": "The Tap Timeout",
+ "description": "The time in ms you have to finish pressing a chord before the engine assumes that you didn't just tap it but are holding it down.",
+ "default": 50
+ },
+ "command_max_length": {
+ "type": "integer",
+ "title": "Command Max Length",
+ "description": "The maximum length for chords buffered in command mode.",
+ "default": 5
+ },
+ "leader_max_length": {
+ "type": "integer",
+ "title": "Leader Max Length",
+ "description": "The maximum length of leader sequences you can define in your keymap",
+ "default": 5
+ },
+ "dynamic_macro_max_length": {
+ "type": "integer",
+ "title": "Dynamic Macro Max Length",
+ "description": "The maximum number of chords (including Dynamic Macro Next) you can record to a Dynamic Macro",
+ "default": 20
+ },
+ "string_max_length": {
+ "type": "integer",
+ "title": "String Max Length",
+ "description": "The maximum length of a string that the STR() chord can accept.",
+ "default": 16
+ },
+ "long_press_multiplier": {
+ "type": "integer",
+ "title": "Long Press Multiplier",
+ "description": "How many times does the chord timer have expire before a chord is registered as not only held but in a long press (for example for Autoshift). Has to be integer.",
+ "default": 3
+ },
+ "default_pseudolayer": {
+ "type": "string",
+ "title": "Default Pseudolayer",
+ "description": "Which pseudolayer should be active when the keyboard starts / restarts.",
+ "examples": [
+ "BASE",
+ "QWERTY"
+ ]
+ }
+ }
+ },
+ "layers": {
+ "type": "array",
+ "title": "QMK Layers",
+ "description": "The layers QMK needs to know about. Can contain chording engine's internal keycodes or QMK's keycodes. Do not define chords here, those belong in pseudolayers.",
+ "minItems": 1,
+ "uniqueItems": false,
+ "items": {
+ "type": "object",
+ "title": "Individual Layers",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "title": "Type of Individual Layers",
+ "description": "Auto layer fills all keycodes to be chording engine's internal keycodes, manual let's you place internal and QMK's keycodes however you wish.",
+ "examples": [
+ "auto",
+ "manual"
+ ]
+ },
+ "keycodes": {
+ "type": "array",
+ "title": "Individual Chord",
+ "description": "A list of of keys that need to be pressed to activate this chord",
+ "items": {
+ "type": "string",
+ "title": "Individual Keycodes",
+ "description": "A keycode that is a part of the individual chord. Has to be an internal keycode."
+ }
+ }
+ }
+ }
+ },
+ "chord_sets": {
+ "type": "array",
+ "title": "Chord Sets Definitions",
+ "description": "Describes predefined sets of chords to ease defining a number of chords in a pseudolayer.",
+ "items": {
+ "type": "object",
+ "required": [
+ "name",
+ "chords"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name of the Set",
+ "examples": [
+ "rows",
+ "asetniop"
+ ]
+ },
+ "chords": {
+ "type": "array",
+ "title": "Chords",
+ "description": "List of all chords in this set",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": {
+ "type": "array",
+ "title": "Individual Chord",
+ "description": "A list of of keys that need to be pressed to activate this chord",
+ "items": {
+ "type": "string",
+ "title": "Individual Keycodes",
+ "description": "A keycode that is a part of the individual chord. Has to be an internal keycode."
+ }
+ }
+ }
+ }
+ }
+ },
+ "pseudolayers": {
+ "type": "array",
+ "title": "Pseudolayers",
+ "description": "The pseudolayers holding the chords to be processed by the chording engine.",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": {
+ "type": "object",
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name of the Pseudolayer",
+ "default": null,
+ "examples": [
+ "ALWAYS_ON",
+ "QWERTY"
+ ]
+ },
+ "chords": {
+ "type": "array",
+ "title": "Chords",
+ "description": "List of chords belonging on the pseudolayer.",
+ "items": {
+ "type": "object",
+ "required": [
+ "type"
+ ],
+ "properties": {
+ "type": {
+ "type": "string",
+ "title": "Type of the chord array",
+ "description": "Defines how this objects describes one or more chords.",
+ "examples": [
+ "visual_array",
+ "visual",
+ "simple",
+ "chord_set"
+ ]
+ },
+ "keys": {
+ "type": "array",
+ "title": "Subset of keys",
+ "description": "Subset of internal keycodes that will be used when defining the chords. For visual_array type only.",
+ "examples": [
+ "[\"L1\", \"L2\", \"L3\", \"L4\", \"R1\", \"R2\", \"R3\", \"R4\"]"
+ ],
+ "items": {
+ "type": "string"
+ }
+ },
+ "dictionary": {
+ "type": "array",
+ "title": "Dictionary",
+ "description": "A table. Each row defines in a visual way which keys have to be pressed and what is the desired outcome. For visual_array type only.",
+ "items": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "examples": [
+ "[\"X"\, \" "\, \" "\, \"X"\, \"X"\, \" "\, \" "\, \"X"\, \"MO(BASE, NUM)\"]
+ ]
+ }
+ }
+ },
+ "keycode": {
+ "type": "string",
+ "title": "Keycode",
+ "description": "A keycode to be assigned to the chord when it is registered. For simple and visual types only."
+ },
+ "set": {
+ "type": "string",
+ "title": "Chord set",
+ "description": "Name of the chord set to be used. Has to be one already defined in the chord_sets array. For chord_set type only."
+ },
+ "keycodes": {
+ "type": "array",
+ "title": "Keycodes",
+ "description": "List of keycodes to be assigned to each chord when it is registered. For set type only.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "chord": {
+ "type": "array",
+ "title": "Chord",
+ "description": "Array of \"X\"'s and \" \"'s that shows which keys have to be pressed to activate the chord. For visual type only ",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "leader_sequences": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "examples": ["fn_L1"]
+ },
+ "function": {
+ "type": "string",
+ "description": "C code the sequence should run. Instead of here, can be defined in extra_dependencies or extra_code",
+ "examples": ["void fn_L1(void) { SEND(KC_LCTL); SEND(KC_LALT); SEND(KC_DEL); }"]
+ },
+ "sequence": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "examples": [["KC_Q", "KC_Z"]]
+ }
+ }
+ }
+ },
+ "extra_code": {
+ "type": "string",
+ "label": "Extra Code",
+ "description": "C code to be inserted into the generated keymap",
+ "examples": ["void fn_L1(void) {\n SEND(KC_LCTL);\n SEND(KC_LALT);\n SEND(KC_DEL);\n}\n"],
+ "default": ""
+ },
+ "extra_dependencies": {
+ "type": "array",
+ "label": "Extra Dependencies",
+ "description": "List of files to be #include'd in the generated keymap",
+ "examples": [
+ "[\"user_functions.c\"]"
+ ],
+ "default": ""
+ }
+ }
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/parser.py b/users/dennytom/chording_engine/parser.py
new file mode 100644
index 000000000..b62cf007e
--- /dev/null
+++ b/users/dennytom/chording_engine/parser.py
@@ -0,0 +1,231 @@
+#!/usr/bin/env python3
+
+import json
+from functools import reduce
+from chord import *
+import sys
+
+comma_separator = (lambda x, y: str(x) + ", " + str(y))
+string_sum = (lambda x, y: str(x) + " + " + str(y))
+newline_separator = (lambda x, y: str(x) + "\n" + str(y))
+
+def add_includes(data):
+ output_buffer = ""
+ if not ("do_not_include_QMK" in data["parameters"] and data["parameters"]["do_not_include_QMK"] == True):
+ output_buffer += "#include QMK_KEYBOARD_H\n"
+ if len(data["extra_dependencies"]) > 0:
+ for dependecy in data["extra_dependencies"]:
+ output_buffer += '#include "' + dependecy + '"\n'
+
+ return output_buffer + "\n"
+
+def add_parameters(data):
+ output_buffer = ""
+
+ number_of_keys = len(data["keys"])
+ if number_of_keys <= 8:
+ hash_type = "uint8_t"
+ elif number_of_keys <= 16:
+ hash_type = "uint16_t"
+ elif number_of_keys <= 32:
+ hash_type = "uint32_t"
+ elif number_of_keys <= 64:
+ hash_type = "uint64_t"
+ else:
+ raise Exception("The engine currently supports only up to 64 keys.")
+
+ output_buffer += "#define CHORD_TIMEOUT " + str(data["parameters"]["chord_timeout"]) + "\n"
+ output_buffer += "#define DANCE_TIMEOUT " + str(data["parameters"]["dance_timeout"]) + "\n"
+ output_buffer += "#define LEADER_TIMEOUT " + str(data["parameters"]["leader_timeout"]) + "\n"
+ output_buffer += "#define TAP_TIMEOUT " + str(data["parameters"]["tap_timeout"]) + "\n"
+ output_buffer += "#define LONG_PRESS_MULTIPLIER " + str(data["parameters"]["long_press_multiplier"]) + "\n"
+ output_buffer += "#define DYNAMIC_MACRO_MAX_LENGTH " + str(data["parameters"]["dynamic_macro_max_length"]) + "\n"
+ output_buffer += "#define COMMAND_MAX_LENGTH " + str(data["parameters"]["command_max_length"]) + "\n"
+ output_buffer += "#define STRING_MAX_LENGTH " + str(data["parameters"]["string_max_length"]) + "\n"
+ output_buffer += "#define LEADER_MAX_LENGTH " + str(data["parameters"]["leader_max_length"]) + "\n"
+ output_buffer += "#define HASH_TYPE " + hash_type + "\n"
+ output_buffer += "#define NUMBER_OF_KEYS " + str(len(data["keys"])) + "\n"
+ output_buffer += "#define DEFAULT_PSEUDOLAYER " + data["parameters"]["default_pseudolayer"] + "\n"
+
+ return output_buffer + "\n"
+
+def add_keycodes(data):
+ output_buffer = ""
+
+ if not len(data["keys"]) == len(set(data["keys"])):
+ raise Exception("The keys must have unique names")
+
+ for key, counter in zip(data["keys"], range(0, len(data["keys"]))):
+ output_buffer += "#define H_" + key + " ((HASH_TYPE) 1 << " + str(counter) + ")\n"
+ output_buffer += "\n"
+
+ output_buffer += "enum internal_keycodes {\n"
+ output_buffer += " " + data["keys"][0] + " = SAFE_RANGE,\n"
+ output_buffer += " " + reduce(comma_separator, [key for key in data["keys"][1:]]) + ",\n"
+ output_buffer += " FIRST_INTERNAL_KEYCODE = " + data["keys"][0] + ",\n"
+ output_buffer += " LAST_INTERNAL_KEYCODE = " + data["keys"][-1] + "\n"
+ output_buffer += "};\n"
+
+ return output_buffer + "\n"
+
+def add_pseudolayers(data):
+ output_buffer = ""
+
+ if len(data["pseudolayers"]) == 0:
+ raise Exception("You didn't define any pseudolayers")
+
+ if not len([pseudolayer["name"] for pseudolayer in data["pseudolayers"]]) == len(set([pseudolayer["name"] for pseudolayer in data["pseudolayers"]])):
+ raise Exception("The pseudolayers must have unique names")
+
+ pseudolayers = data["pseudolayers"]
+ if not "ALWAYS_ON" in [layer["name"] for layer in pseudolayers]:
+ pseudolayers += [{"name": "ALWAYS_ON", "chords": []}] # the engine expects ALWAYS_ON to exist
+
+ output_buffer += "enum pseudolayers {\n"
+ output_buffer += " " + reduce(comma_separator, [layer["name"] for layer in pseudolayers]) + "\n"
+ output_buffer += "};\n"
+
+ return output_buffer + "\n"
+
+def add_layers(data):
+ output_buffer = ""
+
+ output_buffer += "const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {\n"
+ for layer, counter in zip(data["layers"], range(0,len(data["layers"]))):
+ if layer["type"] == "auto":
+ output_buffer += " [" + str(counter) + "] = " + data["parameters"]["layout_function_name"] + "(" + reduce(comma_separator, [key for key in data["keys"]]) + "),\n"
+ else:
+ output_buffer += " [" + str(counter) + "] = " + data["parameters"]["layout_function_name"] + "(" + reduce(comma_separator, [key for key in layer["keycodes"]]) + "),\n"
+ output_buffer += "};\n"
+ output_buffer += "size_t keymapsCount = " + str(len(data["layers"])) + ";\n"
+
+ return output_buffer + "\n"
+
+def prep_buffers(data):
+ output_buffer = ""
+
+ output_buffer += "uint8_t keycodes_buffer_array[] = {\n"
+ output_buffer += " " + reduce(comma_separator, ["0"] * len(data["keys"])) + "\n"
+ output_buffer += "};\n"
+ output_buffer += "\n"
+
+ output_buffer += "uint8_t command_buffer[] = {\n"
+ output_buffer += " " + reduce(comma_separator, ["0"] * data["parameters"]["command_max_length"]) + "\n"
+ output_buffer += "};\n"
+ output_buffer += "\n"
+
+ output_buffer += "uint16_t leader_buffer[] = {\n"
+ output_buffer += " " + reduce(comma_separator, ["0"] * data["parameters"]["leader_max_length"]) + "\n"
+ output_buffer += "};\n"
+ output_buffer += "\n"
+
+ output_buffer += "uint8_t dynamic_macro_buffer[] = {\n"
+ output_buffer += " " + reduce(comma_separator, ["0"] * data["parameters"]["dynamic_macro_max_length"]) + "\n"
+ output_buffer += "};"
+
+ return output_buffer + "\n"
+
+def parse_keyboard_specifics(data):
+ keyboard_part_0 = add_includes(data)
+ keyboard_part_0 += add_keycodes(data)
+ keyboard_part_0 += add_pseudolayers(data)
+ keyboard_part_0 += add_parameters(data)
+ keyboard_part_0 += add_layers(data)
+ keyboard_part_0 += prep_buffers(data)
+
+ return keyboard_part_0 + '\n'
+
+def parse_chords(data):
+ keyboard_part_2 = ""
+ strings = []
+ number_of_strings = 0
+ number_of_chords = 0
+
+ for pseudolayer in data["pseudolayers"]:
+ name = pseudolayer["name"]
+ for chord in pseudolayer["chords"]:
+ if chord["type"] == "chord_set":
+ keycodes = reduce(comma_separator, [word for word in chord["keycodes"]])
+ [keyboard_part_2, number_of_chords, number_of_strings, strings] = add_chord_set(name, keycodes, chord["set"], data, keyboard_part_2, number_of_chords, number_of_strings, strings)
+ if chord["type"] == "visual_array":
+ [keyboard_part_2, number_of_chords, number_of_strings, strings] = add_dictionary(name, chord["keys"], chord["dictionary"], keyboard_part_2, number_of_chords, number_of_strings, strings)
+ if chord["type"] == "visual":
+ keycodes = reduce(comma_separator, [word for word in chord["chord"]])
+ [keyboard_part_2, number_of_chords, number_of_strings, strings] = secret_chord(name, chord["keycode"], keycodes, data, keyboard_part_2, number_of_chords, number_of_strings, strings)
+ elif chord["type"] == "simple":
+ keycodes = reduce(string_sum, ["H_" + word for word in chord["chord"]])
+ [keyboard_part_2, number_of_chords, number_of_strings, strings] = add_key(name, keycodes, chord["keycode"], keyboard_part_2, number_of_chords, number_of_strings, strings)
+ keyboard_part_2 += "\n"
+
+ keyboard_part_2 += "const struct Chord* const list_of_chords[] PROGMEM = {\n"
+ keyboard_part_2 += " " + reduce(comma_separator, ["&chord_" + str(i) for i in range(0, number_of_chords)]) + "\n"
+ keyboard_part_2 += "};\n"
+ keyboard_part_2 += "\n"
+
+ if len(data["leader_sequences"]) > 0:
+ keyboard_part_2 += reduce(newline_separator, [sequence["function"] for sequence in data["leader_sequences"]]) + "\n\n"
+ keyboard_part_2 += "const uint16_t leader_triggers[][LEADER_MAX_LENGTH] PROGMEM = {\n"
+ for sequence in data["leader_sequences"]:
+ keyboard_part_2 += " {" + reduce(comma_separator, sequence["sequence"] + ["0"] * (data["parameters"]["leader_max_length"] - len(sequence["sequence"]))) + "},\n"
+ keyboard_part_2 += "};\n\n"
+ keyboard_part_2 += "void (*leader_functions[]) (void) = {\n"
+ keyboard_part_2 += " " + reduce(comma_separator, ["&" + sequence["name"] for sequence in data["leader_sequences"]]) + "\n"
+ keyboard_part_2 += "};\n"
+ else:
+ keyboard_part_2 += "const uint16_t** const leader_triggers PROGMEM = NULL;\n"
+ keyboard_part_2 += "void (*leader_functions[]) (void) = {};\n"
+ keyboard_part_2 += "\n"
+
+ keyboard_part_2 += "#define NUMBER_OF_CHORDS " + str(number_of_chords) + "\n"
+ keyboard_part_2 += "#define NUMBER_OF_LEADER_COMBOS " + str(len(data["leader_sequences"]))
+
+ return keyboard_part_2 + "\n\n"
+
+def parse_strings_for_chords(data):
+ keyboard_part_1 = ""
+
+ for string, i in zip(strings, range(0, len(strings))):
+ keyboard_part_1 += "const char string_" + str(i) + " [] PROGMEM = \"" + string + "\";\n"
+
+ keyboard_part_1 += "\n"
+ keyboard_part_1 += "const char * const strings[] PROGMEM = {\n"
+ if len(strings) > 0:
+ keyboard_part_1 += " " + reduce(comma_separator, ["string_" + str(i) for i in range(0, len(strings))])
+ keyboard_part_1 += "\n};\n"
+
+ return keyboard_part_1
+
+def main():
+ if len(sys.argv) != 3:
+ raise Exception("Wrong number of arguments.\n\nUsage: python parser.py keymap.json keymap.c")
+
+ input_filepath = sys.argv[1]
+ output_filepath = sys.argv[2]
+
+ with open(input_filepath, "r") as read_file:
+ data = json.load(read_file)
+
+ keyboard_part_0 = parse_keyboard_specifics(data)
+ keyboard_part_1 = parse_strings_for_chords(data)
+ keyboard_part_2 = parse_chords(data)
+
+ engine_part_1 = open("engine.part.1", "r").read()
+ engine_part_2 = open("engine.part.2", "r").read() + "\n"
+ engine_part_3 = open("engine.part.3", "r").read()
+
+ output_buffer = keyboard_part_0
+ output_buffer += engine_part_1
+
+ if len(data["extra_code"]) > 0:
+ output_buffer += data["extra_code"] + "\n"
+
+ output_buffer += keyboard_part_1
+ output_buffer += engine_part_2
+ output_buffer += keyboard_part_2
+ output_buffer += engine_part_3
+
+ with open(output_filepath, "w") as write_file:
+ write_file.write(output_buffer)
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/users/dennytom/chording_engine/state_machine.dot b/users/dennytom/chording_engine/state_machine.dot
new file mode 100644
index 000000000..431e6f69b
--- /dev/null
+++ b/users/dennytom/chording_engine/state_machine.dot
@@ -0,0 +1,49 @@
+digraph {
+ IDLE
+ READY
+ ACTIVATED
+ DEACTIVATED
+ PRESS_FROM_ACTIVE
+ FINISHED_FROM_ACTIVE
+ IDLE_IN_DANCE
+ READY_IN_DANCE
+ FINISHED
+ LOCKED
+ READY_LOCKED
+ RESTART
+ IN_ONE_SHOT
+
+ // common
+ FINISHED -> RESTART;
+ RESTART -> IDLE;
+ DEACTIVATED -> IDLE_IN_DANCE;
+
+ // kill_one_shots()
+ IN_ONE_SHOT -> RESTART [label="non-one-shot key went through", color="blue"];
+
+ // process_finished_dances()
+ ACTIVATED -> PRESS_FROM_ACTIVE [label="dance timer", color="green"];
+ IDLE_IN_DANCE -> FINISHED [label="dance timer", color="green"];
+ PRESS_FROM_ACTIVE -> FINISHED_FROM_ACTIVE [label="dance timer", color="green"];
+
+ // remove_subchords()
+ READY -> IDLE [label="superchord active", color="red"];
+ READY_IN_DANCE -> IDLE_IN_DANCE [label="superchord active", color="red"];
+ READY_LOCKED -> LOCKED [label="superchord active", color="red"];
+
+ // process_ready_chords()
+ LOCKED -> READY_LOCKED [label="all keys pressed", color="orange"];
+ IDLE -> READY [label="all keys pressed", color="orange"];
+ IDLE_IN_DANCE -> READY_IN_DANCE [label="all keys pressed", color="orange"];
+
+ READY_LOCKED -> RESTART [label="chord timer", color="orange"];
+ READY -> ACTIVATED [label="chord timer", color="orange"];
+ READY_IN_DANCE -> ACTIVATED [label="chord timer", color="orange"];
+ ACTIVATED -> PRESS_FROM_ACTIVE [label="lock next", color="orange"];
+ PRESS_FROM_ACTIVE -> LOCKED [label="lock next", color="orange"];
+
+ // deactivate_active_chords()
+ ACTIVATED -> DEACTIVATED [label="a key lifted", color="purple"];
+ PRESS_FROM_ACTIVE -> RESTART [label="a key lifted", color="orange"];
+ FINISHED_FROM_ACTIVE -> DEACTIVATED [label="a key lifted", color="orange"];
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/state_machine.svg b/users/dennytom/chording_engine/state_machine.svg
new file mode 100644
index 000000000..773168988
--- /dev/null
+++ b/users/dennytom/chording_engine/state_machine.svg
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: %0 Pages: 1 -->
+<svg width="829pt" height="754pt"
+ viewBox="0.00 0.00 829.35 754.40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 750.4)">
+<title>%0</title>
+<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-750.4 825.3486,-750.4 825.3486,4 -4,4"/>
+<!-- IDLE -->
+<g id="node1" class="node">
+<title>IDLE</title>
+<ellipse fill="none" stroke="#000000" cx="492" cy="-728.4" rx="33.043" ry="18"/>
+<text text-anchor="middle" x="492" y="-724.2" font-family="Times,serif" font-size="14.00" fill="#000000">IDLE</text>
+</g>
+<!-- READY -->
+<g id="node2" class="node">
+<title>READY</title>
+<ellipse fill="none" stroke="#000000" cx="404" cy="-639.6" rx="44.0814" ry="18"/>
+<text text-anchor="middle" x="404" y="-635.4" font-family="Times,serif" font-size="14.00" fill="#000000">READY</text>
+</g>
+<!-- IDLE&#45;&gt;READY -->
+<g id="edge12" class="edge">
+<title>IDLE&#45;&gt;READY</title>
+<path fill="none" stroke="#ffa500" d="M487.6897,-710.0931C484.347,-699.0742 478.772,-685.3407 470,-675.6 463.1872,-668.0349 454.3989,-661.7377 445.4714,-656.6382"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="447.0426,-653.5099 436.5654,-651.9352 443.7738,-659.6998 447.0426,-653.5099"/>
+<text text-anchor="middle" x="524.317" y="-679.8" font-family="Times,serif" font-size="14.00" fill="#000000">all keys pressed</text>
+</g>
+<!-- READY&#45;&gt;IDLE -->
+<g id="edge8" class="edge">
+<title>READY&#45;&gt;IDLE</title>
+<path fill="none" stroke="#ff0000" d="M383.1899,-655.7528C371.9777,-666.4401 362.0803,-680.6044 370.88,-692.4 380.5143,-705.3144 418.9714,-715.2612 450.0017,-721.3939"/>
+<polygon fill="#ff0000" stroke="#ff0000" points="449.7109,-724.9011 460.188,-723.3263 451.0156,-718.0238 449.7109,-724.9011"/>
+<text text-anchor="middle" x="420.56" y="-679.8" font-family="Times,serif" font-size="14.00" fill="#000000">superchord active</text>
+</g>
+<!-- ACTIVATED -->
+<g id="node3" class="node">
+<title>ACTIVATED</title>
+<ellipse fill="none" stroke="#000000" cx="404" cy="-550.8" rx="66.0512" ry="18"/>
+<text text-anchor="middle" x="404" y="-546.6" font-family="Times,serif" font-size="14.00" fill="#000000">ACTIVATED</text>
+</g>
+<!-- READY&#45;&gt;ACTIVATED -->
+<g id="edge15" class="edge">
+<title>READY&#45;&gt;ACTIVATED</title>
+<path fill="none" stroke="#ffa500" d="M404,-621.2006C404,-609.0949 404,-593.0076 404,-579.2674"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="407.5001,-578.872 404,-568.872 400.5001,-578.8721 407.5001,-578.872"/>
+<text text-anchor="middle" x="436.4611" y="-591" font-family="Times,serif" font-size="14.00" fill="#000000">chord timer</text>
+</g>
+<!-- DEACTIVATED -->
+<g id="node4" class="node">
+<title>DEACTIVATED</title>
+<ellipse fill="none" stroke="#000000" cx="301" cy="-284.4" rx="79.2922" ry="18"/>
+<text text-anchor="middle" x="301" y="-280.2" font-family="Times,serif" font-size="14.00" fill="#000000">DEACTIVATED</text>
+</g>
+<!-- ACTIVATED&#45;&gt;DEACTIVATED -->
+<g id="edge19" class="edge">
+<title>ACTIVATED&#45;&gt;DEACTIVATED</title>
+<path fill="none" stroke="#a020f0" d="M414.457,-532.6765C417.1337,-527.1214 419.6389,-520.8699 421,-514.8 426.1765,-491.7151 456.5634,-425.2497 416,-355.2 402.3607,-331.646 377.4429,-314.8951 354.2805,-303.6207"/>
+<polygon fill="#a020f0" stroke="#a020f0" points="355.7259,-300.433 345.1798,-299.4173 352.7907,-306.7879 355.7259,-300.433"/>
+<text text-anchor="middle" x="468.4881" y="-413.4" font-family="Times,serif" font-size="14.00" fill="#000000">a key lifted</text>
+</g>
+<!-- PRESS_FROM_ACTIVE -->
+<g id="node5" class="node">
+<title>PRESS_FROM_ACTIVE</title>
+<ellipse fill="none" stroke="#000000" cx="279" cy="-462" rx="111.797" ry="18"/>
+<text text-anchor="middle" x="279" y="-457.8" font-family="Times,serif" font-size="14.00" fill="#000000">PRESS_FROM_ACTIVE</text>
+</g>
+<!-- ACTIVATED&#45;&gt;PRESS_FROM_ACTIVE -->
+<g id="edge5" class="edge">
+<title>ACTIVATED&#45;&gt;PRESS_FROM_ACTIVE</title>
+<path fill="none" stroke="#00ff00" d="M381.0189,-533.8085C363.6663,-521.0049 341.3076,-504.5706 332,-498 326.1999,-493.9054 319.9973,-489.6147 313.9535,-485.4802"/>
+<polygon fill="#00ff00" stroke="#00ff00" points="315.5139,-482.3085 305.2776,-479.5755 311.5753,-488.0954 315.5139,-482.3085"/>
+<text text-anchor="middle" x="387.8454" y="-502.2" font-family="Times,serif" font-size="14.00" fill="#000000">dance timer</text>
+</g>
+<!-- ACTIVATED&#45;&gt;PRESS_FROM_ACTIVE -->
+<g id="edge17" class="edge">
+<title>ACTIVATED&#45;&gt;PRESS_FROM_ACTIVE</title>
+<path fill="none" stroke="#ffa500" d="M346.8191,-541.6158C317.1162,-535.5544 285.1886,-526.5544 276.2896,-514.8 271.0903,-507.9325 270.0671,-499.0047 270.857,-490.45"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="274.3462,-490.8071 272.5608,-480.3638 267.444,-489.6411 274.3462,-490.8071"/>
+<text text-anchor="middle" x="302.8552" y="-502.2" font-family="Times,serif" font-size="14.00" fill="#000000">lock next</text>
+</g>
+<!-- IDLE_IN_DANCE -->
+<g id="node7" class="node">
+<title>IDLE_IN_DANCE</title>
+<ellipse fill="none" stroke="#000000" cx="293" cy="-195.6" rx="86.2367" ry="18"/>
+<text text-anchor="middle" x="293" y="-191.4" font-family="Times,serif" font-size="14.00" fill="#000000">IDLE_IN_DANCE</text>
+</g>
+<!-- DEACTIVATED&#45;&gt;IDLE_IN_DANCE -->
+<g id="edge3" class="edge">
+<title>DEACTIVATED&#45;&gt;IDLE_IN_DANCE</title>
+<path fill="none" stroke="#000000" d="M299.3424,-266.0006C298.241,-253.775 296.7738,-237.4887 295.5279,-223.6599"/>
+<polygon fill="#000000" stroke="#000000" points="299.0114,-223.3176 294.6281,-213.672 292.0396,-223.9458 299.0114,-223.3176"/>
+</g>
+<!-- FINISHED_FROM_ACTIVE -->
+<g id="node6" class="node">
+<title>FINISHED_FROM_ACTIVE</title>
+<ellipse fill="none" stroke="#000000" cx="280" cy="-373.2" rx="127.3672" ry="18"/>
+<text text-anchor="middle" x="280" y="-369" font-family="Times,serif" font-size="14.00" fill="#000000">FINISHED_FROM_ACTIVE</text>
+</g>
+<!-- PRESS_FROM_ACTIVE&#45;&gt;FINISHED_FROM_ACTIVE -->
+<g id="edge7" class="edge">
+<title>PRESS_FROM_ACTIVE&#45;&gt;FINISHED_FROM_ACTIVE</title>
+<path fill="none" stroke="#00ff00" d="M279.2072,-443.6006C279.3435,-431.4949 279.5247,-415.4076 279.6794,-401.6674"/>
+<polygon fill="#00ff00" stroke="#00ff00" points="283.1836,-401.3108 279.7965,-391.272 276.184,-401.2319 283.1836,-401.3108"/>
+<text text-anchor="middle" x="312.8454" y="-413.4" font-family="Times,serif" font-size="14.00" fill="#000000">dance timer</text>
+</g>
+<!-- LOCKED -->
+<g id="node10" class="node">
+<title>LOCKED</title>
+<ellipse fill="none" stroke="#000000" cx="84" cy="-373.2" rx="50.38" ry="18"/>
+<text text-anchor="middle" x="84" y="-369" font-family="Times,serif" font-size="14.00" fill="#000000">LOCKED</text>
+</g>
+<!-- PRESS_FROM_ACTIVE&#45;&gt;LOCKED -->
+<g id="edge18" class="edge">
+<title>PRESS_FROM_ACTIVE&#45;&gt;LOCKED</title>
+<path fill="none" stroke="#ffa500" d="M241.402,-444.8785C207.8161,-429.584 158.7472,-407.2387 124.3482,-391.574"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="125.6113,-388.3034 115.06,-387.3442 122.7102,-394.6739 125.6113,-388.3034"/>
+<text text-anchor="middle" x="224.8552" y="-413.4" font-family="Times,serif" font-size="14.00" fill="#000000">lock next</text>
+</g>
+<!-- RESTART -->
+<g id="node12" class="node">
+<title>RESTART</title>
+<ellipse fill="none" stroke="#000000" cx="201" cy="-18" rx="53.9098" ry="18"/>
+<text text-anchor="middle" x="201" y="-13.8" font-family="Times,serif" font-size="14.00" fill="#000000">RESTART</text>
+</g>
+<!-- PRESS_FROM_ACTIVE&#45;&gt;RESTART -->
+<g id="edge20" class="edge">
+<title>PRESS_FROM_ACTIVE&#45;&gt;RESTART</title>
+<path fill="none" stroke="#ffa500" d="M190.3393,-450.9993C108.6441,-438.3099 0,-413.8018 0,-373.2 0,-373.2 0,-373.2 0,-106.8 0,-74.7037 86.8374,-46.4364 146.3579,-30.8311"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="147.578,-34.1313 156.3916,-28.2515 145.835,-27.3517 147.578,-34.1313"/>
+<text text-anchor="middle" x="31.4881" y="-235.8" font-family="Times,serif" font-size="14.00" fill="#000000">a key lifted</text>
+</g>
+<!-- FINISHED_FROM_ACTIVE&#45;&gt;DEACTIVATED -->
+<g id="edge21" class="edge">
+<title>FINISHED_FROM_ACTIVE&#45;&gt;DEACTIVATED</title>
+<path fill="none" stroke="#ffa500" d="M284.3512,-354.8006C287.2424,-342.575 291.0939,-326.2887 294.3642,-312.4599"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="297.8308,-313.0091 296.7262,-302.472 291.0187,-311.3981 297.8308,-313.0091"/>
+<text text-anchor="middle" x="324.4881" y="-324.6" font-family="Times,serif" font-size="14.00" fill="#000000">a key lifted</text>
+</g>
+<!-- READY_IN_DANCE -->
+<g id="node8" class="node">
+<title>READY_IN_DANCE</title>
+<ellipse fill="none" stroke="#000000" cx="402" cy="-106.8" rx="97.2741" ry="18"/>
+<text text-anchor="middle" x="402" y="-102.6" font-family="Times,serif" font-size="14.00" fill="#000000">READY_IN_DANCE</text>
+</g>
+<!-- IDLE_IN_DANCE&#45;&gt;READY_IN_DANCE -->
+<g id="edge13" class="edge">
+<title>IDLE_IN_DANCE&#45;&gt;READY_IN_DANCE</title>
+<path fill="none" stroke="#ffa500" d="M285.2465,-177.3414C281.8879,-166.3406 280.1649,-152.6093 287.366,-142.8 292.9374,-135.2107 308.8319,-128.4976 327.077,-122.9864"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="328.1338,-126.3246 336.79,-120.2157 326.2135,-119.5932 328.1338,-126.3246"/>
+<text text-anchor="middle" x="332.317" y="-147" font-family="Times,serif" font-size="14.00" fill="#000000">all keys pressed</text>
+</g>
+<!-- FINISHED -->
+<g id="node9" class="node">
+<title>FINISHED</title>
+<ellipse fill="none" stroke="#000000" cx="201" cy="-106.8" rx="55.0323" ry="18"/>
+<text text-anchor="middle" x="201" y="-102.6" font-family="Times,serif" font-size="14.00" fill="#000000">FINISHED</text>
+</g>
+<!-- IDLE_IN_DANCE&#45;&gt;FINISHED -->
+<g id="edge6" class="edge">
+<title>IDLE_IN_DANCE&#45;&gt;FINISHED</title>
+<path fill="none" stroke="#00ff00" d="M231.9976,-182.6889C220.3684,-177.4272 209.5756,-170.022 202.3092,-159.6 197.3878,-152.5413 195.8986,-143.5625 195.9866,-135.0199"/>
+<polygon fill="#00ff00" stroke="#00ff00" points="199.4821,-135.2114 196.7515,-124.9745 192.5023,-134.6799 199.4821,-135.2114"/>
+<text text-anchor="middle" x="235.8454" y="-147" font-family="Times,serif" font-size="14.00" fill="#000000">dance timer</text>
+</g>
+<!-- READY_IN_DANCE&#45;&gt;ACTIVATED -->
+<g id="edge16" class="edge">
+<title>READY_IN_DANCE&#45;&gt;ACTIVATED</title>
+<path fill="none" stroke="#ffa500" d="M460.9306,-121.2262C473.3432,-126.4214 485.5301,-133.4169 495,-142.8 512.9398,-160.5753 516,-170.3454 516,-195.6 516,-462 516,-462 516,-462 516,-495.4749 484.8997,-518.3284 455.476,-532.4591"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="453.6869,-529.4272 446.0233,-536.7429 456.5764,-535.803 453.6869,-529.4272"/>
+<text text-anchor="middle" x="548.4611" y="-324.6" font-family="Times,serif" font-size="14.00" fill="#000000">chord timer</text>
+</g>
+<!-- READY_IN_DANCE&#45;&gt;IDLE_IN_DANCE -->
+<g id="edge9" class="edge">
+<title>READY_IN_DANCE&#45;&gt;IDLE_IN_DANCE</title>
+<path fill="none" stroke="#ff0000" d="M398.1917,-124.942C395.0071,-136.1761 389.421,-150.2021 380,-159.6 372.9696,-166.6132 364.3766,-172.3251 355.3586,-176.9585"/>
+<polygon fill="#ff0000" stroke="#ff0000" points="353.8046,-173.8215 346.241,-181.2406 356.7803,-180.1575 353.8046,-173.8215"/>
+<text text-anchor="middle" x="441.56" y="-147" font-family="Times,serif" font-size="14.00" fill="#000000">superchord active</text>
+</g>
+<!-- FINISHED&#45;&gt;RESTART -->
+<g id="edge1" class="edge">
+<title>FINISHED&#45;&gt;RESTART</title>
+<path fill="none" stroke="#000000" d="M201,-88.4006C201,-76.2949 201,-60.2076 201,-46.4674"/>
+<polygon fill="#000000" stroke="#000000" points="204.5001,-46.072 201,-36.072 197.5001,-46.0721 204.5001,-46.072"/>
+</g>
+<!-- READY_LOCKED -->
+<g id="node11" class="node">
+<title>READY_LOCKED</title>
+<ellipse fill="none" stroke="#000000" cx="116" cy="-284.4" rx="88.0442" ry="18"/>
+<text text-anchor="middle" x="116" y="-280.2" font-family="Times,serif" font-size="14.00" fill="#000000">READY_LOCKED</text>
+</g>
+<!-- LOCKED&#45;&gt;READY_LOCKED -->
+<g id="edge11" class="edge">
+<title>LOCKED&#45;&gt;READY_LOCKED</title>
+<path fill="none" stroke="#ffa500" d="M62.8266,-356.7262C52.2277,-346.3972 43.0571,-332.745 50.366,-320.4 53.6683,-314.8223 58.175,-310.0516 63.2916,-305.985"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="65.4987,-308.7148 71.7485,-300.1596 61.5278,-302.9501 65.4987,-308.7148"/>
+<text text-anchor="middle" x="95.317" y="-324.6" font-family="Times,serif" font-size="14.00" fill="#000000">all keys pressed</text>
+</g>
+<!-- READY_LOCKED&#45;&gt;LOCKED -->
+<g id="edge10" class="edge">
+<title>READY_LOCKED&#45;&gt;LOCKED</title>
+<path fill="none" stroke="#ff0000" d="M134.3377,-302.181C142.7003,-312.508 149.4503,-325.708 143,-337.2 139.1182,-344.1159 133.3081,-349.8603 126.8241,-354.5772"/>
+<polygon fill="#ff0000" stroke="#ff0000" points="124.8745,-351.6695 118.3451,-360.0132 128.6526,-357.5624 124.8745,-351.6695"/>
+<text text-anchor="middle" x="195.56" y="-324.6" font-family="Times,serif" font-size="14.00" fill="#000000">superchord active</text>
+</g>
+<!-- READY_LOCKED&#45;&gt;RESTART -->
+<g id="edge14" class="edge">
+<title>READY_LOCKED&#45;&gt;RESTART</title>
+<path fill="none" stroke="#ffa500" d="M114.0574,-266.3175C111.0132,-230.457 108.1435,-148.6335 137,-88.8 145.6041,-70.9596 160.1275,-54.343 173.1661,-41.6972"/>
+<polygon fill="#ffa500" stroke="#ffa500" points="175.702,-44.1178 180.6155,-34.7312 170.9209,-39.0049 175.702,-44.1178"/>
+<text text-anchor="middle" x="152.4611" y="-147" font-family="Times,serif" font-size="14.00" fill="#000000">chord timer</text>
+</g>
+<!-- RESTART&#45;&gt;IDLE -->
+<g id="edge2" class="edge">
+<title>RESTART&#45;&gt;IDLE</title>
+<path fill="none" stroke="#000000" d="M251.8307,-24.1482C358.5139,-37.7418 596,-71.9196 596,-106.8 596,-639.6 596,-639.6 596,-639.6 596,-665.1965 591.0323,-674.2337 573,-692.4 561.7252,-703.7586 546.243,-711.8298 531.8327,-717.4099"/>
+<polygon fill="#000000" stroke="#000000" points="530.3349,-714.2281 522.0925,-720.8849 532.6871,-720.8211 530.3349,-714.2281"/>
+</g>
+<!-- IN_ONE_SHOT -->
+<g id="node13" class="node">
+<title>IN_ONE_SHOT</title>
+<ellipse fill="none" stroke="#000000" cx="700" cy="-106.8" rx="75.8643" ry="18"/>
+<text text-anchor="middle" x="700" y="-102.6" font-family="Times,serif" font-size="14.00" fill="#000000">IN_ONE_SHOT</text>
+</g>
+<!-- IN_ONE_SHOT&#45;&gt;RESTART -->
+<g id="edge4" class="edge">
+<title>IN_ONE_SHOT&#45;&gt;RESTART</title>
+<path fill="none" stroke="#0000ff" d="M676.9312,-89.3704C659.5151,-77.2164 634.5042,-61.8271 610,-54 547.5343,-34.0473 363.5933,-24.1795 265.053,-20.2067"/>
+<polygon fill="#0000ff" stroke="#0000ff" points="265.0515,-16.704 254.9213,-19.8069 264.7755,-23.6986 265.0515,-16.704"/>
+<text text-anchor="middle" x="733.6743" y="-58.2" font-family="Times,serif" font-size="14.00" fill="#000000">non&#45;one&#45;shot key went through</text>
+</g>
+</g>
+</svg>
diff --git a/users/dennytom/chording_engine/tests/minunit.h b/users/dennytom/chording_engine/tests/minunit.h
new file mode 100644
index 000000000..ed71b6253
--- /dev/null
+++ b/users/dennytom/chording_engine/tests/minunit.h
@@ -0,0 +1,288 @@
+#define mu_assert(message, test) \
+ do { \
+ if (!(test)) { \
+ return message; \
+ } \
+ } while (0)
+
+#define RED "\033[0;31m"
+#define GREEN "\033[0;32m"
+#define NC "\033[0m"
+
+enum ASSERT_TYPES {
+ UINT,
+ INT
+};
+
+#define BUFF_SIZE 1024
+char buffer[BUFF_SIZE];
+
+#define ASSERT_EQ(type, actual, expected) \
+ do { \
+ if (actual != expected) { \
+ switch (type) { \
+ case UINT: \
+ snprintf(buffer, BUFF_SIZE, "\nline %d\nvar %s\nactual = %u\nexpected = %u\n", __LINE__, #actual, actual, expected); \
+ break; \
+ case INT: \
+ snprintf(buffer, BUFF_SIZE, "\nline %d\nvar %s\nactual = %d\nexpected = %d\n", __LINE__, #actual, actual, expected); \
+ break; \
+ default: \
+ snprintf(buffer, BUFF_SIZE, "\nline %d\nunsupported ASSERT_EQ type\n", __LINE__); \
+ break; \
+ } \
+ printf("%s\n", buffer); \
+ passed = false; \
+ all_passed = false; \
+ } \
+ } while (0)
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+
+#define MATRIX_ROWS 2
+#define MATRIX_COLS 10
+#define LAYOUT_test( \
+ k09, k08, k07, k06, k05, k04, k03, k02, k01, k00, \
+ k19, k18, k17, k16, k15, k14, k13, k12, k11, k10 \
+) { \
+ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09}, \
+ { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19}, \
+}
+
+#define PROGMEM
+#define memcpy_P memcpy
+const struct Chord* pgm_read_word(const struct Chord* const* chord) {return *chord;}
+
+typedef struct {
+ uint8_t col;
+ uint8_t row;
+} keypos_t;
+
+typedef struct {
+ keypos_t key;
+ bool pressed;
+ uint16_t time;
+} keyevent_t;
+
+typedef struct {
+ bool interrupted :1;
+ bool reserved2 :1;
+ bool reserved1 :1;
+ bool reserved0 :1;
+ uint8_t count :4;
+} tap_t;
+
+typedef struct {
+ keyevent_t event;
+ tap_t tap;
+} keyrecord_t;
+
+keyrecord_t pressed = {{{0,0},true,0}, {0,0,0,0,0}};
+keyrecord_t depressed = {{{0,0},false,0}, {0,0,0,0,0}};
+
+enum keycodes {
+ KC_NO,
+ KC_TILDE,
+ KC_GRAVE,
+ KC_EXCLAIM,
+ KC_1,
+ KC_AT,
+ KC_2,
+ KC_HASH,
+ KC_3,
+ KC_DOLLAR,
+ KC_4,
+ KC_PERCENT,
+ KC_5,
+ KC_CIRCUMFLEX,
+ KC_6,
+ KC_AMPERSAND,
+ KC_7,
+ KC_ASTERISK,
+ KC_8,
+ KC_LEFT_PAREN,
+ KC_9,
+ KC_RIGHT_PAREN,
+ KC_0,
+ KC_UNDERSCORE,
+ KC_MINUS,
+ KC_PLUS,
+ KC_EQUAL,
+ KC_LEFT_CURLY_BRACE,
+ KC_LBRACKET,
+ KC_RIGHT_CURLY_BRACE,
+ KC_RBRACKET,
+ KC_PIPE,
+ KC_BSLASH,
+ KC_COLON,
+ KC_SCOLON,
+ KC_DOUBLE_QUOTE,
+ KC_QUOTE,
+ KC_LEFT_ANGLE_BRACKET,
+ KC_COMMA,
+ KC_RIGHT_ANGLE_BRACKET,
+ KC_DOT,
+ KC_QUESTION,
+ KC_SLASH,
+ 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_Z,
+ KC_X,
+ KC_C,
+ KC_V,
+ KC_B,
+ KC_N,
+ KC_M,
+ KC_ESC,
+ KC_LSFT,
+ KC_LCTL,
+ KC_LGUI,
+ KC_LALT,
+ KC_RALT,
+ KC_RCTL,
+ KC_RGUI,
+ KC_RSFT,
+ KC_TAB,
+ KC_DEL,
+ KC_INS,
+ KC_BSPC,
+ KC_ENTER,
+ KC_SPACE,
+ 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_LEFT,
+ KC_DOWN,
+ KC_UP,
+ KC_RIGHT,
+
+ SAFE_RANGE
+};
+
+#define HISTORY 20
+
+int16_t current_time;
+uint8_t keyboard_history[HISTORY][SAFE_RANGE-1];
+int16_t time_history[HISTORY];
+uint8_t history_index;
+
+void register_code(int16_t keycode) {
+ history_index++;
+ for (int j = 0; j < SAFE_RANGE-1; j++) {
+ keyboard_history[history_index][j] = keyboard_history[history_index-1][j];
+ }
+ keyboard_history[history_index][keycode] = 1;
+ time_history[history_index] = current_time;
+};
+void unregister_code(int16_t keycode) {
+ history_index++;
+ for (int j = 0; j < SAFE_RANGE-1; j++) {
+ keyboard_history[history_index][j] = keyboard_history[history_index-1][j];
+ }
+ keyboard_history[history_index][keycode] = 0;
+ time_history[history_index] = current_time;
+};
+void send_keyboard_report(void) { /*still don't know what this does*/ };
+void matrix_scan_user (void);
+void wait_ms(uint16_t ms) {
+ current_time += ms;
+};
+uint16_t timer_read(void) {
+ uint16_t result = current_time;
+ return result;
+};
+uint16_t timer_elapsed(uint16_t timer) {
+ uint16_t result = current_time - timer;
+ return result;
+};
+void layer_move(int16_t layer) { /*ignoring for now*/ };
+void clear_keyboard(void) {
+ history_index++;
+ for (int j = 0; j < SAFE_RANGE-1; j++) {
+ keyboard_history[history_index][j] = 0;
+ }
+ time_history[history_index] = current_time;
+};
+void reset_keyboard(void) { /*ignoring for now*/ };
+
+void pause_ms(uint16_t ms) {
+ for (int i = 0; i < ms; i++) {
+ current_time++;
+ matrix_scan_user();
+ }
+};
+
+#define TEST(name) \
+ do { \
+ printf("%s\n", name); \
+ passed = true; \
+ do { \
+ uint8_t clear_state = ACTIVATED; \
+ struct Chord clear_chord PROGMEM = {0, QWERTY, &clear_state, NULL, 0, 0, clear}; \
+ clear_chord.function(&clear_chord); \
+ } while (0); \
+ current_time = 0; \
+ history_index = 0; \
+ for (int j = 0; j < SAFE_RANGE-1; j++) { \
+ keyboard_history[0][j] = 0; \
+ } \
+ time_history[0] = 0; \
+ for (int i = 1; i < HISTORY; i++) { \
+ for (int j = 0; j < SAFE_RANGE-1; j++) { \
+ keyboard_history[i][j] = -1; \
+ } \
+ time_history[i] = -1; \
+ }
+
+#define END_TEST \
+ if (passed) { \
+ printf(GREEN"PASSED"NC"\n"); \
+ } else { \
+ printf(RED"FAILED"NC"\n"); \
+ } \
+ } while(0);
+
+#define MAIN \
+int main(int argc, char **argv) { \
+ bool passed = true; \
+ bool all_passed = true;
+
+#define END \
+ printf("\n"); \
+ if (all_passed) { \
+ printf(GREEN"ALL TESTS PASSED"NC"\n"); \
+ } else { \
+ printf(RED"TESTS FAILED"NC"\n"); \
+ } \
+ return 1 - all_passed; \
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/tests/test.c b/users/dennytom/chording_engine/tests/test.c
new file mode 100644
index 000000000..0cc172f0a
--- /dev/null
+++ b/users/dennytom/chording_engine/tests/test.c
@@ -0,0 +1,1259 @@
+#include "minunit.h"
+#include "test_keymap.c"
+
+MAIN
+
+// CLEAR_KB
+TEST("clear")
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ struct Chord* chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ struct Chord chord_storage;
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ struct Chord* chord = &chord_storage;
+
+ *chord->state = READY;
+
+ if (chord->counter) {
+ *chord->counter = 1;
+ }
+ }
+
+ history_index++;
+ for (int j = 0; j < SAFE_RANGE-1; j++) {
+ keyboard_history[history_index][j] = 1;
+ }
+
+ current_pseudolayer = 5;
+ lock_next = true;
+ autoshift_mode = false;
+ command_mode = 1;
+ in_leader_mode = true;
+ dynamic_macro_mode = true;
+ a_key_went_through = true;
+
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ dynamic_macro_buffer[i] = 1;
+ }
+
+ uint8_t clear_state = ACTIVATED;
+ struct Chord clear_chord PROGMEM = {0, QWERTY, &clear_state, NULL, 0, 0, clear};
+ clear_chord.function(&clear_chord);
+
+ for (int i = 0; i < NUMBER_OF_CHORDS; i++) {
+ struct Chord* chord_ptr = (struct Chord*) pgm_read_word (&list_of_chords[i]);
+ struct Chord chord_storage;
+ memcpy_P(&chord_storage, chord_ptr, sizeof(struct Chord));
+ struct Chord* chord = &chord_storage;
+
+ ASSERT_EQ(UINT, *chord->state, IDLE);
+
+ if (chord->counter) {
+ ASSERT_EQ(UINT, *chord->counter, 0);
+ }
+ }
+
+ for (int j = 0; j < SAFE_RANGE-1; j++) {
+ ASSERT_EQ(UINT, keyboard_history[history_index][j], 0);
+ }
+
+ ASSERT_EQ(UINT, current_pseudolayer, 1);
+ ASSERT_EQ(UINT, lock_next, false);
+ ASSERT_EQ(UINT, autoshift_mode, true);
+ ASSERT_EQ(UINT, command_mode, 0);
+ ASSERT_EQ(UINT, in_leader_mode, false);
+ ASSERT_EQ(UINT, leader_ind, 0);
+ ASSERT_EQ(UINT, dynamic_macro_mode, false);
+ ASSERT_EQ(UINT, a_key_went_through, false);
+
+ for (int i = 0; i < DYNAMIC_MACRO_MAX_LENGTH; i++) {
+ ASSERT_EQ(UINT, dynamic_macro_buffer[i], 0);
+ }
+END_TEST
+
+TEST("pause_ms")
+ pause_ms(500);
+ ASSERT_EQ(UINT, current_time, 500);
+END_TEST
+
+// KC
+TEST("single_dance_held_states")
+ ASSERT_EQ(UINT, state_1, IDLE);
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT);
+ ASSERT_EQ(UINT, state_1, IDLE);
+ pause_ms(1);
+ ASSERT_EQ(UINT, state_1, ACTIVATED);
+ pause_ms(DANCE_TIMEOUT);
+ ASSERT_EQ(UINT, state_1, ACTIVATED);
+ pause_ms(1);
+ ASSERT_EQ(UINT, state_1, PRESS_FROM_ACTIVE);
+ pause_ms(DANCE_TIMEOUT);
+ ASSERT_EQ(UINT, state_1, PRESS_FROM_ACTIVE);
+ pause_ms(1);
+ ASSERT_EQ(UINT, state_1, FINISHED_FROM_ACTIVE);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, state_1, IDLE);
+END_TEST
+
+TEST("single_dance_held_codes")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ pause_ms(1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ pause_ms(DANCE_TIMEOUT);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ pause_ms(1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ pause_ms(DANCE_TIMEOUT);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ pause_ms(1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+END_TEST
+
+TEST("single_dance_tapped_states")
+ ASSERT_EQ(UINT, state_1, IDLE);
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT);
+ ASSERT_EQ(UINT, state_1, IDLE);
+ pause_ms(1);
+ ASSERT_EQ(UINT, state_1, ACTIVATED);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, state_1, IDLE);
+END_TEST
+
+TEST("single_dance_tapped_codes")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ pause_ms(1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+END_TEST
+
+// I can not actually track the states if the tap is faster than chord timeout
+
+TEST("single_dance_tapped_fast_codes")
+ ASSERT_EQ(UINT, state_0, IDLE);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Q], 0);
+END_TEST
+
+TEST("subchords_are_ignored")
+ ASSERT_EQ(UINT, state_0, IDLE);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_W], 0);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_ESC], 1);
+END_TEST
+
+TEST("multiple_chords_at_once")
+ ASSERT_EQ(UINT, state_0, IDLE);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_E], 1);
+END_TEST
+
+// MO
+TEST("momentary_layer")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT7, &pressed);
+ pause_ms(1);
+ process_record_user(BOT8, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ process_record_user(BOT7, &depressed);
+ pause_ms(1);
+ process_record_user(BOT8, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+END_TEST
+
+TEST("momentary_layer_reset")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT7, &pressed);
+ pause_ms(1);
+ process_record_user(BOT8, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ pause_ms(DANCE_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ process_record_user(BOT7, &depressed);
+ pause_ms(1);
+ process_record_user(BOT8, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+END_TEST
+
+TEST("momentary_layer_alt")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+
+ process_record_user(TOP8, &pressed);
+ pause_ms(1);
+ process_record_user(TOP9, &pressed);
+ pause_ms(1);
+ process_record_user(TOP0, &pressed);
+ pause_ms(1);
+ process_record_user(BOT8, &pressed);
+ pause_ms(1);
+ process_record_user(BOT9, &pressed);
+ pause_ms(1);
+ process_record_user(BOT0, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ process_record_user(TOP8, &depressed);
+ pause_ms(1);
+ process_record_user(TOP9, &depressed);
+ pause_ms(1);
+ process_record_user(TOP0, &depressed);
+ pause_ms(1);
+ process_record_user(BOT8, &depressed);
+ pause_ms(1);
+ process_record_user(BOT9, &depressed);
+ pause_ms(1);
+ process_record_user(BOT0, &depressed);
+
+ ASSERT_EQ(UINT, current_pseudolayer, FNC);
+END_TEST
+
+// DF
+TEST("permanent_layer")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT9, &pressed);
+ pause_ms(1);
+ process_record_user(BOT0, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ process_record_user(BOT9, &depressed);
+ pause_ms(1);
+ process_record_user(BOT0, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+END_TEST
+
+// AT
+TEST("autoshift_toggle")
+ ASSERT_EQ(UINT, autoshift_mode, 1);
+ uint8_t state = ACTIVATED;
+ struct Chord chord PROGMEM = {0, QWERTY, &state, NULL, 0, 0, autoshift_toggle};
+ chord.function(&chord);
+ ASSERT_EQ(UINT, autoshift_mode, 0);
+ state = ACTIVATED;
+ chord.function(&chord);
+ ASSERT_EQ(UINT, autoshift_mode, 1);
+END_TEST
+
+// AS
+TEST("autoshift_tap")
+ process_record_user(BOT1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(BOT1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Z], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 0);
+END_TEST
+
+TEST("autoshift_hold")
+ process_record_user(BOT1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(LONG_PRESS_MULTIPLIER * (DANCE_TIMEOUT + 1));
+ process_record_user(BOT1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Z], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[4][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LSFT], 0);
+END_TEST
+
+TEST("autoshift_hold_off")
+ autoshift_mode = 0;
+ process_record_user(BOT1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(LONG_PRESS_MULTIPLIER * (DANCE_TIMEOUT + 1));
+ process_record_user(BOT1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Z], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Z], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 0);
+END_TEST
+
+// LOCK
+TEST("lock")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+ process_record_user(BOT1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ pause_ms(1);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP2, &pressed);
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP2, &depressed);
+ process_record_user(BOT1, &depressed);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1);
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+ process_record_user(BOT1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+ pause_ms(1);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1000);
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT1, &depressed);
+ pause_ms(1);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+END_TEST
+
+// OSK
+TEST("one_shot_key_tap")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT2, &pressed);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1);
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+END_TEST
+
+TEST("one_shot_key_hold")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT2, &pressed);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(DANCE_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+
+ process_record_user(BOT2, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+END_TEST
+
+TEST("one_shot_key_retrotapping")
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT2, &pressed);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(DANCE_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+
+ pause_ms(1000);
+
+ process_record_user(BOT2, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 1);
+END_TEST
+
+// OSL
+TEST("one_shot_layer_tap")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT6, &pressed);
+ process_record_user(BOT7, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT6, &depressed);
+ pause_ms(1);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+END_TEST
+
+TEST("one_shot_layer_hold")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT6, &pressed);
+ process_record_user(BOT7, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(DANCE_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ process_record_user(BOT6, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+END_TEST
+
+TEST("one_shot_layer_retrotapping")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT6, &pressed);
+ process_record_user(BOT7, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(DANCE_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ pause_ms(1000);
+
+ process_record_user(BOT6, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+END_TEST
+
+// CMD
+TEST("command_mode")
+ // start recording
+ process_record_user(TOP5, &pressed);
+ process_record_user(TOP6, &pressed);
+ process_record_user(BOT5, &pressed);
+ process_record_user(BOT6, &pressed);
+ pause_ms(1);
+ process_record_user(TOP5, &depressed);
+ process_record_user(TOP6, &depressed);
+ process_record_user(BOT5, &depressed);
+ process_record_user(BOT6, &depressed);
+
+ ASSERT_EQ(UINT, command_mode, 1);
+
+ // record shift+q
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(BOT1, &depressed);
+ process_record_user(BOT2, &depressed);
+ pause_ms(1000);
+
+ process_record_user(TOP1, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+
+
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[history_index][KC_LSFT], 0);
+ // execute
+ process_record_user(TOP5, &pressed);
+ process_record_user(TOP6, &pressed);
+ process_record_user(BOT5, &pressed);
+ process_record_user(BOT6, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+
+ ASSERT_EQ(UINT, command_mode, 0);
+
+ // test history
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[4][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[5][KC_Q], 255);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LSFT], 255);
+END_TEST
+
+// KK
+TEST("key_key_dance_tap")
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ process_record_user(BOT2, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_X], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LCTL], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_X], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LCTL], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_X], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LCTL], 0);
+END_TEST
+
+TEST("key_key_dance_hold")
+ process_record_user(BOT2, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ pause_ms(DANCE_TIMEOUT + 1);
+ process_record_user(BOT2, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_X], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LCTL], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_X], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LCTL], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_X], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LCTL], 0);
+END_TEST
+
+// KL
+TEST("key_layer_tap")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_C], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_C], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_C], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_C], 255);
+END_TEST
+
+TEST("key_layer_retrotapping")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT3, &pressed);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_C], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_C], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_C], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_C], 255);
+END_TEST
+
+TEST("key_layer_hold_quick_typist")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ pause_ms(1);
+
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_1], 255);
+END_TEST
+
+TEST("key_layer_hold_slow_typist")
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+ process_record_user(BOT3, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, NUM);
+ pause_ms(1);
+
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_1], 255);
+END_TEST
+
+// KM
+TEST("key_mod_tap")
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_V], 0);
+ process_record_user(BOT4, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_V], 0);
+ process_record_user(BOT4, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_V], 0);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_V], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LALT], 255);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_V], 255);
+END_TEST
+
+TEST("key_mod_retrotapping")
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_V], 0);
+ process_record_user(BOT4, &pressed);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_V], 0);
+ process_record_user(BOT4, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_V], 0);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_V], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LALT], 255);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_V], 255);
+END_TEST
+
+TEST("key_mod_hold_quick_typist")
+ process_record_user(BOT4, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+
+ process_record_user(BOT4, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_LALT], 255);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_V], 255);
+END_TEST
+
+TEST("key_mod_hold_slow_typist")
+ process_record_user(BOT4, &pressed);
+ pause_ms(CHORD_TIMEOUT + 1);
+
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1000);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1000);
+
+ process_record_user(BOT4, &depressed);
+ ASSERT_EQ(UINT, current_pseudolayer, QWERTY);
+
+ ASSERT_EQ(UINT, keyboard_history[0][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[0][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_Q], 1);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_LALT], 1);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_LALT], 0);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_V], 0);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_Q], 0);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_LALT], 255);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_V], 255);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_Q], 255);
+END_TEST
+
+// LEADER
+TEST("leader_triggers_global")
+ uint8_t state = ACTIVATED;
+ struct Chord chord PROGMEM = {0, QWERTY, &state, NULL, 0, 0, leader};
+ chord.function(&chord);
+
+ ASSERT_EQ(UINT, in_leader_mode, 1);
+END_TEST
+
+TEST("leader_no_follow")
+ uint8_t state = ACTIVATED;
+ struct Chord chord PROGMEM = {0, QWERTY, &state, NULL, 0, 0, leader};
+ chord.function(&chord);
+
+ ASSERT_EQ(UINT, in_leader_mode, 1);
+
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, in_leader_mode, 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_O], 255);
+END_TEST
+
+TEST("leader_wrong_follow")
+ process_record_user(TOP2, &pressed);
+ process_record_user(TOP3, &pressed);
+ process_record_user(BOT2, &pressed);
+ process_record_user(BOT3, &pressed);
+ pause_ms(1);
+ process_record_user(TOP2, &depressed);
+ process_record_user(TOP3, &depressed);
+ process_record_user(BOT2, &depressed);
+ process_record_user(BOT3, &depressed);
+
+ ASSERT_EQ(UINT, in_leader_mode, 1);
+
+ pause_ms(1);
+ process_record_user(TOP1, &pressed);
+ pause_ms(1);
+ process_record_user(TOP1, &depressed);
+ pause_ms(1);
+ process_record_user(TOP2, &pressed);
+ pause_ms(1);
+ process_record_user(TOP2, &depressed);
+
+ pause_ms(LEADER_TIMEOUT);
+ pause_ms(1);
+
+ ASSERT_EQ(UINT, in_leader_mode, 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_Q], 255);
+END_TEST
+
+TEST("leader_correct_follow")
+ process_record_user(TOP2, &pressed);
+ process_record_user(TOP3, &pressed);
+ process_record_user(BOT2, &pressed);
+ process_record_user(BOT3, &pressed);
+ pause_ms(1);
+ process_record_user(TOP2, &depressed);
+ process_record_user(TOP3, &depressed);
+ process_record_user(BOT2, &depressed);
+ process_record_user(BOT3, &depressed);
+
+ ASSERT_EQ(UINT, in_leader_mode, 1);
+
+ pause_ms(1);
+ process_record_user(TOP0, &pressed);
+ pause_ms(1);
+ process_record_user(TOP0, &depressed);
+ pause_ms(1);
+ process_record_user(TOP9, &pressed);
+ pause_ms(1);
+ process_record_user(TOP9, &depressed);
+
+ pause_ms(LEADER_TIMEOUT);
+ ASSERT_EQ(UINT, in_leader_mode, 1);
+
+ pause_ms(1);
+ ASSERT_EQ(UINT, in_leader_mode, 0);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_O], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_P], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_A], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_S], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_O], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_P], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_A], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_S], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_O], 255);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_P], 255);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_A], 255);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_S], 255);
+
+ ASSERT_EQ(UINT, keyboard_history[4][KC_O], 255);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_P], 255);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_A], 255);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_S], 255);
+
+ ASSERT_EQ(UINT, keyboard_history[5][KC_Q], 255);
+END_TEST
+
+// DYNAMIC MACRO
+TEST("dynamic_macro_record_mode")
+ current_pseudolayer = NUM;
+
+ // record
+ ASSERT_EQ(UINT, dynamic_macro_mode, 0);
+ process_record_user(BOT7, &pressed);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+ pause_ms(1000);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+END_TEST
+
+TEST("dynamic_macro_record_mode_off")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT7, &pressed);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+
+ process_record_user(BOT9, &pressed);
+ process_record_user(BOT9, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 0);
+END_TEST
+
+TEST("dynamic_macro_record_one")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT7, &pressed);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 255);
+
+ process_record_user(BOT9, &pressed);
+ process_record_user(BOT9, &depressed);
+
+ pause_ms(1000);
+
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 255);
+
+ pause_ms(1000);
+
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 255);
+END_TEST
+
+TEST("dynamic_macro_record_two")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT7, &pressed);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+
+ process_record_user(TOP2, &pressed);
+ process_record_user(TOP2, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 255);
+
+ process_record_user(BOT9, &pressed);
+ process_record_user(BOT9, &depressed);
+
+ pause_ms(1000);
+
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 255);
+END_TEST
+
+TEST("dynamic_macro_record_two_parts")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT7, &pressed);
+ process_record_user(BOT7, &depressed);
+ ASSERT_EQ(UINT, dynamic_macro_mode, 1);
+
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+
+ process_record_user(TOP2, &pressed);
+ process_record_user(TOP2, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 255);
+
+ process_record_user(BOT8, &pressed);
+ process_record_user(BOT8, &depressed);
+
+ process_record_user(TOP3, &pressed);
+ process_record_user(TOP3, &depressed);
+
+ process_record_user(BOT9, &pressed);
+ process_record_user(BOT9, &depressed);
+
+ pause_ms(1000);
+
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_3], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_3], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_3], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_3], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_3], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[6][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_3], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[7][KC_1], 255);
+END_TEST
+
+// dance + M()
+
+TEST("dance_tap")
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_9], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_0], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_9], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_0], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_9], 255);
+END_TEST
+
+TEST("dance_hold")
+ process_record_user(BOT0, &pressed);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_9], 1);
+
+ process_record_user(BOT0, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_9], 0);
+END_TEST
+
+TEST("dance_tap_tap")
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_9], 0);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_0], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_9], 0);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_0], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_9], 255);
+END_TEST
+
+TEST("dance_tap_hold")
+ process_record_user(BOT0, &pressed);
+ process_record_user(BOT0, &depressed);
+ pause_ms(1);
+ process_record_user(BOT0, &pressed);
+ pause_ms(1000);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_0], 1);
+
+ process_record_user(BOT0, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_0], 0);
+END_TEST
+
+// MK
+TEST("multiple_keys")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT1, &pressed);
+ process_record_user(BOT1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LCTL], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LCTL], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LCTL], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LCTL], 0);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[5][KC_LCTL], 255);
+END_TEST
+
+TEST("multiple_keys_interleaved")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT1, &pressed);
+ pause_ms(CHORD_TIMEOUT+1);
+
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+ process_record_user(TOP1, &pressed);
+ process_record_user(TOP1, &depressed);
+
+ process_record_user(BOT1, &depressed);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LCTL], 1);
+ ASSERT_EQ(UINT, keyboard_history[1][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LCTL], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[6][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[7][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[8][KC_1], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[9][KC_LCTL], 0);
+ ASSERT_EQ(UINT, keyboard_history[9][KC_LSFT], 1);
+
+ ASSERT_EQ(UINT, keyboard_history[10][KC_LCTL], 0);
+ ASSERT_EQ(UINT, keyboard_history[10][KC_LSFT], 0);
+
+ ASSERT_EQ(UINT, keyboard_history[11][KC_LCTL], 255);
+END_TEST
+
+// D
+TEST("dance_one")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 255);
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_1], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_1], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_1], 255);
+END_TEST
+
+TEST("dance_two")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_2], 255);
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_2], 255);
+END_TEST
+
+TEST("dance_three")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_3], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_3], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_3], 255);
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_3], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_3], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_3], 1);
+ ASSERT_EQ(UINT, keyboard_history[4][KC_3], 0);
+ ASSERT_EQ(UINT, keyboard_history[5][KC_3], 255);
+END_TEST
+
+TEST("dance_two_held")
+ current_pseudolayer = NUM;
+
+ process_record_user(BOT3, &pressed);
+ process_record_user(BOT3, &depressed);
+ process_record_user(BOT3, &pressed);
+
+ pause_ms(CHORD_TIMEOUT+DANCE_TIMEOUT+2);
+
+ ASSERT_EQ(UINT, keyboard_history[1][KC_2], 1);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 255);
+
+ process_record_user(BOT3, &depressed);
+ ASSERT_EQ(UINT, keyboard_history[2][KC_2], 0);
+ ASSERT_EQ(UINT, keyboard_history[3][KC_2], 255);
+END_TEST
+
+// These two are leaving the chording engine, they kinda have to be tested manually
+// TO
+// RESET
+
+END
diff --git a/users/dennytom/chording_engine/tests/test_full.sh b/users/dennytom/chording_engine/tests/test_full.sh
new file mode 100644
index 000000000..ea93aec8f
--- /dev/null
+++ b/users/dennytom/chording_engine/tests/test_full.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+cd ..
+python3 parser.py tests/test_keymap_def.json tests/test_keymap.c && \
+gcc -g tests/test.c -o tests/test && \
+tests/test && \
+python3 parser.py ../../../keyboards/butterstick/keymaps/tomas/keymap_def.json ../../../keyboards/butterstick/keymaps/tomas/keymap.c && \
+python3 parser.py ../../../keyboards/georgi/keymaps/tomas/keymap_def.json ../../../keyboards/georgi/keymaps/tomas/keymap.c && \
+python3 parser.py ../../../keyboards/georgi/keymaps/buttery/keymap_def.json ../../../keyboards/georgi/keymaps/buttery/keymap.c && \
+cd ../../../ && \
+make butterstick && \
+make georgi \ No newline at end of file
diff --git a/users/dennytom/chording_engine/tests/test_keymap_def.json b/users/dennytom/chording_engine/tests/test_keymap_def.json
new file mode 100644
index 000000000..eae2ed37c
--- /dev/null
+++ b/users/dennytom/chording_engine/tests/test_keymap_def.json
@@ -0,0 +1,145 @@
+{
+ "keys": [
+ "TOP1", "TOP2", "TOP3", "TOP4", "TOP5", "TOP6", "TOP7", "TOP8", "TOP9", "TOP0",
+ "BOT1", "BOT2", "BOT3", "BOT4", "BOT5", "BOT6", "BOT7", "BOT8", "BOT9", "BOT0"
+ ],
+ "parameters": {
+ "do_not_include_QMK": true,
+ "layout_function_name": "LAYOUT_test",
+ "chord_timeout": 100,
+ "dance_timeout": 200,
+ "leader_timeout": 750,
+ "tap_timeout": 50,
+ "command_max_length": 5,
+ "leader_max_length": 5,
+ "dynamic_macro_max_length": 20,
+ "string_max_length": 16,
+ "long_press_multiplier": 3,
+ "default_pseudolayer": "QWERTY"
+ },
+ "layers": [
+ {
+ "type": "auto"
+ },
+ {
+ "type": "manual",
+ "keycodes": ["KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0",
+ "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P"
+ ]
+ }
+ ],
+ "chord_sets": [
+ {
+ "name": "rows",
+ "chords": [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP5"], ["TOP6"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP0"],
+ ["TOP1", "BOT1"], ["TOP2", "BOT2"], ["TOP3", "BOT3"], ["TOP4", "BOT4"], ["TOP5", "BOT5"], ["TOP6", "BOT6"], ["TOP7", "BOT7"], ["TOP8", "BOT8"], ["TOP9", "BOT9"], ["TOP0", "BOT0"],
+ ["BOT1"], ["BOT2"], ["BOT3"], ["BOT4"], ["BOT5"], ["BOT6"], ["BOT7"], ["BOT8"], ["BOT9"], ["BOT0"]
+ ]
+ },
+ {
+ "name": "cols",
+ "chords": [
+ ["TOP1", "TOP2"], ["TOP2", "TOP3"], ["TOP3", "TOP4"], ["TOP4", "TOP5"], ["TOP5", "TOP6"], ["TOP6", "TOP7"], ["TOP7", "TOP8"], ["TOP8", "TOP9"], ["TOP9", "TOP0"],
+ ["TOP1", "TOP2", "BOT1", "BOT2"], ["TOP2", "TOP3", "BOT2", "BOT3"], ["TOP3", "TOP4", "BOT3", "BOT4"], ["TOP4", "TOP5", "BOT4", "BOT5"], ["TOP5", "TOP6", "BOT5", "BOT6"], ["TOP6", "TOP7", "BOT6", "BOT7"], ["TOP7", "TOP8", "BOT7", "BOT8"], ["TOP8", "TOP9", "BOT8", "BOT9"], ["TOP9", "TOP0", "BOT9", "BOT0"],
+ ["BOT1", "BOT2"], ["BOT2", "BOT3"], ["BOT3", "BOT4"], ["BOT4", "BOT5"], ["BOT5", "BOT6"], ["BOT6", "BOT7"], ["BOT7", "BOT8"], ["BOT8", "BOT9"], ["BOT9", "BOT0"]
+ ]
+ },
+ {
+ "name": "asetniop",
+ "chords": [
+ ["TOP1"], ["TOP2"], ["TOP3"], ["TOP4"], ["TOP7"], ["TOP8"], ["TOP9"], ["TOP0"],
+ ["TOP1", "TOP2"], ["TOP2", "TOP3"], ["TOP3", "TOP4"], ["TOP4", "TOP7"], ["TOP7", "TOP8"], ["TOP8", "TOP9"], ["TOP9", "TOP0"],
+ ["TOP1", "TOP3"], ["TOP2", "TOP4"], ["TOP3", "TOP7"], ["TOP4", "TOP8"], ["TOP7", "TOP9"], ["TOP8", "TOP0"],
+ ["TOP1", "TOP4"], ["TOP2", "TOP7"], ["TOP3", "TOP8"], ["TOP4", "TOP9"], ["TOP7", "TOP0"],
+ ["TOP1", "TOP7"], ["TOP2", "TOP8"], ["TOP3", "TOP9"], ["TOP4", "TOP0"],
+ ["TOP1", "TOP8"], ["TOP2", "TOP9"], ["TOP3", "TOP0"],
+ ["TOP1", "TOP9"], ["TOP2", "TOP0"],
+ ["TOP1", "TOP0"]
+ ]
+ }
+ ],
+ "pseudolayers": [
+ {
+ "name": "ALWAYS_ON",
+ "chords": [
+ {
+ "type": "visual",
+ "chord": [
+ " ", " ", " ", " ", " ", " ", " ", "X", "X", "X",
+ " ", " ", " ", " ", " ", " ", " ", "X", "X", "X"
+ ],
+ "keycode": "MO(FNC, NUM)"
+ }
+ ]
+ },
+ {
+ "name": "QWERTY",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+ "A", "S", "D", "F", "G", "H", "J", "K", "L", ";",
+ "AS(Z)", "KK(X, LCTL)", "KL(C, NUM)", "KM(V, LALT)", "B", "N", "M", "COMMA", ".", "M(double_dance, KC_9, KC_0)"
+ ]
+ },
+ {
+ "type": "chord_set",
+ "set": "cols",
+ "keycodes": [
+ "ESC", "", "", "", "", "", "", "", "",
+ "", "LEAD", "", "", "CMD", "", "", "", "",
+ "LSFT", "O(LSFT)", "", "", "", "O(NUM)", "MO(NUM)", "", "DF(NUM)"
+ ]
+ },
+ {
+ "type": "visual",
+ "chord": [
+ "X", "X", " ", " ", " ", " ", " ", " ", " ", " ",
+ "X", "X", " ", " ", " ", " ", " ", " ", " ", " "
+ ],
+ "keycode": "LOCK"
+ }
+ ]
+ },
+ {
+ "name": "NUM",
+ "chords": [
+ {
+ "type": "chord_set",
+ "set": "rows",
+ "keycodes": [
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "KC_LEFT", "D(KC_1, KC_2, KC_3)", "", "", "", "DM_RECORD", "DM_NEXT", "DM_END", "DM_PLAY"
+ ]
+ },
+ {
+ "type": "simple",
+ "chord": ["BOT1"],
+ "keycode": "MK(KC_LCTL, KC_LSFT)"
+ }
+ ]
+ },
+ {
+ "name": "FNC",
+ "chords": []
+ }
+ ],
+ "leader_sequences": [
+ {
+ "name": "fnc_L1",
+ "function": "void fnc_L1(void) { key_in(KC_A); clear_keyboard(); }",
+ "sequence": ["KC_O", "KC_P"]
+ },
+ {
+ "name": "fnc_L2",
+ "function": "void fnc_L2(void) { key_in(KC_S); clear_keyboard(); }",
+ "sequence": ["KC_P", "KC_O"]
+ }
+ ],
+ "extra_code": "void double_dance(const struct Chord* self) {\n switch (*self->state) {\n case ACTIVATED:\n *self->counter = (*self->counter + 1) % 2;\n break;\n case PRESS_FROM_ACTIVE:\n if (*self->counter == 1) {\n key_in(self->value1);\n } else {\n key_in(self->value2);\n }\n *self->state = FINISHED_FROM_ACTIVE;\n break;\n case FINISHED:\n if (*self->counter == 1) {\n tap_key(self->value1);\n } else {\n tap_key(self->value2);\n }\n *self->counter = 0;\n *self->state = IDLE;\n break;\n case RESTART:\n if (*self->counter == 1) {\n key_out(self->value1);\n } else {\n key_out(self->value2);\n }\n *self->counter = 0;\n break;\n default:\n break;\n }\n}\n",
+ "extra_dependencies": []
+} \ No newline at end of file
diff --git a/users/dennytom/chording_engine/tests/test_quick.sh b/users/dennytom/chording_engine/tests/test_quick.sh
new file mode 100644
index 000000000..3740122e2
--- /dev/null
+++ b/users/dennytom/chording_engine/tests/test_quick.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+cd ..
+python3 parser.py tests/test_keymap_def.json tests/test_keymap.c && \
+gcc -g tests/test.c -o tests/test && \
+tests/test \ No newline at end of file
diff --git a/users/konstantin/config.h b/users/konstantin/config.h
index bc1987c35..dcea9be27 100644
--- a/users/konstantin/config.h
+++ b/users/konstantin/config.h
@@ -2,11 +2,13 @@
#define FORCE_NKRO
-#define MOUSEKEY_DELAY 50
-#define MOUSEKEY_INTERVAL 15
+#define MOUSEKEY_DELAY 0
+#define MOUSEKEY_INTERVAL 10
#define MOUSEKEY_MAX_SPEED 4
-#define MOUSEKEY_TIME_TO_MAX 50
-#define MOUSEKEY_WHEEL_MAX_SPEED 1
+#define MOUSEKEY_TIME_TO_MAX 100
+#define MOUSEKEY_WHEEL_DELAY 0
+#define MOUSEKEY_WHEEL_INTERVAL 50
+#define MOUSEKEY_WHEEL_MAX_SPEED 4
#define MOUSEKEY_WHEEL_TIME_TO_MAX 50
#define NO_ACTION_FUNCTION
@@ -21,7 +23,7 @@
#define PERMISSIVE_HOLD
#define TAPPING_TERM 200
-#define TAPPING_TOGGLE 2
+#define TAPPING_TOGGLE 3
#define UNICODE_CYCLE_PERSIST false
#define UNICODE_SELECTED_MODES UC_WINC, UC_WIN, UC_LNX
diff --git a/users/konstantin/konstantin.c b/users/konstantin/konstantin.c
index 9cee25ac6..72aca9fb8 100644
--- a/users/konstantin/konstantin.c
+++ b/users/konstantin/konstantin.c
@@ -69,7 +69,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case CLEAR:
if (record->event.pressed) {
CLEAN_MODS(
- SEND_STRING(SS_LCTRL("a") SS_TAP(X_DELETE));
+ SEND_STRING(SS_LCTL("a") SS_TAP(X_DELETE));
)
}
break;
@@ -117,3 +117,12 @@ void led_set_keymap(uint8_t usb_led) {}
void led_set_user(uint8_t usb_led) {
led_set_keymap(usb_led);
}
+
+__attribute__((weak))
+bool led_update_keymap(led_t led_state) {
+ return true;
+}
+
+bool led_update_user(led_t led_state) {
+ return led_update_keymap(led_state);
+}
diff --git a/users/konstantin/konstantin.h b/users/konstantin/konstantin.h
index da2105831..0936e3c3e 100644
--- a/users/konstantin/konstantin.h
+++ b/users/konstantin/konstantin.h
@@ -86,3 +86,4 @@ void keyboard_post_init_keymap(void);
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
uint32_t layer_state_set_keymap(uint32_t state);
void led_set_keymap(uint8_t usb_led);
+bool led_update_keymap(led_t led_state);
diff --git a/users/konstantin/rgb.h b/users/konstantin/rgb.h
index cc7d91808..e09c5bd77 100644
--- a/users/konstantin/rgb.h
+++ b/users/konstantin/rgb.h
@@ -5,7 +5,7 @@
#define GODSPEED_BLUE 198, 68, 255
#define GODSPEED_YELLOW 27, 153, 255
#define MODERN_DOLCH_CYAN 110, 255, 108
-#define MODERN_DOLCH_RED 251, 255, 108
+#define MODERN_DOLCH_RED 253, 255, 108
extern const HSV godspeed_blue;
extern const HSV godspeed_yellow;
diff --git a/users/konstantin/rules.mk b/users/konstantin/rules.mk
index bf0ab979f..d989f486c 100644
--- a/users/konstantin/rules.mk
+++ b/users/konstantin/rules.mk
@@ -13,4 +13,4 @@ ifneq (,$(filter yes,$(UNICODE_ENABLE) $(UNICODEMAP_ENABLE)))
SRC += unicode.c
endif
-EXTRAFLAGS += -flto
+LTO_ENABLE = yes
diff --git a/users/pvinis/config.h b/users/pvinis/config.h
index 8e2efb40a..14ec0dc8f 100644
--- a/users/pvinis/config.h
+++ b/users/pvinis/config.h
@@ -1,10 +1,9 @@
#pragma once
-#ifdef AUDIO_ENABLE
-// #define STARTUP_SONG SONG(SONIC_RING)
-// #define DAC_SAMPLE_MAX 65535U // maybe this works for volume?
-#endif
-
// allow rolling when keys have hold functionality
#define IGNORE_MOD_TAP_INTERRUPT
// #define TAPPING_TERM 150
+
+#if defined(MOUSE_KEYS)
+# define MOUSEKEY_WHEEL_TIME_TO_MAX 1
+#endif
diff --git a/users/pvinis/pvinis.c b/users/pvinis/pvinis.c
index e97edcb98..31c3023e8 100644
--- a/users/pvinis/pvinis.c
+++ b/users/pvinis/pvinis.c
@@ -2,88 +2,97 @@
#include "version.h"
#ifdef AUDIO_ENABLE
-#include "audio.h"
-#endif // AUDIO_ENABLE
-
-
-#ifdef AUDIO_ENABLE
-// float tone_katamari_rolling_star[][2] = SONG(KATAMARI_ROLLING_STAR);
-#endif // AUDIO_ENABLE
+# include "audio.h"
+float song_sonic_ring[][2] = SONG(SONIC_RING);
+float song_coin_sound[][2] = SONG(COIN_SOUND);
+float song_test[][2] = SONG(QWERTY_SOUND);
+#endif
// SYMBOL + SYSCTL = KBCTL
uint32_t layer_state_set_user(uint32_t state) {
- uint32_t intermediate_state = update_tri_layer_state(state, LR_SYMBOL, LR_SYSCTL, LR_KBCTL);
- intermediate_state = layer_state_set_user_local(intermediate_state);
- return intermediate_state;
+ uint32_t intermediate_state = update_tri_layer_state(state, LR_SYMBOL, LR_SYSCTL, LR_KBCTL);
+ intermediate_state = layer_state_set_user_keymap(intermediate_state);
+ return intermediate_state;
}
-
// functions for the individual keymaps to implement if they need something extra
-__attribute__ ((weak))
-bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
- return true;
-}
+__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
-
-// handle my own keycodes
+// Handle my own keycodes.
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- switch (keycode) {
-
- case PV_VRSN:
- if (record->event.pressed) {
- SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
- }
- return false;
-
- case PV_MAKE:
- if (!record->event.pressed) {
- SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
+ switch (keycode) {
+ case PV_VRSN:
+ if (record->event.pressed) {
+ SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
+ }
+ return false;
+
+ case PV_MAKE:
+ // make ergodox_ez:pvinis:teensy
+ if (!record->event.pressed) {
+ SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
- ":dfu"
+ ":dfu"
#elif defined(BOOTLOADER_HALFKAY)
- ":teensy"
+ ":teensy"
#elif defined(BOOTLOADER_CATERINA)
- ":avrdude"
+ ":avrdude"
#endif
- SS_TAP(X_ENTER)
- );
- }
- return false;
+ SS_TAP(X_ENTER));
+ }
+ return false;
- case PV_FLSH:
- reset_keyboard();
- return false;
+ case PV_FLSH:
+ reset_keyboard();
+ return false;
- case PV_KTMR:
- if (record->event.pressed) {
+ case PV_SSNC:
+ if (record->event.pressed) {
#ifdef AUDIO_ENABLE
- // PLAY_SONG(tone_katamari_rolling_star);
+ PLAY_SONG(song_sonic_ring);
#endif
- }
- return false;
- }
- return process_record_keymap(keycode, record);
-}
+ }
+ return false;
+ case PV_SCIN:
+ if (record->event.pressed) {
+#ifdef AUDIO_ENABLE
+ PLAY_SONG(song_coin_sound);
+#endif
+ }
+ return false;
+
+ case PV_TEST:
+ if (record->event.pressed) {
+#ifdef AUDIO_ENABLE
+ PLAY_SONG(song_test);
+#endif
+ }
+ return false;
+ }
+ return process_record_keymap(keycode, record);
+}
#ifdef TAP_DANCE_ENABLE
-qk_tap_dance_action_t tap_dance_actions[] = {
-};
-#endif // TAP_DANCE_ENABLE
+qk_tap_dance_action_t tap_dance_actions[] = {};
+#endif
+void keyboard_post_init_rgb_light(void) {
+ rgblight_sethsv(HSV_GOLD);
+ rgblight_mode(RGBLIGHT_MODE_BREATHING);
+ // rgblight_mode(RGBLIGHT_MODE_KNIGHT+1);
+}
-// init stuff
+// Init stuff.
void keyboard_post_init_user(void) {
- keyboard_post_init_user_local();
+#if defined(RGBLIGHT_ENABLE)
+ keyboard_post_init_rgb_light();
+#endif
+ keyboard_post_init_user_keymap();
}
+// Default functions.
+__attribute__((weak)) void keyboard_post_init_user_keymap(void) {}
-// default functions
-__attribute__ ((weak))
-void keyboard_post_init_user_local(void) {}
-
-__attribute__ ((weak))
-uint32_t layer_state_set_user_local(uint32_t state) {
- return state;
-}
+__attribute__((weak)) uint32_t layer_state_set_user_keymap(uint32_t state) { return state; }
diff --git a/users/pvinis/pvinis.h b/users/pvinis/pvinis.h
index 0c75c6a66..c50033a44 100644
--- a/users/pvinis/pvinis.h
+++ b/users/pvinis/pvinis.h
@@ -2,84 +2,103 @@
#include "quantum.h"
-
-// my own keycodes
+// My own keycodes.
enum userspace_custom_keycodes {
- PV_ = SAFE_RANGE,
+ PV_ = SAFE_RANGE,
+
+ PV_VRSN, // Print firmware version.
+ PV_MAKE, // Print the make command of the keyboard.
+ PV_FLSH, // Reset keyboard.
- PV_VRSN, // prints firmware version
- PV_MAKE, // prints the make command of the keyboard
- PV_FLSH, // resets keyboard
- PV_KTMR, // play katamari music
+ PV_SSNC, // Play Sonic Ring.
+ PV_SCIN, // Play Coin Sound.
- PV_SAFE_RANGE, // used for extra keycodes in the individual keymaps
+ PV_TEST, // For quick testing purposes.
+
+ PV_SAFE_RANGE, // Used for extra keycodes in individual keymaps.
};
enum tap_dance_indexes {
- // tap dance
- TD_FLSH, // flash keyboard (as if the physical flash key was pressed)
+ // tap dance
+ TD_FLSH, // flash keyboard (as if the physical flash key was pressed)
};
-#define ALLM(kc) LCAG(kc) // easier name for left ctrl-alt-gui
-#define PV_ESCC CTL_T(KC_ESC) // esc on tap, ctrl on hold
-#define PV_LOCK LCTL(LSFT(KC_PWR)) // lock computer
-#define TD_3FLS TD(TD_FLSH) // tap dance 3 times for flash
-
+#define ALLM(kc) LCAG(kc) // Easier name for left ctrl-alt-gui.
+#define PV_ESCC CTL_T(KC_ESC) // esc on tap, ctrl on hold.
+#define PV_LOCK LCTL(LSFT(KC_PWR)) // Lock computer.
+#define TD_3FLS TD(TD_FLSH) // Tap dance 3 times for flash.
-// layers
+// Layers.
enum {
- LR_BASE = 0, // used for basic keys like the surrounding ctrl, cmd, etc
+ LR_BASE = 0, // used for basic keys like the surrounding ctrl, cmd, etc
- LR_QWERTY,
- LR_CARPALX,
+ LR_QWERTY,
+ LR_CARPALX,
+ LR_GAME1, // game layout (space on the left thumb, no modifiers, etc)
+ LR_GAME2, // game layout (space on the left thumb, no modifiers, etc, arrows)
- LR_SYMBOL, // symbol input (!, @, #, etc)
- LR_SYSCTL, // system control (music, volume, keyboard flash, etc)
- LR_KBCTL, // keyboard control (version, make, flash, etc)
-};
+ LR_SYMBOL, // symbol input (!, @, #, etc)
+ LR_SYSCTL, // system control (music, volume, keyboard flash, etc)
+ LR_KBCTL, // keyboard control (version, make, flash, etc)
+};
-// layer switchers
-#define BASE TO(LR_BASE)
-#define QWERTY TO(LR_QWERTY)
+// Layer switchers.
+#define BASE TO(LR_BASE)
+#define QWERTY TO(LR_QWERTY)
#define CARPALX TO(LR_CARPALX)
-
-#define SYMBOL MO(LR_SYMBOL)
-#define SYSCTL MO(LR_SYSCTL)
-#define KBCTL MO(LR_KBCTL)
-
-
-// layout parts for easy reuse between keyboard keymaps
-
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-// | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 |
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define ________________NUMBERS_L__________________ KC_1, KC_2, KC_3, KC_4, KC_5
-#define ________________NUMBERS_R__________________ KC_6, KC_7, KC_8, KC_9, KC_0
-
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-// | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 |
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define ______________________F_L__________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5
-#define ______________________F_R__________________ KC_F6, KC_F7, KC_F8, KC_F9, KC_F10
-
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-// | Q | W | E | R | T | | Y | U | I | O | P |
-// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
-// | A | S | D | F | G | | H | J | K | L | ; |
-// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
-// | Z | X | C | V | B | | N | M | , | . | / |
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define _________________QWERTY_L1_________________ KC_Q , KC_W , KC_E , KC_R , KC_T
-#define _________________QWERTY_L2_________________ KC_A , KC_S , KC_D , KC_F , KC_G
-#define _________________QWERTY_L3_________________ KC_Z , KC_X , KC_C , KC_V , KC_B
-
-#define _________________QWERTY_R1_________________ KC_Y , KC_U , KC_I , KC_O , KC_P
-#define _________________QWERTY_R2_________________ KC_H , KC_J , KC_K , KC_L , KC_SCLN
-#define _________________QWERTY_R3_________________ KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH
-
-#define _____________MOD_QWERTY_L2_________________ CTL_T(KC_A), SFT_T(KC_S), GUI_T(KC_D), ALT_T(KC_F), KC_G
-#define _____________MOD_QWERTY_R2_________________ KC_H , ALT_T(KC_J), GUI_T(KC_K), SFT_T(KC_L), CTL_T(KC_SCLN)
+#define GAME1 TO(LR_GAME1)
+#define GAME2 TO(LR_GAME2)
+
+#define SYMBOL MO(LR_SYMBOL)
+#define SYSCTL MO(LR_SYSCTL)
+#define KBCTL MO(LR_KBCTL)
+
+// Layout parts for easy reuse between keyboard keymaps.
+
+// Transparent.
+// ┌─────┬─────┬─────┬─────┬─────┐
+// │ │ │ │ │ │
+// └─────┴─────┴─────┴─────┴─────┘
+#define ___________________________________________ _______, _______, _______, _______, _______
+
+// Numbers.
+// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+// │ 1 │ 2 │ 3 │ 4 │ 5 │ │ 6 │ 7 │ 8 │ 9 │ 0 │
+// └─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘
+#define ________________NUMBERS_L__________________ KC_1, KC_2, KC_3, KC_4, KC_5
+#define ________________NUMBERS_R__________________ KC_6, KC_7, KC_8, KC_9, KC_0
+
+// F keys.
+// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+// │ F1 │ F2 │ F3 │ F4 │ F5 │ │ F6 │ F7 │ F8 │ F9 │ F10 │
+// └─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘
+#define ______________________F_L__________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5
+#define ______________________F_R__________________ KC_F6, KC_F7, KC_F8, KC_F9, KC_F10
+
+// QWERTY.
+// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+// │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │
+// ├─────┼─────┼─────╆━━━━━╅─────┤ ├─────╆━━━━━╅─────┼─────┼─────┤
+// │ A │ S │ D ┃ F ┃ G │ │ H ┃ J ┃ K │ L │ ; │
+// ├─────┼─────┼─────╄━━━━━╃─────┤ ├─────╄━━━━━╃─────┼─────┼─────┤
+// │ Z │ X │ C │ V │ B │ │ N │ M │ , │ . │ / │
+// └─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘
+#define _________________QWERTY_L1_________________ KC_Q, KC_W, KC_E, KC_R, KC_T
+#define _________________QWERTY_L2_________________ KC_A, KC_S, KC_D, KC_F, KC_G
+#define _________________QWERTY_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_B
+
+#define _________________QWERTY_R1_________________ KC_Y, KC_U, KC_I, KC_O, KC_P
+#define _________________QWERTY_R2_________________ KC_H, KC_J, KC_K, KC_L, KC_SCLN
+#define _________________QWERTY_R3_________________ KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH
+
+// QWERTY with mods.
+// ┌───────┬───────┬───────┲━━━━━━━┱───────┐ ┌───────┲━━━━━━━┱───────┬───────┬───────┐
+// │ ctl/A │ sft/S │ cmd/D ┃ opt/F ┃ G │ │ H ┃ opt/J ┃ cmd/K │ sft/L │ ctl/; │
+// └───────┴───────┴───────┺━━━━━━━┹───────┘ └───────┺━━━━━━━┹───────┴───────┴───────┘
+// #define _____________MOD_QWERTY_L2_________________ CTL_T(KC_A), SFT_T(KC_S), GUI_T(KC_D), ALT_T(KC_F), KC_G
+#define _____________MOD_QWERTY_L2_________________ KC_A, KC_S, KC_D, ALT_T(KC_F), KC_G
+#define _____________MOD_QWERTY_R2_________________ KC_H, ALT_T(KC_J), GUI_T(KC_K), SFT_T(KC_L), CTL_T(KC_SCLN)
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
// | Q | G | M | L | W | | Y | F | I | O | P |
@@ -88,13 +107,13 @@ enum {
// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
// | Z | X | C | V | J | | K | P | , | . | / |
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define ________________CARPALX_L1_________________ KC_Q , KC_G , KC_M , KC_L , KC_W
-#define ________________CARPALX_L2_________________ KC_D , KC_S , KC_T , KC_N , KC_R
-#define ________________CARPALX_L3_________________ KC_Z , KC_X , KC_C , KC_V , KC_J
+#define ________________CARPALX_L1_________________ KC_Q, KC_G, KC_M, KC_L, KC_W
+#define ________________CARPALX_L2_________________ KC_D, KC_S, KC_T, KC_N, KC_R
+#define ________________CARPALX_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_J
-#define ________________CARPALX_R1_________________ KC_Y , KC_F , KC_U , KC_B , KC_SCLN
-#define ________________CARPALX_R2_________________ KC_I , KC_A , KC_E , KC_O , KC_H
-#define ________________CARPALX_R3_________________ KC_K , KC_P , KC_COMM, KC_DOT , KC_SLSH
+#define ________________CARPALX_R1_________________ KC_Y, KC_F, KC_U, KC_B, KC_SCLN
+#define ________________CARPALX_R2_________________ KC_I, KC_A, KC_E, KC_O, KC_H
+#define ________________CARPALX_R3_________________ KC_K, KC_P, KC_COMM, KC_DOT, KC_SLSH
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
// | ! | @ | { | } | _ | | \ | | ` | | |
@@ -103,50 +122,51 @@ enum {
// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
// | % | ^ | [ | ] | + | | * | ~ | < | > | / |
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define _________________SYMBOL_L1_________________ KC_EXLM, KC_AT , KC_LCBR, KC_RCBR, KC_UNDS
-#define _________________SYMBOL_L2_________________ KC_HASH, KC_DLR , KC_LPRN, KC_RPRN, KC_MINS
-#define _________________SYMBOL_L3_________________ KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_PLUS
-
-#define _________________SYMBOL_R1_________________ KC_BSLS, _______, KC_GRV , _______, _______
-#define _________________SYMBOL_R2_________________ KC_EQL , KC_AMPR, KC_QUOT, KC_DQUO, KC_PIPE
-#define _________________SYMBOL_R3_________________ KC_ASTR, KC_TILD, KC_LABK, KC_RABK, KC_SLSH
-
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-// | | | | | | |MUTE |HOME | ^ | END | |
-// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
-// | | | | | | |VOLUP| < | v | > | |
-// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
-// | | | | | | |VOLDN|MPREV|MPLAY|MNEXT| |
-// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define _________________SYSCTL_L1_________________
-#define _________________SYSCTL_L2_________________
-#define _________________SYSCTL_L3_________________
+#define _________________SYMBOL_L1_________________ KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_UNDS
+#define _________________SYMBOL_L2_________________ KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_MINS
+#define _________________SYMBOL_L3_________________ KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_PLUS
+
+#define _________________SYMBOL_R1_________________ KC_BSLS, _______, KC_GRV, _______, _______
+#define _________________SYMBOL_R2_________________ KC_EQL, KC_AMPR, KC_QUOT, KC_DQUO, KC_PIPE
+#define _________________SYMBOL_R3_________________ KC_ASTR, KC_TILD, KC_LABK, KC_RABK, KC_SLSH
+
+// System Control.
+// vol ↓ ctl ↓
+// ┌─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┐
+// │ │ │ │ │ │ │MUTE │HOME │ ↑ │ END │LOCK │
+// ├─────┼─────┼─────╆━━━━━╅─────┤ ├─────╆━━━━━╅─────┼─────┼─────┤
+// │ │ │ ┃ ┃ │ │VOLUP┃ ← ┃ ↓ │ → │SLEEP│ ← arrows
+// ├─────┼─────┼─────╄━━━━━╃─────┤ ├─────╄━━━━━╃─────┼─────┼─────┤
+// │ │ │ │ │ │ │VOLDN│MPREV│MPLAY│MNEXT│ PWR │ ← music
+// └─────┴─────┴─────┴─────┴─────┘ └─────┴─────┴─────┴─────┴─────┘
+#define _________________SYSCTL_L1_________________ XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_BTN1, XXXXXXX
+#define _________________SYSCTL_L2_________________ XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_RIGHT, KC_MS_WH_UP
+#define _________________SYSCTL_L3_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_WH_DOWN
// vol v ctl v
-#define _________________SYSCTL_R1_________________ KC_MUTE , KC_HOME , KC_UP , KC_END , PV_LOCK
-#define _________________SYSCTL_R2_________________ KC_VOLU , KC_LEFT , KC_DOWN , KC_RGHT /* < arrows */ , KC_SLEP
-#define _________________SYSCTL_R3_________________ KC_VOLD , KC_MPRV , KC_MPLY , KC_MNXT /* < music */ , KC_PWR
+#define _________________SYSCTL_R1_________________ KC_MUTE, KC_HOME, KC_UP, KC_END, PV_LOCK
+#define _________________SYSCTL_R2_________________ KC_VOLU, KC_LEFT, KC_DOWN, KC_RGHT /* < arrows */, KC_SLEP
+#define _________________SYSCTL_R3_________________ KC_VOLD, KC_MPRV, KC_MPLY, KC_MNXT /* < music */, KC_PWR
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-// |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX| |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX|
+// |GAME |CRPLX|XXXXX|XXXXX|XXXXX| |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX|
// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
// |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX| |XXXXX|VERSN|MAKE |FLASH|XXXXX|
// ,-----+-----+-----x-----x-----, ,-----x-----x-----+-----+-----,
// |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX| |XXXXX|XXXXX|XXXXX|XXXXX|XXXXX|
// ,-----+-----+-----+-----+-----, ,-----+-----+-----+-----+-----,
-#define __________________KBCTL_L1_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
-#define __________________KBCTL_L2_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
-#define __________________KBCTL_L3_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
-
-#define __________________KBCTL_R1_________________ XXXXXXX, XXXXXXX, XXXXXXX, PV_KTMR, XXXXXXX
-#define __________________KBCTL_R2_________________ XXXXXXX, PV_VRSN, PV_MAKE, PV_FLSH, XXXXXXX
-#define __________________KBCTL_R3_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+#define __________________KBCTL_L1_________________ PV_SSNC, PV_SCIN, PV_TEST, XXXXXXX, XXXXXXX
+#define __________________KBCTL_L2_________________ RGB_TOG, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX
+#define __________________KBCTL_L3_________________ RGB_MOD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX
-// we need wrappers in order for these definitions, because they need to be expanded before being used as arguments to the LAYOUT_xxx macro
-#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__)
-#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
+#define __________________KBCTL_R1_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+#define __________________KBCTL_R2_________________ XXXXXXX, PV_VRSN, PV_MAKE, PV_FLSH, XXXXXXX
+#define __________________KBCTL_R3_________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+// We need wrappers in order for these definitions, because they need to be expanded before being used as arguments to the LAYOUT_xxx macro.
+#define LAYOUT_ergodox_pretty_wrapper(...) LAYOUT_ergodox_pretty(__VA_ARGS__)
+#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
-// extra stuff that might be needed
-void keyboard_post_init_user_local(void);
-uint32_t layer_state_set_user_local(uint32_t state);
+// Extra stuff that might be needed.
+void keyboard_post_init_user_keymap(void);
+uint32_t layer_state_set_user_keymap(uint32_t state);
diff --git a/users/pvinis/rules.mk b/users/pvinis/rules.mk
index da10cc743..f6f09e54d 100644
--- a/users/pvinis/rules.mk
+++ b/users/pvinis/rules.mk
@@ -1,15 +1,19 @@
-# add userspace file
-SRC += pvinis.c
-
-AUDIO_ENABLE = no # piezo speaker sounds
-RGBLIGHT_ENABLE = no # rgb leds underlight
-TAP_DANCE_ENABLE = yes
-BACKLIGHT_ENABLE = no # leds under keycaps
-#MOUSEKEY_ENABLE = no
-#SLEEP_LED_ENABLE = no # no led blinking while sleeping
-#NKRO_ENABLE = yes
-
-# make firmware smaller
-LINK_TIME_OPTIMIZATION_ENABLE = yes
-CONSOLE_ENABLE = no
-COMMAND_ENABLE = no
+SRC += pvinis.c # add userspace file
+
+
+## Use the stuff below on the keyboard keymaps, not here.
+## If they are used here, they will replace the keymap's rules, since this file is eval'd later.
+
+# TAP_DANCE_ENABLE = yes
+# AUDIO_ENABLE = yes # piezo speaker sounds
+# RGBLIGHT_ENABLE = yes # rgb leds underlight
+# BACKLIGHT_ENABLE = no # leds under keycaps
+# MOUSEKEY_ENABLE = yes
+# LEEP_LED_ENABLE = no # no led blinking while sleeping
+# KRO_ENABLE = yes
+
+## Some extra stuff to make firmware smaller.
+
+# LINK_TIME_OPTIMIZATION_ENABLE = yes
+# CONSOLE_ENABLE = no
+# COMMAND_ENABLE = no
diff --git a/users/spidey3/init.c b/users/spidey3/init.c
index a4be6113f..b92394609 100644
--- a/users/spidey3/init.c
+++ b/users/spidey3/init.c
@@ -1,15 +1,15 @@
#include "spidey3.h"
void keyboard_post_init_user(void) {
- print("SPIDEY3: keyboard_post_init_user\n");
- uprintf(" debug_enable=%u\n", debug_enable);
+ print("keyboard_post_init_user\n");
+ uprintf("\tdebug_enable=%u\n", debug_enable);
#ifdef RGBLIGHT_ENABLE
keyboard_post_init_user_rgb();
#endif
}
void eeconfig_init_user(void) {
- print("SPIDEY3: eeconfig_init_user\n");
+ print("eeconfig_init_user\n");
set_single_persistent_default_layer(_BASE);
#ifdef UNICODEMAP_ENABLE
eeconfig_init_user_unicode();
@@ -19,3 +19,12 @@ void eeconfig_init_user(void) {
eeconfig_init_user_rgb();
#endif
}
+
+void shutdown_user() {
+#ifdef RGBLIGHT_ENABLE
+ clear_rgb_layers();
+ rgblight_enable();
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
+ rgblight_sethsv_noeeprom(HSV_RED);
+#endif
+}
diff --git a/users/spidey3/layer_rgb.c b/users/spidey3/layer_rgb.c
index d80eb20a3..75e66384e 100644
--- a/users/spidey3/layer_rgb.c
+++ b/users/spidey3/layer_rgb.c
@@ -10,7 +10,7 @@ uint8_t rgb_val;
bool rgb_saved = 0;
void spidey_swirl(void) {
- dprint("SPIDEY3: Setting Spidey Swirl!\n");
+ dprint("Setting Spidey Swirl!\n");
rgblight_enable();
rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
rgblight_sethsv(213, 255, 128);
@@ -27,54 +27,104 @@ void eeconfig_init_user_rgb(void)
const rgblight_segment_t PROGMEM _capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS( {0, 2, HSV_AZURE}, {14, 2, HSV_AZURE} );
const rgblight_segment_t PROGMEM _layer1_layer[] = RGBLIGHT_LAYER_SEGMENTS( {7, 1, HSV_PURPLE} );
-const rgblight_segment_t PROGMEM _layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 2, HSV_GREEN} );
+const rgblight_segment_t PROGMEM _layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS( {10, 3, HSV_MAGENTA} );
+const rgblight_segment_t PROGMEM _layer3_layer[] = RGBLIGHT_LAYER_SEGMENTS( {10, 1, HSV_GREEN} );
+const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_GREEN} );
+const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_RED} );
// Now define the array of layers. Later layers take precedence
-const rgblight_segment_t* const PROGMEM _rgb_layers[] = RGBLIGHT_LAYERS_LIST( _capslock_layer, _layer1_layer, _layer2_layer );
+const rgblight_segment_t* const PROGMEM _rgb_layers[] =
+ RGBLIGHT_LAYERS_LIST( _capslock_layer, _layer1_layer, _layer2_layer, _layer3_layer, _yes_layer, _no_layer );
const uint8_t PROGMEM _n_rgb_layers = sizeof(_rgb_layers) / sizeof(_rgb_layers[0]) - 1;
+void clear_rgb_layers() {
+ for (uint8_t i=0; i<_n_rgb_layers; i++) {
+ rgblight_set_layer_state(i, false);
+ }
+}
+
void do_rgb_layers(layer_state_t state, uint8_t start, uint8_t end) {
- dprint("SPIDEY3: do_rgb_layers()\n");
- for (uint8_t i=start; i<end; i++) {
+ dprint("do_rgb_layers()\n");
+ for (uint8_t i=start; i<end; i++) {
bool is_on = layer_state_cmp(state, i);
- dprintf(" layer[%d]=%u\n", i, is_on);
+ dprintf("\tlayer[%d]=%u\n", i, is_on);
rgblight_set_layer_state(i, is_on);
}
}
void keyboard_post_init_user_rgb(void) {
do_rgb_layers(default_layer_state, 1u, RGB_LAYER_BASE_REGULAR);
- do_rgb_layers(layer_state, RGB_LAYER_BASE_REGULAR, _n_rgb_layers);
+ do_rgb_layers(layer_state, RGB_LAYER_BASE_REGULAR, RGB_LAYER_BASE_ACKS);
+ do_rgb_layers(0, RGB_LAYER_BASE_ACKS, _n_rgb_layers);
// Enable the LED layers
rgblight_layers = _rgb_layers;
}
layer_state_t default_layer_state_set_user_rgb(layer_state_t state) {
- dprint("SPIDEY3: default_layer_state_set_user_rgb()\n");
+ dprint("default_layer_state_set_user_rgb()\n");
do_rgb_layers(state, 1u, RGB_LAYER_BASE_REGULAR);
return state;
}
layer_state_t layer_state_set_user_rgb(layer_state_t state) {
- dprint("SPIDEY3: layer_state_set_user_rgb()\n");
- do_rgb_layers(state, RGB_LAYER_BASE_REGULAR, _n_rgb_layers);
+ dprint("layer_state_set_user_rgb()\n");
+ do_rgb_layers(state, RGB_LAYER_BASE_REGULAR, RGB_LAYER_BASE_ACKS);
return state;
}
bool led_update_user_rgb(led_t led_state) {
- dprintf("SPIDEY3: caps_lock=%u\n", led_state.caps_lock);
+ dprintf("caps_lock=%u\n", led_state.caps_lock);
rgblight_set_layer_state(0, led_state.caps_lock);
return true;
}
+void rgb_layer_ack(bool yn, bool pressed) {
+ uint8_t layer = RGB_LAYER_BASE_ACKS + (yn ? 0 : 1);
+ rgblight_set_layer_state(layer, pressed);
+}
+
+extern keymap_config_t keymap_config;
+
bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
+ bool pressed = record->event.pressed;
switch (keycode) {
case SPI_GLO:
- if (record->event.pressed) {
+ if (pressed) {
spidey_swirl();
}
- break;
+ return false;
+
+ // Acks follow...
+ case DEBUG:
+ rgb_layer_ack(debug_enable, pressed);
+ return false;
+
+ case SPI_LNX:
+ case SPI_OSX:
+ case SPI_WIN:
+ rgb_layer_ack(true, pressed);
+ return false;
+
+ // Tricky!
+ // For these, on press the toggle hasn't happened yet,
+ // so we need a little logic to invert, assuming that
+ // on key press the flag WILL be toggled, and on key
+ // release the flag has already been toggled.
+
+#ifdef VELOCIKEY_ENABLE
+ case VLK_TOG:
+ rgb_layer_ack(pressed != velocikey_enabled(), pressed);
+ return true;
+#endif
+
+#ifdef NKRO_ENABLE
+ case NK_TOGG:
+ case NK_ON:
+ case NK_OFF:
+ rgb_layer_ack(pressed != keymap_config.nkro, pressed);
+ return true;
+#endif
}
return true;
diff --git a/users/spidey3/spidey3.c b/users/spidey3/spidey3.c
index d0b794704..8be99dea0 100644
--- a/users/spidey3/spidey3.c
+++ b/users/spidey3/spidey3.c
@@ -20,39 +20,39 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
eeconfig_update_debug(debug_config.raw);
#endif
- return false;
+ break;
case SPI_LNX:
- dprint("SPIDEY3: SPI_LNX\n");
+ dprint("SPI_LNX\n");
set_single_persistent_default_layer(_BASE);
layer_off(_OSX);
#if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE)
set_unicode_input_mode(UC_LNX);
#endif
- return false;
+ break;
case SPI_OSX:
- dprint("SPIDEY3: SPI_OSX\n");
+ dprint("SPI_OSX\n");
set_single_persistent_default_layer(_OSX);
#if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE)
set_unicode_input_mode(UC_OSX);
#endif
- return false;
+ break;
case SPI_WIN:
- dprint("SPIDEY3: SPI_WIN\n");
+ dprint("SPI_WIN\n");
set_single_persistent_default_layer(_BASE);
layer_off(_OSX);
#if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE)
set_unicode_input_mode(UC_WINC);
#endif
- return false;
+ break;
}
}
#ifdef RGBLIGHT_ENABLE
bool res = process_record_user_rgb(keycode, record);
- if (!res) return false;
+ if (res) return true;
#endif
- return true;
+ return false;
}
layer_state_t default_layer_state_set_user(layer_state_t state) {
diff --git a/users/spidey3/spidey3.h b/users/spidey3/spidey3.h
index 125f70a9a..224858391 100644
--- a/users/spidey3/spidey3.h
+++ b/users/spidey3/spidey3.h
@@ -9,12 +9,14 @@
enum userspace_layers {
_BASE = 0,
_OSX,
+ _NUMPAD,
_FN,
};
enum rgb_base_layer {
RGB_LAYER_BASE_DEFAULT = _BASE,
- RGB_LAYER_BASE_REGULAR = _FN,
+ RGB_LAYER_BASE_REGULAR = _NUMPAD,
+ RGB_LAYER_BASE_ACKS = _FN+1,
};
enum custom_keycodes {
@@ -32,6 +34,7 @@ bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record);
layer_state_t layer_state_set_user_rgb(layer_state_t state);
layer_state_t default_layer_state_set_user_rgb(layer_state_t state);
bool led_update_user_rgb(led_t led_state);
+void clear_rgb_layers(void);
#endif
#ifdef UNICODEMAP_ENABLE
diff --git a/users/stanrc85/config.h b/users/stanrc85/config.h
index 42306727c..fba488e1c 100644
--- a/users/stanrc85/config.h
+++ b/users/stanrc85/config.h
@@ -4,6 +4,7 @@
#define RETRO_TAPPING
#ifdef RGBLIGHT_ENABLE
+ #define RGBLIGHT_LAYERS
#define RGBLIGHT_LIMIT_VAL 175
#define RGBLIGHT_SLEEP
#endif
diff --git a/users/stanrc85/rgblight_layers.c b/users/stanrc85/rgblight_layers.c
new file mode 100644
index 000000000..0363e358b
--- /dev/null
+++ b/users/stanrc85/rgblight_layers.c
@@ -0,0 +1,47 @@
+#include "stanrc85.h"
+
+const rgblight_segment_t PROGMEM my_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {3, 2, HSV_RED},
+ {10, 2, HSV_RED}
+);
+
+const rgblight_segment_t PROGMEM my_layer1_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {3, 1, HSV_GREEN},
+ {11, 1, HSV_GREEN}
+);
+
+const rgblight_segment_t PROGMEM my_layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {3, 1, HSV_BLUE},
+ {11, 1, HSV_BLUE}
+);
+
+const rgblight_segment_t PROGMEM my_layer3_layer[] = RGBLIGHT_LAYER_SEGMENTS(
+ {3, 1, HSV_WHITE},
+ {11, 1, HSV_WHITE}
+);
+
+// Now define the array of layers. Later layers take precedence
+const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
+ my_capslock_layer,
+ my_layer1_layer,
+ my_layer2_layer,
+ my_layer3_layer
+);
+
+void keyboard_post_init_user(void) {
+ // Enable the LED layers
+ rgblight_layers = my_rgb_layers;
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ // Both layers will light up if both kb layers are active
+ rgblight_set_layer_state(1, layer_state_cmp(state, 1));
+ rgblight_set_layer_state(2, layer_state_cmp(state, 2));
+ rgblight_set_layer_state(3, layer_state_cmp(state, 3));
+ return state;
+}
+
+bool led_update_user(led_t led_state) {
+ rgblight_set_layer_state(0, led_state.caps_lock);
+ return true;
+} \ No newline at end of file
diff --git a/users/stanrc85/rules.mk b/users/stanrc85/rules.mk
index 16391b555..d544b2d95 100644
--- a/users/stanrc85/rules.mk
+++ b/users/stanrc85/rules.mk
@@ -10,20 +10,18 @@ NKRO_ENABLE = no
SRC += stanrc85.c
-ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
- # Include my fancy rgb functions source here
- SRC += layer_rgb.c
-endif
-
ifeq ($(strip $(KEYBOARD)), 1upkeyboards/1up60hse)
+ SRC += layer_rgb.c
VIA_ENABLE = yes
LTO_ENABLE = yes
endif
ifeq ($(strip $(KEYBOARD)), dz60)
+ SRC += layer_rgb.c
VIA_ENABLE = yes
LTO_ENABLE = yes
endif
-ifeq ($(strip $(KEYBOARD)), projectkb/alice)
+ifeq ($(strip $(KEYBOARD)), projectkb/alice/rev1)
+ SRC += rgblight_layers.c
VIA_ENABLE = yes
LTO_ENABLE = no
endif \ No newline at end of file
diff --git a/users/yanfali/rules.mk b/users/yanfali/rules.mk
index a4f1092d0..456d3bf32 100644
--- a/users/yanfali/rules.mk
+++ b/users/yanfali/rules.mk
@@ -25,3 +25,7 @@ endif
ifeq ($(strip $(KEYBOARD)), kbdfans/kbd75/rev1)
COMMAND_ENABLE = no
endif
+
+ifeq ($(strip $(KEYBOARD)), ai03/polaris)
+ RGBLIGHT_ENABLE = no
+endif
diff --git a/users/yanfali_wkl b/users/yanfali_wkl
new file mode 120000
index 000000000..491d08e43
--- /dev/null
+++ b/users/yanfali_wkl
@@ -0,0 +1 @@
+yanfali \ No newline at end of file
diff --git a/util/1-setup-path-win.bat b/util/1-setup-path-win.bat
deleted file mode 100644
index 699aee215..000000000
--- a/util/1-setup-path-win.bat
+++ /dev/null
@@ -1,66 +0,0 @@
-@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
-@ECHO OFF
-SET CMDLINERUNSTR=%SystemRoot%\system32\cmd.exe
-
-DEL script1.log > NUL 2>&1
-DEL add-paths.log > NUL 2>&1
-DEL add-paths-detail.log > NUL 2>&1
-DEL UPDATE > NUL 2>&1
-
-ELEVATE -wait add-paths.bat >> script1.log 2>&1
-
-IF ERRORLEVEL 1 (
- ECHO You denied admin access. Rerun the script, and be sure to press the yes button this time.
-) ELSE (
- TYPE add-paths.log 2> NUL
-)
-ECHO.
-
-:: Branch to UpdateEnv if we need to update
-IF EXIST UPDATE (
- DEL UPDATE
- GOTO UpdateEnv
-)
-
-GOTO ExitBatch
-
-:: -----------------------------------------------------------------------------
-
-:UpdateEnv
-ECHO Making updated PATH go live . . .
-REG delete HKCU\Environment /F /V TEMPVAR > NUL 2>&1
-setx TEMPVAR 1 > NUL
-REG delete HKCU\Environment /F /V TEMPVAR > NUL 2>&1
-IF NOT !cmdcmdline! == !CMDLINERUNSTR! (CALL :KillExplorer)
-GOTO ExitBatch
-
-:: -----------------------------------------------------------------------------
-
-:ExitBatch
-ENDLOCAL
-PAUSE
-EXIT /b
-
-:: -----------------------------------------------------------------------------
-
-:KillExplorer
-ECHO.
-ECHO.
-ECHO Your desktop will be restarted.
-ECHO.
-ECHO All file explorer windows except for the one you launched this script from WILL BE CLOSED.
-ECHO.
-ECHO Press enter when ready, or close this window if you would rather do a full restart of your computer at a later time.
-ECHO.
-PAUSE
-ping -n 5 127.0.0.1 > NUL 2>&1
-ECHO Killing process Explorer.exe. . .
-ECHO.
-taskkill /f /im explorer.exe > NUL
-ECHO.
-ECHO Your desktop is now loading. . .
-ECHO.
-ping -n 5 127.0.0.1 > NUL 2>&1
-START explorer.exe
-START explorer.exe %CD%
-EXIT /b \ No newline at end of file
diff --git a/util/2-setup-environment-win.bat b/util/2-setup-environment-win.bat
deleted file mode 100644
index 22a2e17f7..000000000
--- a/util/2-setup-environment-win.bat
+++ /dev/null
@@ -1,72 +0,0 @@
-@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
-@ECHO OFF
-
-CD %~dp0
-
-SET STARTINGDIR=%CD%
-echo %STARTINGDIR%
-
-:: Check for admin privilages
-SETX /M test test > nul 2>&1
-IF NOT ["%ERRORLEVEL%"]==["0"] (
- ELEVATE -wait 2-setup-environment-win.bat & goto :EOF
-)
-
-DEL %STARTINGDIR%\environment-setup.log
-
-:: Make sure path to MinGW exists - if so, CD to it
-SET MINGWPATH="C:\MinGW\bin"
-IF NOT EXIST !MINGWPATH! (ECHO Path not found: %MINGWPATH%. Did you install MinGW to the default location? && GOTO ExitBatch)
-CD /D %MINGWPATH%
-
-ECHO.
-ECHO ------------------------------------------
-ECHO Installing wget and unzip
-ECHO ------------------------------------------
-ECHO.
-mingw-get install msys-wget-bin msys-unzip-bin
-
-MKDIR temp
-CD temp
-
-ECHO.
-ECHO ------------------------------------------
-ECHO Installing dfu-programmer.
-ECHO ------------------------------------------
-ECHO.
-wget --no-check-certificate 'http://downloads.sourceforge.net/project/dfu-programmer/dfu-programmer/0.7.2/dfu-programmer-win-0.7.2.zip' >> %STARTINGDIR%\environment-setup.log
-unzip -o dfu-programmer-win-0.7.2.zip >> %STARTINGDIR%\environment-setup.log
-COPY dfu-programmer.exe .. >> %STARTINGDIR%\environment-setup.log
-
-ECHO ------------------------------------------
-ECHO Downloading driver
-ECHO ------------------------------------------
-wget --no-check-certificate http://downloads.sourceforge.net/project/libusb-win32/libusb-win32-releases/1.2.6.0/libusb-win32-bin-1.2.6.0.zip >> %STARTINGDIR%\environment-setup.log
-unzip -o libusb-win32-bin-1.2.6.0.zip >> %STARTINGDIR%\environment-setup.log
-COPY libusb-win32-bin-1.2.6.0\bin\x86\libusb0_x86.dll ../libusb0.dll >> %STARTINGDIR%\environment-setup.log
-
-ECHO.
-ECHO ------------------------------------------
-ECHO Installing driver. Accept prompt.
-ECHO ------------------------------------------
-ECHO.
-IF EXIST "%WinDir%\System32\PnPUtil.exe" (%WinDir%\System32\PnPUtil.exe -i -a dfu-prog-usb-1.2.2\atmel_usb_dfu.inf && GOTO PNPUTILFOUND)
-IF EXIST "%WinDir%\Sysnative\PnPUtil.exe" (%WinDir%\Sysnative\PnPUtil.exe -i -a dfu-prog-usb-1.2.2\atmel_usb_dfu.inf && GOTO PNPUTILFOUND)
-
-ECHO FAILED. Could not find PnPUtil.exe in "%WinDir%\System32" or "%WinDir%\Sysnative".
-
-:PNPUTILFOUND
-
-:: Wait then delete directory
-ping -n 5 127.0.0.1 > NUL 2>&1
-CD ..
-RD /s /q temp
-
-ECHO ------------------------------------------
-ECHO Finished!
-
-:ExitBatch
-CD /D %STARTINGDIR%
-ENDLOCAL
-PAUSE
-EXIT /b \ No newline at end of file
diff --git a/util/ELEVATE_LICENSE.md b/util/ELEVATE_LICENSE.md
deleted file mode 100644
index 1cf4fda91..000000000
--- a/util/ELEVATE_LICENSE.md
+++ /dev/null
@@ -1,25 +0,0 @@
-Elevate was downloaded from [here](https://jpassing.com/2007/12/08/launch-elevated-processes-from-the-command-line/).
-
-### LICENSE
-
-The MIT License (MIT)
-
-Copyright (c) <year> <copyright holders>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE. \ No newline at end of file
diff --git a/util/Win_Check.bat b/util/Win_Check.bat
deleted file mode 100644
index 3fdb656f9..000000000
--- a/util/Win_Check.bat
+++ /dev/null
@@ -1,208 +0,0 @@
-@setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
-@echo OFF
-set BAT_VERSION=v1.0
-set REPORT_NAME=Win_Check_Output.txt
-
-:: -----------------------------------------------------------------------------
-
-cls
-
-echo QMK Windows Check Output %BAT_VERSION%
-echo QMK Windows Check Output %BAT_VERSION%.>%REPORT_NAME%
-
-:: -----------------------------------------------------------------------------
-
-set MINGW_BASE_DIR=C:\MinGW
-
-set KEYMAP=atomic-pvc
-set KEYMAP_CLEAN=atomic-pvc-clean
-
-:: -----------------------------------------------------------------------------
-
-if /I "%1" EQU VERBOSE (goto :Verbose_Make) else (goto :Normal_Make)
-
-:Normal_Make
-set MAKE_CMD_LEVEL_0=make -r -f Makefile COLOR=FALSE
-set MAKE_CMD_LEVEL_1=make -r -f ../Makefile COLOR=FALSE
-set MAKE_CMD_LEVEL_2=make -r -f ../../Makefile COLOR=FALSE
-goto :Start_Report
-
-:Verbose_Make
-echo Verbose Mode
-set MAKE_CMD_LEVEL_0=make -r -d -f Makefile COLOR=FALSE VERBOSE=TRUE
-set MAKE_CMD_LEVEL_1=make -r -d -f ../Makefile COLOR=FALSE VERBOSE=TRUE
-set MAKE_CMD_LEVEL_2=make -r -d -f ../../Makefile COLOR=FALSE VERBOSE=TRUE
-goto :Start_Report
-
-:Start_Report
-
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=CURRENT DIRECTORY & call :ReportHeader
-
-echo %CD%>>%REPORT_NAME% 2>&1
-
-echo.>>%REPORT_NAME% 2>&1
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=CURRENT PATHS & call :ReportHeader
-
-for %%A in ("%path:;=";"%") do (echo %%~A>>%REPORT_NAME% 2>&1)
-
-echo.>>%REPORT_NAME% 2>&1
-
-:: -----------------------------------------------------------------------------
-
-rem set HEADER=CURRENT ENVIRONMENTAL SETTINGS & call :ReportHeader
-
-rem set>>%REPORT_NAME% 2>&1
-rem echo.>>%REPORT_NAME% 2>&1
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=KEY EXECUTABLE LOCATIONS - GENERAL & call :ReportHeader
-
-set FILENAME=make.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU Make" & call :ReportVersion
-set FILENAME=git.exe & set VERSION_CMD=--version & set VERSION_FIND="git" & call :ReportVersion
-set FILENAME=cmp.exe & set VERSION_CMD=--version & set VERSION_FIND="cmp" & call :ReportVersion
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=EXECUTABLE LOCATIONS - AVR MCU COMPILERS & call :ReportHeader
-
-set FILENAME=avr-gcc.exe & set VERSION_CMD=--version & set VERSION_FIND="avr" & call :ReportVersion
-set FILENAME=avr-objcopy.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objcopy" & call :ReportVersion
-set FILENAME=avr-objdump.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objdump" & call :ReportVersion
-set FILENAME=avr-size.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU size" & call :ReportVersion
-set FILENAME=avr-ar.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU ar" & call :ReportVersion
-set FILENAME=avr-nm.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU nm" & call :ReportVersion
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=EXECUTABLE LOCATIONS - ARM MCU COMPILERS & call :ReportHeader
-
-set FILENAME=arm-none-eabi-gcc.exe & set VERSION_CMD=--version & set VERSION_FIND="arm-none-eabi-gcc" & call :ReportVersion
-set FILENAME=arm-none-eabi-objcopy.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objcopy" & call :ReportVersion
-set FILENAME=arm-none-eabi-objdump.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objdump" & call :ReportVersion
-set FILENAME=arm-none-eabi-size.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU size" & call :ReportVersion
-set FILENAME=arm-none-eabi-ar.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU ar" & call :ReportVersion
-set FILENAME=arm-none-eabi-nm.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU nm" & call :ReportVersion
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=EXECUTABLE LOCATIONS - NATIVE COMPILERS & call :ReportHeader
-
-set FILENAME=gcc.exe & set VERSION_CMD=--version & set VERSION_FIND="gcc" & call :ReportVersion
-set FILENAME=objcopy.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objcopy" & call :ReportVersion
-set FILENAME=objdump.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU objdump" & call :ReportVersion
-set FILENAME=size.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU size" & call :ReportVersion
-set FILENAME=ar.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU ar" & call :ReportVersion
-set FILENAME=nm.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU nm" & call :ReportVersion
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=EXECUTABLE LOCATIONS - PROGRAMMERS & call :ReportHeader
-
-set FILENAME=dfu-programmer.exe & set VERSION_CMD=--version & set VERSION_FIND="dfu" & call :ReportVersion
-set FILENAME=batchisp.exe & set VERSION_CMD=-version & set VERSION_FIND="batchisp" & call :ReportVersion
-set FILENAME=dfu-util.exe & call :Report
-set FILENAME=teensy_loader_cli.exe & call :Report
-set FILENAME=hid_bootloader_cli.exe & call :Report
-set FILENAME=avrdude.exe & call :Report
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=EXECUTABLE LOCATIONS - OPTIONAL & call :ReportHeader
-set FILENAME=cppcheck.exe & call :Report
-set FILENAME=doxygen.exe & call :Report
-set FILENAME=gdb-config.exe & call :Report
-set FILENAME=wget.exe & call :Report
-set FILENAME=unzip.exe & call :Report
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=MINGW CHECK - OPTIONAL & call :ReportHeader
-if exist %MINGW_BASE_DIR% (echo Expected MinGW Base Dir = %MINGW_BASE_DIR%>>%REPORT_NAME% 2>&1) else (echo Expected MinGW Base Dir = %MINGW_BASE_DIR% - Not Found>>%REPORT_NAME% 2>&1)
-echo.>>%REPORT_NAME% 2>&1
-set FILENAME=mingw32-make.exe & set VERSION_CMD=--version & set VERSION_FIND="GNU Make" & call :ReportVersion
-if exist %MINGW_BASE_DIR%\bin\make.exe (ECHO It is not recommended to have make.exe in mingw/bin.>>%REPORT_NAME% 2>&1 & echo.>>%REPORT_NAME% 2>&1)
-
-:: -----------------------------------------------------------------------------
-
-set HEADER=MAKE CHECK & call :ReportHeader
-if exist Makefile (set MAKE_CMD=%MAKE_CMD_LEVEL_0% & goto MakeFound)
-if exist ..\Makefile (set MAKE_CMD=%MAKE_CMD_LEVEL_1% & goto MakeFound)
-if exist ..\..\Makefile (set MAKE_CMD=%MAKE_CMD_LEVEL_2% & goto MakeFound)
-
-echo No Makfile Found.>>%REPORT_NAME% 2>&1
-echo.>>%REPORT_NAME% 2>&1
-echo ------------------------------------------------------------------------->>%REPORT_NAME% 2>&1
-
-goto :ContinueAfterMake
-
-:MakeFound
-call :RunMake
-
-:ContinueAfterMake
-goto :ExitBatch
-
-:ExitBatch
- echo Done!
- echo.
- rem type %REPORT_NAME%
- echo.
- echo See %REPORT_NAME% for the report.
- endlocal
-exit /b
-
-:: -----------------------------------------------------------------------------
-
-:RunMake
-
- echo Makfile Found.>>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
- set HEADER=MAKE CLEAN & call :ReportHeader
- echo Make Command = %MAKE_CMD% %KEYMAP_CLEAN%>>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
- %MAKE_CMD% %KEYMAP_CLEAN%>>%REPORT_NAME% 2>&1
- set HEADER=MAKE & call :ReportHeader
- echo Make Command = %MAKE_CMD% %KEYMAP%>>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
- %MAKE_CMD% %KEYMAP%>>%REPORT_NAME% 2>&1
- echo ------------------------------------------------------------------------->>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
-exit /b
-
-:ReportHeader
- echo ------------------------------------------------------------------------->>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
- echo %HEADER%>>%REPORT_NAME% 2>&1
- echo.>>%REPORT_NAME% 2>&1
-exit /b
-
-:Report
- echo Filename = %FILENAME% >>%REPORT_NAME% 2>&1
- <nul set /p output="Location = " >>%REPORT_NAME% 2>&1
- where %FILENAME% >>%REPORT_NAME% 2> NUL
- if ERRORLEVEL 1 (echo Not Found >>%REPORT_NAME% 2>&1 & goto :EndReport)
-
- :EndReport
- echo.>>%REPORT_NAME% 2>&1
- <nul set /p output="."
-exit /b
-
-:ReportVersion
- echo Filename = %FILENAME% >>%REPORT_NAME% 2>&1
- <nul set /p output="Location = " >>%REPORT_NAME% 2>&1
- where %FILENAME% >>%REPORT_NAME% 2> NUL
- if ERRORLEVEL 1 (echo Not Found >>%REPORT_NAME% 2>&1 & goto :EndReportVersion)
- <nul set /p output ="Version = " >>%REPORT_NAME% 2>&1
-
- (%FILENAME% %VERSION_CMD% | find %VERSION_FIND%) >>%REPORT_NAME% 2>&1
-
- :EndReportVersion
- echo.>>%REPORT_NAME% 2>&1
- <nul set /p output="."
-exit /b \ No newline at end of file
diff --git a/util/activate_msys2.sh b/util/activate_msys2.sh
index 07888ffe1..8741cc6b0 100755
--- a/util/activate_msys2.sh
+++ b/util/activate_msys2.sh
@@ -6,7 +6,6 @@ function export_variables {
export PATH=$PATH:$util_dir/dfu-programmer
export PATH=$PATH:$util_dir/dfu-util-0.9-win64
export PATH=$PATH:$util_dir/bootloadHID.2012-12-08/commandline
- export PATH=$PATH:$util_dir/flip/bin
export PATH=$PATH:$util_dir/avr8-gnu-toolchain/bin
export PATH=$PATH:$util_dir/gcc-arm-none-eabi/bin
}
diff --git a/util/activate_wsl.sh b/util/activate_wsl.sh
index 78bbf9ccb..26a47187a 100755
--- a/util/activate_wsl.sh
+++ b/util/activate_wsl.sh
@@ -8,7 +8,6 @@ function export_variables {
export DFU_UTIL=$download_dir/dfu-util-0.9-win64/dfu-util.exe
export TEENSY_LOADER_CLI=$download_dir/teensy_loader_cli.exe
export BOOTLOADHID_PROGRAMMER=$download_dir/bootloadHID.2012-12-08/commandline/bootloadHID.exe
- export BATCHISP=batchisp.exe
}
export_variables
diff --git a/util/add-paths.bat b/util/add-paths.bat
deleted file mode 100644
index ab3d91da1..000000000
--- a/util/add-paths.bat
+++ /dev/null
@@ -1,30 +0,0 @@
-@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
-@ECHO off
-
-SET NEWPATH1="C:\MinGW\msys\1.0\bin"
-SET NEWPATH2="C:\MinGW\bin"
-
-CD %~dp0
-
-ECHO. > add-paths.log
-
-CALL :AddPath %NEWPATH1%
-CALL :AddPath %NEWPATH2%
-
-EXIT /b
-
-:AddPath <pathToAdd>
-ECHO %PATH% | FINDSTR /C:"%~1" > nul
-IF ERRORLEVEL 1 (
- REG add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /f /v PATH /t REG_SZ /d "%PATH%;%~1" >> add-paths-detail.log
- IF ERRORLEVEL 0 (
- ECHO Adding %1 . . . Success! >> add-paths.log
- SET "PATH=%PATH%;%~1"
- COPY NUL UPDATE
- ) ELSE (
- ECHO Adding %1 . . . FAILED. Run this script with administrator privileges. >> add-paths.log
- )
-) ELSE (
- ECHO Skipping %1 - Already in PATH >> add-paths.log
- )
-EXIT /b \ No newline at end of file
diff --git a/util/elevate.exe b/util/elevate.exe
deleted file mode 100644
index fc6180ec9..000000000
--- a/util/elevate.exe
+++ /dev/null
Binary files differ
diff --git a/util/linux_install.sh b/util/linux_install.sh
index 048b2f318..9ef064157 100755
--- a/util/linux_install.sh
+++ b/util/linux_install.sh
@@ -105,17 +105,17 @@ elif grep ID /etc/os-release | grep -q gentoo; then
sudo touch /etc/portage/package.use/qmkfirmware
# tee is used here since sudo doesn't apply to >>
echo "sys-devel/gcc multilib" | sudo tee --append /etc/portage/package.use/qmkfirmware >/dev/null
- sudo emerge -auN \
+ sudo emerge -auN sys-devel/gcc
+ sudo emerge -au --noreplace \
app-arch/unzip \
app-arch/zip \
app-mobilephone/dfu-util \
dev-embedded/avrdude \
- dev-lang/python:3.5 \
net-misc/wget \
sys-devel/clang \
- sys-devel/gcc \
sys-devel/crossdev
- sudo crossdev -s4 --stable --g =4.9.4 --portage --verbose --target avr
+ sudo crossdev -s4 --stable --g \<9 --portage --verbose --target avr
+ sudo crossdev -s4 --stable --g \<9 --portage --verbose --target arm-none-eabi
echo "Done!"
else
echo "Quitting..."
@@ -132,7 +132,8 @@ elif grep ID /etc/os-release | grep -q sabayon; then
sys-devel/clang \
sys-devel/gcc \
sys-devel/crossdev
- sudo crossdev -s4 --stable --g =4.9.4 --portage --verbose --target avr
+ sudo crossdev -s4 --stable --g \<9 --portage --verbose --target avr
+ sudo crossdev -s4 --stable --g \<9 --portage --verbose --target arm-none-eabi
echo "Done!"
elif grep ID /etc/os-release | grep -qE "opensuse|tumbleweed"; then
diff --git a/util/msys2_install.sh b/util/msys2_install.sh
index 001f55dc4..55df9c007 100755
--- a/util/msys2_install.sh
+++ b/util/msys2_install.sh
@@ -4,11 +4,10 @@ dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
download_dir=~/qmk_utils
avrtools=avr8-gnu-toolchain
armtools=gcc-arm-none-eabi
-installflip=false
util_dir=$(dirname "$0")
echo "Installing dependencies needed for the installation (quazip)"
-pacman --needed --noconfirm --disable-download-timeout -Sy base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang msys/git msys/p7zip mingw-w64-x86_64-python3-pip msys/unzip
+pacman --needed --noconfirm --disable-download-timeout -Sy base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-clang git mingw-w64-x86_64-python3-pip unzip
source "$dir/win_shared_install.sh"
@@ -31,19 +30,8 @@ function install_arm {
rm gcc-arm-none-eabi-8-2019-q3-update-win32.zip
}
-function extract_flip {
- rm -f -r flip
- 7z -oflip x FlipInstaller.exe
-}
-
pushd "$download_dir"
-if [ -f "FlipInstaller.exe" ]; then
- echo
- echo "Extracting flip"
- extract_flip
-fi
-
if [ ! -d "$avrtools" ]; then
echo
echo "The AVR toolchain is not installed."
diff --git a/util/win_shared_install.sh b/util/win_shared_install.sh
index 1265cb027..072ca47c8 100755
--- a/util/win_shared_install.sh
+++ b/util/win_shared_install.sh
@@ -22,10 +22,6 @@ function install_utils {
wget 'https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.zip'
unzip bootloadHID.2012-12-08.zip
- echo "Installing Atmel Flip"
- wget 'http://ww1.microchip.com/downloads/en/DeviceDoc/Flip%20Installer%20-%203.4.7.112.exe'
- mv Flip\ Installer\ \-\ 3.4.7.112.exe FlipInstaller.exe
-
echo "Downloading the QMK driver installer"
wget -qO- https://api.github.com/repos/qmk/qmk_driver_installer/releases | grep browser_download_url | head -n 1 | cut -d '"' -f 4 | wget -i -
diff --git a/util/wsl_install.sh b/util/wsl_install.sh
index 197d9f089..8ed177ca3 100755
--- a/util/wsl_install.sh
+++ b/util/wsl_install.sh
@@ -31,21 +31,6 @@ source "$dir/win_shared_install.sh"
pip3 install -r ${util_dir}/../requirements.txt
-pushd "$download_dir"
-while true; do
- echo
- echo "Flip need to be installed if you want to use that for programming."
- echo "Please install it to the default location!"
- read -p "Do you want to install it now? (Y/N) " res
- case $res in
- [Yy]* ) cmd.exe /c FlipInstaller.exe; break;;
- [Nn]* ) break;;
- * ) echo "Invalid answer";;
- esac
-done
-popd
-
-
echo
echo "Creating a softlink to the utils directory as ~/qmk_utils."
echo "This is needed so that the the make system can find all utils it need."