浏览代码

Merge branch 'master' into default_atreus_layout

Hugh Enxing 8 年之前
父节点
当前提交
3fdc45b4e9
共有 100 个文件被更改,包括 4925 次插入781 次删除
  1. 1 0
      .gitignore
  2. 22 14
      build_keyboard.mk
  3. 3 0
      doc/keymap.md
  4. 27 11
      keyboards/atreus62/atreus62.h
  5. 223 0
      keyboards/ergodox/keymaps/italian/keymap.c
  6. 72 0
      keyboards/ergodox/keymaps/italian/readme.md
  7. 1 1
      keyboards/frosty_flake/Makefile
  8. 147 0
      keyboards/frosty_flake/config.h
  9. 63 0
      keyboards/frosty_flake/frosty_flake.c
  10. 50 0
      keyboards/frosty_flake/frosty_flake.h
  11. 21 0
      keyboards/frosty_flake/keymaps/default/Makefile
  12. 8 0
      keyboards/frosty_flake/keymaps/default/config.h
  13. 11 0
      keyboards/frosty_flake/keymaps/default/keymap.c
  14. 1 0
      keyboards/frosty_flake/keymaps/default/readme.md
  15. 135 0
      keyboards/frosty_flake/matrix.c
  16. 32 0
      keyboards/frosty_flake/readme.md
  17. 71 0
      keyboards/frosty_flake/rules.mk
  18. 3 0
      keyboards/handwired/atreus50/Makefile
  19. 10 0
      keyboards/handwired/atreus50/atreus50.c
  20. 36 0
      keyboards/handwired/atreus50/atreus50.h
  21. 163 0
      keyboards/handwired/atreus50/config.h
  22. 6 0
      keyboards/handwired/atreus50/keymaps/default/Makefile
  23. 250 0
      keyboards/handwired/atreus50/keymaps/default/keymap.c
  24. 16 0
      keyboards/handwired/atreus50/readme.md
  25. 81 0
      keyboards/handwired/atreus50/rules.mk
  26. 276 0
      keyboards/lets_split/common/glcdfont.c
  27. 19 1
      keyboards/lets_split/i2c.h
  28. 25 0
      keyboards/lets_split/keymaps/OLED_sample/Makefile
  29. 45 0
      keyboards/lets_split/keymaps/OLED_sample/config.h
  30. 356 0
      keyboards/lets_split/keymaps/OLED_sample/keymap.c
  31. 25 0
      keyboards/lets_split/keymaps/OLED_sample/readme.md
  32. 4 0
      keyboards/lets_split/keymaps/hexwire/Makefile
  33. 0 23
      keyboards/lets_split/keymaps/hexwire/compact_keymap.h
  34. 33 2
      keyboards/lets_split/keymaps/hexwire/config.h
  35. 1 1
      keyboards/lets_split/keymaps/hexwire/keymap.c
  36. 0 2
      keyboards/lets_split/matrix.c
  37. 7 0
      keyboards/lets_split/rev1/config.h
  38. 8 0
      keyboards/lets_split/rev2/rev2.c
  39. 51 8
      keyboards/lets_split/rev2/rev2.h
  40. 0 32
      keyboards/lets_split/rev2fliphalf/rev2fliphalf.c
  41. 0 28
      keyboards/lets_split/rev2fliphalf/rev2fliphalf.h
  42. 0 5
      keyboards/lets_split/rev2fliphalf/rules.mk
  43. 2 13
      keyboards/lets_split/rules.mk
  44. 4 1
      keyboards/lets_split/split_util.c
  45. 2 0
      keyboards/lets_split/split_util.h
  46. 468 0
      keyboards/lets_split/ssd1306.c
  47. 29 0
      keyboards/planck/keymaps/dbroqua/config.h
  48. 29 0
      keyboards/planck/keymaps/default/config.h
  49. 23 0
      keyboards/planck/keymaps/experimental/config.h
  50. 29 0
      keyboards/planck/keymaps/impossible/config.h
  51. 29 0
      keyboards/planck/keymaps/jeebak/config.h
  52. 23 0
      keyboards/planck/keymaps/jhenahan/config.h
  53. 4 0
      keyboards/planck/keymaps/khord/Makefile
  54. 25 23
      keyboards/planck/keymaps/khord/config.h
  55. 336 0
      keyboards/planck/keymaps/khord/keymap.c
  56. 29 0
      keyboards/planck/keymaps/premek/config.h
  57. 29 0
      keyboards/planck/keymaps/sgoodwin/config.h
  58. 29 0
      keyboards/planck/keymaps/smt/config.h
  59. 23 0
      keyboards/planck/keymaps/thermal_printer/config.h
  60. 29 0
      keyboards/planck/keymaps/unicode/config.h
  61. 29 0
      keyboards/planck/keymaps/xyverz/config.h
  62. 29 0
      keyboards/preonic/keymaps/CMD-Preonic/config.h
  63. 29 0
      keyboards/preonic/keymaps/default/config.h
  64. 29 0
      keyboards/preonic/keymaps/smt/config.h
  65. 21 0
      keyboards/satan/keymaps/midi/Makefile
  66. 29 0
      keyboards/satan/keymaps/midi/config.h
  67. 77 0
      keyboards/satan/keymaps/midi/keymap.c
  68. 1 0
      keyboards/satan/keymaps/midi/readme.md
  69. 21 0
      keyboards/satan/keymaps/smt/Makefile
  70. 141 0
      keyboards/satan/keymaps/smt/keymap.c
  71. 1 0
      keyboards/satan/keymaps/smt/readme.md
  72. 29 0
      keyboards/subatomic/keymaps/default/config.h
  73. 10 56
      keyboards/tada68/keymaps/default/keymap.c
  74. 2 0
      keyboards/tada68/keymaps/default/readme.md
  75. 13 2
      keyboards/tada68/readme.md
  76. 13 0
      keyboards/xd60/keymaps/cheese/README.md
  77. 二进制
      keyboards/xd60/keymaps/cheese/base_layout.png
  78. 二进制
      keyboards/xd60/keymaps/cheese/fn_layout.png
  79. 67 0
      keyboards/xd60/keymaps/cheese/keymap.c
  80. 164 158
      quantum/audio/audio.c
  81. 27 0
      quantum/audio/song_list.h
  82. 62 0
      quantum/process_keycode/process_audio.c
  83. 11 0
      quantum/process_keycode/process_audio.h
  84. 231 61
      quantum/process_keycode/process_midi.c
  85. 29 196
      quantum/process_keycode/process_midi.h
  86. 61 57
      quantum/process_keycode/process_music.c
  87. 5 1
      quantum/process_keycode/process_music.h
  88. 6 11
      quantum/quantum.c
  89. 6 1
      quantum/quantum.h
  90. 234 10
      quantum/quantum_keycodes.h
  91. 23 0
      quantum/template/config.h
  92. 1 1
      quantum/template/keymaps/default/Makefile
  93. 1 1
      quantum/template/rules.mk
  94. 10 4
      tmk_core/common.mk
  95. 5 4
      tmk_core/common/action_tapping.c
  96. 9 3
      tmk_core/protocol/lufa.mk
  97. 2 2
      tmk_core/protocol/lufa/adafruit_ble.h
  98. 48 44
      tmk_core/protocol/lufa/lufa.c
  99. 1 1
      tmk_core/protocol/lufa/lufa.h
  100. 3 3
      tmk_core/protocol/lufa/outputselect.c

+ 1 - 0
.gitignore

@@ -1,5 +1,6 @@
 .dep
 *.o
+*.bin
 *.eep
 *.elf
 *.hex

+ 22 - 14
build_keyboard.mk

@@ -23,9 +23,9 @@ ifdef master
 	MASTER = $(master)
 endif
 
-ifeq ($(MASTER),right)	
+ifeq ($(MASTER),right)
 	OPT_DEFS += -DMASTER_IS_ON_RIGHT
-else 
+else
 	ifneq ($(MASTER),left)
 $(error MASTER does not have a valid value(left/right))
 	endif
@@ -38,7 +38,7 @@ KEYBOARD_C := $(KEYBOARD_PATH)/$(KEYBOARD).c
 
 ifneq ("$(wildcard $(KEYBOARD_C))","")
     include $(KEYBOARD_PATH)/rules.mk
-else 
+else
     $(error "$(KEYBOARD_C)" does not exist)
 endif
 
@@ -49,7 +49,7 @@ ifneq ($(SUBPROJECT),)
     ifneq ("$(wildcard $(SUBPROJECT_C))","")
         OPT_DEFS += -DSUBPROJECT_$(SUBPROJECT)
         include $(SUBPROJECT_PATH)/rules.mk
-    else 
+    else
         $(error "$(SUBPROJECT_PATH)/$(SUBPROJECT).c" does not exist)
     endif
 endif
@@ -83,7 +83,7 @@ ifneq ($(SUBPROJECT),)
 	endif
 endif
 
-# Save the defines and includes here, so we don't include any keymap specific ones 
+# Save the defines and includes here, so we don't include any keymap specific ones
 PROJECT_DEFS := $(OPT_DEFS)
 PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(SUBPROJECT_PATH) $(KEYBOARD_PATH)
 PROJECT_CONFIG := $(CONFIG_H)
@@ -139,11 +139,27 @@ ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
     MIDI_ENABLE=yes
 endif
 
+MUSIC_ENABLE := 0
+
+ifeq ($(strip $(AUDIO_ENABLE)), yes)
+    OPT_DEFS += -DAUDIO_ENABLE
+    MUSIC_ENABLE := 1
+	SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
+	SRC += $(QUANTUM_DIR)/audio/audio.c
+	SRC += $(QUANTUM_DIR)/audio/voices.c
+	SRC += $(QUANTUM_DIR)/audio/luts.c
+endif
+
 ifeq ($(strip $(MIDI_ENABLE)), yes)
     OPT_DEFS += -DMIDI_ENABLE
+	MUSIC_ENABLE := 1
 	SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
 endif
 
+ifeq ($(MUSIC_ENABLE), 1)
+	SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
+endif
+
 ifeq ($(strip $(COMBO_ENABLE)), yes)
     OPT_DEFS += -DCOMBO_ENABLE
 	SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
@@ -153,14 +169,6 @@ ifeq ($(strip $(VIRTSER_ENABLE)), yes)
     OPT_DEFS += -DVIRTSER_ENABLE
 endif
 
-ifeq ($(strip $(AUDIO_ENABLE)), yes)
-    OPT_DEFS += -DAUDIO_ENABLE
-	SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
-	SRC += $(QUANTUM_DIR)/audio/audio.c
-	SRC += $(QUANTUM_DIR)/audio/voices.c
-	SRC += $(QUANTUM_DIR)/audio/luts.c
-endif
-
 ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
     OPT_DEFS += -DFAUXCLICKY_ENABLE
 	SRC += $(QUANTUM_DIR)/fauxclicky.c
@@ -250,7 +258,7 @@ endif
 
 OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
 $(KEYMAP_OUTPUT)_SRC := $(SRC)
-$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\" 
+$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\"
 $(KEYMAP_OUTPUT)_INC :=  $(VPATH) $(EXTRAINCDIRS)
 $(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
 $(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC)

+ 3 - 0
doc/keymap.md

@@ -549,6 +549,9 @@ Layer switching with tap key:
 
 [dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
 
+When user hold a key after tap, it repeat the tapped key rather to hold a modifier key.
+If you prefer to hold a modifier instead, define `TAPPING_FORCE_HOLD` in `config.h`.
+See https://github.com/qmk/qmk_firmware/issues/889 for the detail.
 
 ### 4.2 Tap Toggle
 This is a feature to assign both toggle layer and momentary switch layer action to just same one physical key. It works as momentary layer switch when holding a key but toggle switch with several taps.

+ 27 - 11
keyboards/atreus62/atreus62.h

@@ -9,18 +9,34 @@ void promicro_bootloader_jmp(bool program);
 // The first section contains all of the arguements
 // The second converts the arguments into a two-dimensional array
 #define KEYMAP( \
-  k00, k01, k02, k03, k04, k05,           k06, k07, k08, k09, k0a, k0b, \
-  k10, k11, k12, k13, k14, k15,           k16, k17, k18, k19, k1a, k1b, \
-  k20, k21, k22, k23, k24, k25,           k26, k27, k28, k29, k2a, k2b, \
-  k30, k31, k32, k33, k34, k35,           k36, k37, k38, k39, k3a, k3b, \
-  k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
+    k00, k01, k02, k03, k04, k05,           k06, k07, k08, k09, k0a, k0b, \
+    k10, k11, k12, k13, k14, k15,           k16, k17, k18, k19, k1a, k1b, \
+    k20, k21, k22, k23, k24, k25,           k26, k27, k28, k29, k2a, k2b, \
+    k30, k31, k32, k33, k34, k35,           k36, k37, k38, k39, k3a, k3b, \
+    k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
 ) \
 { \
-	{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
-	{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
-	{ k20, k21, k22, k23, k24, k25, KC_NO, k26, k27, k28, k29, k2a, k2b }, \
-	{ k30, k31, k32, k33, k34, k35, k46,   k36, k37, k38, k39, k3a, k3b }, \
-	{ k40, k41, k42, k43, k44, k45, k47,   k48, k49, k4a, k4b, k4c, k4d } \
+    { k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
+    { k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
+    { k20, k21, k22, k23, k24, k25, KC_NO, k26, k27, k28, k29, k2a, k2b }, \
+    { k30, k31, k32, k33, k34, k35, k46,   k36, k37, k38, k39, k3a, k3b }, \
+    { k40, k41, k42, k43, k44, k45, k47,   k48, k49, k4a, k4b, k4c, k4d } \
 }
 
-#endif
+// Used to create a keymap using only KC_ prefixed keys.
+#define KC_KEYMAP( \
+    k00, k01, k02, k03, k04, k05,           k06, k07, k08, k09, k0a, k0b, \
+    k10, k11, k12, k13, k14, k15,           k16, k17, k18, k19, k1a, k1b, \
+    k20, k21, k22, k23, k24, k25,           k26, k27, k28, k29, k2a, k2b, \
+    k30, k31, k32, k33, k34, k35,           k36, k37, k38, k39, k3a, k3b, \
+    k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
+) \
+{ \
+    { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO,    KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \
+    { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO,    KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \
+    { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_NO,    KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \
+    { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k46, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b }, \
+    { KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45, KC_##k47, KC_##k48, KC_##k49, KC_##k4a, KC_##k4b, KC_##k4c, KC_##k4d } \
+}
+
+#endif

+ 223 - 0
keyboards/ergodox/keymaps/italian/keymap.c

@@ -0,0 +1,223 @@
+#include "ergodox.h"
+#include "debug.h"
+#include "action_layer.h"
+#include "version.h"
+
+#define BASE 0 // default layer
+#define SYMB 1 // symbols
+#define MDIA 2 // media keys
+
+enum custom_keycodes {
+  PLACEHOLDER = SAFE_RANGE, // can always be here
+  EPRM,
+  VRSN,
+  RGB_SLD
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ,--------------------------------------------------.           ,--------------------------------------------------.
+ * |   \    |   1  |   2  |   3  |   4  |   5  | ESC  |           |  T2  |   6  |   7  |   8  |   9  |   0  |   '    |
+ * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ * | Tab    |   Q  |   W  |   E  |   R  |   T  | TT1  |           |  TT1 |   Y  |   U  |   I  |   O  |   P  |   è    |
+ * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ * | Caps   |   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |   ò  |   à    |
+ * |--------+------+------+------+------+------| Alt  |           | Alt  |------+------+------+------+------+--------|
+ * | LShift |   Z  |   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ,  |   .  |   ù  |-/RShift|
+ * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+ *   |</Win |   +  |   -  |   *  |//Ctr |                                       |ì/RAlt| Left | Down |  Up  | Right  | ~L1  |
+ *   `----------------------------------'                                       `----------------------------------'
+ *                                        ,-------------.       ,-------------.
+ *                                        | Ins  | LGui |       | Win  | Ctrl |
+ *                                 ,------|------|------|       |------+--------+------.
+ *                                 |      |      | Home |       | PgUp |        |      |
+ *                                 |Backsp| Del  |------|       |------|  Enter |Space |
+ *                                 |ace   |      | End  |       | PgDn |        |      |
+ *                                 `--------------------'       `----------------------'
+ */
+// If it accepts an argument (i.e, is a function), it doesn't need KC_.
+// Otherwise, it needs KC_*
+[BASE] = KEYMAP(  // layer 0 : default
+        // left hand
+        KC_GRV,                      KC_1,         KC_2,   KC_3,   KC_4,   KC_5,   KC_ESC,
+        KC_TAB,                      KC_Q,         KC_W,   KC_E,   KC_R,   KC_T,   TT(SYMB),
+        KC_CAPS,                     KC_A,         KC_S,   KC_D,   KC_F,   KC_G,
+        KC_LSFT,                     KC_Z,         KC_X,   KC_C,   KC_V,   KC_B,   KC_LALT, 
+        MT(MOD_LGUI,KC_NONUS_BSLASH),KC_PPLS,      KC_PMNS,KC_PAST,MT(MOD_LCTL,KC_PSLS),
+                                                           KC_INS,  KC_LGUI,
+                                                                    KC_HOME,
+                                                   KC_BSPC,KC_DEL,  KC_END,
+        // right hand
+             TG(MDIA),    KC_6,   KC_7,                 KC_8,   KC_9,   KC_0,      KC_MINS,
+             TT(SYMB),    KC_Y,   KC_U,                 KC_I,   KC_O,   KC_P,      KC_LBRC,
+                          KC_H,   KC_J,                 KC_K,   KC_L,   KC_SCLN,   KC_QUOT,
+             KC_LALT,     KC_N,   KC_M,                 KC_COMM,KC_DOT, KC_BSLASH, MT(MOD_RSFT,KC_SLSH),
+                                  MT(MOD_RALT,KC_EQL), KC_LEFT,KC_DOWN,KC_UP,     KC_RIGHT,
+             KC_LGUI,     KC_RCTL,
+             KC_PGUP,
+             KC_PGDN,     KC_ENT, KC_SPC
+    ),
+/* Keymap 1: Symbol Layer
+ *
+ * ,--------------------------------------------------.           ,--------------------------------------------------.
+ * |Version |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |   F11  |
+ * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ * |        |   !  |   @  |   {  |   }  |   |  |      |           |      |      |   7  |   8  |   9  |      |   F12  |
+ * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ * |        |   #  |   $  |   [  |   ]  |   &  |------|           |------|      |   4  |   5  |   6  |      |        |
+ * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ * |        |   %  |   ^  |   (  |   )  |      |      |           |      |      |   1  |   2  |   3  |      |        |
+ * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+ *   |      |      |      |      |      |                                       |   .  |      |      |      |      |
+ *   `----------------------------------'                                       `----------------------------------'
+ *                                        ,-------------.       ,-------------.
+ *                                        |      |      |       |      |      |
+ *                                 ,------|------|------|       |------+------+------.
+ *                                 |      |      |      |       |      |      |      |
+ *                                 |      |      |------|       |------|      |  0   |
+ *                                 |      |      |      |       |      |      |      |
+ *                                 `--------------------'       `--------------------'
+ */
+// SYMBOLS
+[SYMB] = KEYMAP(
+       // left hand
+       M(0),    KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_TRNS,
+       KC_TRNS, KC_EXLM,                RALT(KC_SCLN), RALT(KC_LCBR), RALT(KC_RCBR), KC_TILD,  KC_TRNS,
+       KC_TRNS, RALT(KC_QUOT),          KC_DLR,        RALT(KC_LBRC), RALT(KC_RBRC), KC_CIRC,
+       KC_TRNS, KC_PERC,                LSFT(KC_EQL),  LSFT(KC_8),    LSFT(KC_9),    KC_TRNS,  KC_TRNS,
+       KC_TRNS, KC_TRNS,                KC_TRNS,       KC_TRNS,       KC_TRNS,
+		              KC_TRNS,          KC_TRNS,
+                                                KC_TRNS,
+                              KC_TRNS, KC_TRNS, KC_TRNS,
+       // right hand
+       KC_TRNS, KC_F6,   KC_F7,  KC_F8,   KC_F9,   KC_F10,  KC_F11,
+       KC_TRNS, KC_TRNS, KC_7,   KC_8,    KC_9,    KC_ASTR, KC_F12,
+                KC_TRNS, KC_4,   KC_5,    KC_6,    KC_PLUS, KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_1,   KC_2,    KC_3,    KC_BSLS, KC_TRNS,
+                         KC_DOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+       KC_TRNS, KC_TRNS,
+       KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_0
+),
+/* Keymap 2: Media and mouse keys
+ *
+ * ,--------------------------------------------------.           ,--------------------------------------------------.
+ * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
+ * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ * |        |      |      | MsUp |      |      |      |           |      | Lclk | Rclk |      |      |      |        |
+ * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ * |        |      |MsLeft|MsDown|MsRght|      |------|           |------|      |      |      |      |      |  Play  |
+ * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ * |        |      |      |      |      |      |      |           |      |      |      | Prev | Next |      |        |
+ * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+ *   |      |      |      |      |      |                                       |VolUp |VolDn | Mute |      |      |
+ *   `----------------------------------'                                       `----------------------------------'
+ *                                        ,-------------.       ,-------------.
+ *                                        |      |      |       |      |      |
+ *                                 ,------|------|------|       |------+------+------.
+ *                                 |      |      |      |       |      |      |Brwser|
+ *                                 |      |      |------|       |------|      |Back  |
+ *                                 |      |      |      |       |      |      |      |
+ *                                 `--------------------'       `--------------------'
+ */
+// MEDIA AND MOUSE
+[MDIA] = KEYMAP(
+       KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+                                           KC_TRNS, KC_TRNS,
+                                                    KC_TRNS,
+                                  KC_TRNS, KC_TRNS, KC_TRNS,
+    // right hand
+       KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+       KC_TRNS,  KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+                 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
+       KC_TRNS,  KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
+                          KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
+       KC_TRNS, KC_TRNS,
+       KC_TRNS,
+       KC_TRNS, KC_TRNS, KC_WBAK
+),
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+    [1] = ACTION_LAYER_TAP_TOGGLE(SYMB)                // FN1 - Momentary Layer 1 (Symbols)
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+  // MACRODOWN only works in this function
+      switch(id) {
+        case 0:
+        if (record->event.pressed) {
+          SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
+        }
+        break;
+        case 1:
+        if (record->event.pressed) { // For resetting EEPROM
+          eeconfig_init();
+        }
+        break;
+      }
+    return MACRO_NONE;
+};
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    // dynamically generate these.
+    case EPRM:
+      if (record->event.pressed) {
+        eeconfig_init();
+      }
+      return false;
+      break;
+    case VRSN:
+      if (record->event.pressed) {
+        SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
+      }
+      return false;
+      break;
+    case RGB_SLD:
+      if (record->event.pressed) {
+        #ifdef RGBLIGHT_ENABLE
+          rgblight_mode(1);
+        #endif
+      }
+      return false;
+      break;
+  }
+  return true;
+}
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+
+};
+
+
+// Runs constantly in the background, in a loop.
+void matrix_scan_user(void) {
+
+    uint8_t layer = biton32(layer_state);
+
+    ergodox_board_led_off();
+    ergodox_right_led_1_off();
+    ergodox_right_led_2_off();
+    ergodox_right_led_3_off();
+    switch (layer) {
+      // TODO: Make this relevant to the ErgoDox EZ.
+        case 1:
+            ergodox_right_led_1_on();
+            break;
+        case 2:
+            ergodox_right_led_2_on();
+            break;
+        default:
+            // none
+            break;
+    }
+
+};

+ 72 - 0
keyboards/ergodox/keymaps/italian/readme.md

@@ -0,0 +1,72 @@
+# ErgoDox Italian layout
+
+## Layer 0
+```
+ 
+ ,--------------------------------------------------.           ,--------------------------------------------------.
+ |   \    |   1  |   2  |   3  |   4  |   5  | ESC  |           |  T2  |   6  |   7  |   8  |   9  |   0  |   '    |
+ |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ | Tab    |   Q  |   W  |   E  |   R  |   T  | TT1  |           |  TT1 |   Y  |   U  |   I  |   O  |   P  |   è    |
+ |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ | Caps   |   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |   ò  |   à    |
+ |--------+------+------+------+------+------| Alt  |           | Alt  |------+------+------+------+------+--------|
+ | LShift |   Z  |   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ,  |   .  |   ù  |-/RShift|
+ `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+   |</Win |   +  |   -  |   *  |//Ctr |                                       |ì/RAlt| Left | Down |  Up  | Right  | ~L1  |
+   `----------------------------------'                                       `----------------------------------'
+                                        ,-------------.       ,-------------.
+                                        | Ins  | LGui |       | Win  | Ctrl |
+                                 ,------|------|------|       |------+--------+------.
+                                 |      |      | Home |       | PgUp |        |      |
+                                 |Backsp| Del  |------|       |------|  Enter |Space |
+                                 |ace   |      | End  |       | PgDn |        |      |
+                                 `--------------------'       `----------------------'
+```
+
+## Layer 1
+```
+
+ ,--------------------------------------------------.           ,--------------------------------------------------.
+ |Version |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |   F11  |
+ |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ |        |   !  |   @  |   {  |   }  |   |  |      |           |      |      |   7  |   8  |   9  |      |   F12  |
+ |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ |        |   #  |   $  |   [  |   ]  |   &  |------|           |------|      |   4  |   5  |   6  |      |        |
+ |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ |        |   %  |   ^  |   (  |   )  |      |      |           |      |      |   1  |   2  |   3  |      |        |
+ `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+   |      |      |      |      |      |                                       |   .  |      |      |      |      |
+   `----------------------------------'                                       `----------------------------------'
+                                        ,-------------.       ,-------------.
+                                        |      |      |       |      |      |
+                                 ,------|------|------|       |------+------+------.
+                                 |      |      |      |       |      |      |      |
+                                 |      |      |------|       |------|      |  0   |
+                                 |      |      |      |       |      |      |      |
+                                 `--------------------'       `--------------------'
+```
+
+## Layer 2
+```
+
+ ,--------------------------------------------------.           ,--------------------------------------------------.
+ |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
+ |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
+ |        |      |      | MsUp |      |      |      |           |      | Lclk | Rclk |      |      |      |        |
+ |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ |        |      |MsLeft|MsDown|MsRght|      |------|           |------|      |      |      |      |      |  Play  |
+ |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
+ |        |      |      |      |      |      |      |           |      |      |      | Prev | Next |      |        |
+ `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
+   |      |      |      |      |      |                                       |VolUp |VolDn | Mute |      |      |
+   `----------------------------------'                                       `----------------------------------'
+                                        ,-------------.       ,-------------.
+                                        |      |      |       |      |      |
+                                 ,------|------|------|       |------+------+------.
+                                 |      |      |      |       |      |      |Brwser|
+                                 |      |      |------|       |------|      |Back  |
+                                 |      |      |      |       |      |      |      |
+                                 `--------------------'       `--------------------' 
+```
+
+

+ 1 - 1
keyboards/lets_split/rev2fliphalf/Makefile → keyboards/frosty_flake/Makefile

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

+ 147 - 0
keyboards/frosty_flake/config.h

@@ -0,0 +1,147 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID       0xFEED
+#define PRODUCT_ID      0x6060
+#define DEVICE_VER      0x0001
+#define MANUFACTURER    Bathroom Epiphanies
+#define PRODUCT         frosty_flake
+#define DESCRIPTION     Frosty Flake controller for the CM Storm Quick Fire Rapid
+
+/*
+ * Frosty Flake Rev. 20140521 made by Bathroom Ephiphanies
+ * Ported from the Bathroom Epiphanies TMK Firmware:
+ * https://github.com/BathroomEpiphanies/epiphanies_tmk_keyboard/tree/master/be_controllers
+ *
+ */
+
+/* key matrix size */
+#define MATRIX_ROWS 8   // Row0 - Row7 in the schematic
+#define MATRIX_COLS 18  // ColA - ColR in the schematic
+
+/*
+ * Keyboard Matrix Assignments
+ */
+#define UNUSED_PINS { B0, C4, D3 }
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCING_DELAY 5
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/*
+ * Magic Key Options
+ *
+ * Magic keys are hotkey commands that allow control over firmware functions of
+ * the keyboard. They are best used in combination with the HID Listen program,
+ * found here: https://www.pjrc.com/teensy/hid_listen.html
+ *
+ * The options below allow the magic key functionality to be changed. This is
+ * useful if your keyboard/keypad is missing keys and you want magic key support.
+ *
+ */
+
+/* key combination for magic key command */
+#define IS_COMMAND() ( \
+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/* control how magic key switches layers */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
+
+/* override magic key keymap */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
+//#define MAGIC_KEY_HELP1          H
+//#define MAGIC_KEY_HELP2          SLASH
+//#define MAGIC_KEY_DEBUG          D
+//#define MAGIC_KEY_DEBUG_MATRIX   X
+//#define MAGIC_KEY_DEBUG_KBD      K
+//#define MAGIC_KEY_DEBUG_MOUSE    M
+//#define MAGIC_KEY_VERSION        V
+//#define MAGIC_KEY_STATUS         S
+//#define MAGIC_KEY_CONSOLE        C
+//#define MAGIC_KEY_LAYER0_ALT1    ESC
+//#define MAGIC_KEY_LAYER0_ALT2    GRAVE
+//#define MAGIC_KEY_LAYER0         0
+//#define MAGIC_KEY_LAYER1         1
+//#define MAGIC_KEY_LAYER2         2
+//#define MAGIC_KEY_LAYER3         3
+//#define MAGIC_KEY_LAYER4         4
+//#define MAGIC_KEY_LAYER5         5
+//#define MAGIC_KEY_LAYER6         6
+//#define MAGIC_KEY_LAYER7         7
+//#define MAGIC_KEY_LAYER8         8
+//#define MAGIC_KEY_LAYER9         9
+//#define MAGIC_KEY_BOOTLOADER     PAUSE
+//#define MAGIC_KEY_LOCK           CAPS
+//#define MAGIC_KEY_EEPROM         E
+//#define MAGIC_KEY_NKRO           N
+//#define MAGIC_KEY_SLEEP_LED      Z
+
+/*
+ * Feature disable options
+ *  These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+#endif

+ 63 - 0
keyboards/frosty_flake/frosty_flake.c

@@ -0,0 +1,63 @@
+#include "frosty_flake.h"
+
+void matrix_init_kb(void) {
+    // put your keyboard start-up code here
+    // runs once when the firmware starts up
+
+    matrix_init_user();
+}
+
+void matrix_scan_kb(void) {
+    // put your looping keyboard code here
+    // runs every cycle (a lot)
+
+    matrix_scan_user();
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+    // put your per-action keyboard code here
+    // runs for every action, just before processing by the firmware
+
+    return process_record_user(keycode, record);
+}
+
+void led_set_kb(uint8_t usb_led) {
+    DDRB |= (1<<7);
+    DDRC |= (1<<5) | (1<<6);
+
+    print_dec(usb_led);
+
+    if (usb_led & (1<<USB_LED_CAPS_LOCK))
+        PORTC &= ~(1<<5);
+    else
+        PORTC |=  (1<<5);
+
+    if (usb_led & (1<<USB_LED_NUM_LOCK))
+        PORTB &= ~(1<<7);
+    else
+        PORTB |=  (1<<7);
+
+    if (usb_led & (1<<USB_LED_SCROLL_LOCK))
+        PORTC &= ~(1<<6);
+    else
+        PORTC |=  (1<<6);
+
+    led_set_user(usb_led);
+}
+
+__attribute__ ((weak))
+void matrix_init_user(void) {
+}
+
+__attribute__ ((weak))
+void matrix_scan_user(void) {
+}
+
+__attribute__ ((weak))
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  return true;
+}
+
+__attribute__ ((weak))
+void led_set_user(uint8_t usb_led) {
+}

+ 50 - 0
keyboards/frosty_flake/frosty_flake.h

@@ -0,0 +1,50 @@
+#ifndef FROSTY_FLAKE_H
+#define FROSTY_FLAKE_H
+
+#include "quantum.h"
+
+// This a shortcut to help you visually see your layout.
+// The following is an example using the Planck MIT layout
+// The first section contains all of the arguements
+// The second converts the arguments into a two-dimensional array
+
+/*
+  Matrix col/row mapping
+
+  ,----.    ,-------------------. ,-------------------. ,-------------------. ,--------------.
+  | J6 |    | I4 | H4 | H2 | H6 | | A7 | E6 | D2 | D4 | | B4 | B7 | B6 | B0 | | C7 | C5 | A5 |
+  `----'    `-------------------' `-------------------' `-------------------' `--------------'
+  ,-------------------------------------------------------------------------. ,--------------. ,-------------------.
+  | J4 | J7 | I7 | H7 | G7 | G4 | F4 | F7 | E7 | D7 | R7 | R4 | E4 |     B2 | | L4 | O4 | Q4 | | K1 | L1 | Q1 | Q0 |
+  |-------------------------------------------------------------------------| |--------------| |-------------------|
+  | J2   | J5 | I5 | H5 | G5 | G2 | F2 | F5 | E5 | D5 | R5 | R2 | E2 |   B3 | | K4 | O7 | Q7 | | K5 | L5 | Q5 | O5 |
+  |-------------------------------------------------------------------------| '--------------' |--------------     |
+  | O5    | J3 | I3 | H3 | G3 | G6 | F6 | F3 | E3 | D3 | R3 | R6 |       B1 |                  | K2 | L2 | Q2 |    |
+  |-------------------------------------------------------------------------|      ,----.      |-------------------|
+  | N2      | J1 | I1 | H1 | G1 | G0 | F0 | F1 | E1 | D1 | R0 |          N3 |      | O6 |      | K3 | L3 | Q3 | O3 |
+  |-------------------------------------------------------------------------| ,--------------. |--------------     |
+  | A4 | P2 | C6 |                  K6                  | C0 | M3 | D0 | A1 | | O0 | K0 | L0 | | L6      | Q6 |    |
+  `-------------------------------------------------------------------------' `--------------' `-------------------'
+*/
+#define KEYMAP( \
+  KJ6,      KI4, KH4, KH2, KH6, KA7, KE6, KD2, KD4, KB4, KB7, KB6, KB0,   KC7, KC5, KA5,                       \
+  KJ4, KJ7, KI7, KH7, KG7, KG4, KF4, KF7, KE7, KD7, KR7, KR4, KE4, KB2,   KL4, KO4, KQ4,   KK1, KL1, KQ1, KQ0, \
+  KJ2, KJ5, KI5, KH5, KG5, KG2, KF2, KF5, KE5, KD5, KR5, KR2, KE2, KB3,   KK4, KO7, KQ7,   KK5, KL5, KQ5, KO5, \
+  KI2, KJ3, KI3, KH3, KG3, KG6, KF6, KF3, KE3, KD3, KR3, KR6,      KB1,                    KK2, KL2, KQ2,      \
+  KN2, KI6, KJ1, KI1, KH1, KG1, KG0, KF0, KF1, KE1, KD1, KR0,      KN3,        KO6,        KK3, KL3, KQ3, KO3, \
+  KA4, KP2, KC6,                KK6,                KC0, KM3, KD0, KA1,   KO0, KK0, KL0,   KL6,      KQ6       \
+) \
+{ \
+/* Columns and rows need to be swapped in the below definition */ \
+/*          A       B       C       D       E       F       G       H       I       J       K       L       M       N       O       P       Q       R       */ \
+/* 0 */ {   KC_NO,  KB0,    KC0,    KD0,    KC_NO,  KF0,    KG0,    KC_NO,  KC_NO,  KC_NO,  KK0,    KL0,    KC_NO,  KC_NO,  KO0,    KC_NO,  KQ0,    KR0     }, \
+/* 1 */ {   KA1,    KB1,    KC_NO,  KD1,    KE1,    KF1,    KG1,    KH1,    KI1,    KJ1,    KK1,    KL1,    KC_NO,  KC_NO,  KC_NO,  KC_NO,  KQ1,    KC_NO   }, \
+/* 2 */ {   KC_NO,  KB2,    KC_NO,  KD2,    KE2,    KF2,    KG2,    KH2,    KI2,    KJ2,    KK2,    KL2,    KC_NO,  KN2,    KC_NO,  KP2,    KQ2,    KR2     }, \
+/* 3 */ {   KC_NO,  KB3,    KC_NO,  KD3,    KE3,    KF3,    KG3,    KH3,    KI3,    KJ3,    KK3,    KL3,    KM3,    KN3,    KO3,    KC_NO,  KQ3,    KR3     }, \
+/* 4 */ {   KA4,    KB4,    KC_NO,  KD4,    KE4,    KF4,    KG4,    KH4,    KI4,    KJ4,    KK4,    KL4,    KC_NO,  KC_NO,  KO4,    KC_NO,  KQ4,    KR4     }, \
+/* 5 */ {   KA5,    KC_NO,  KC5,    KD5,    KE5,    KF5,    KG5,    KH5,    KI5,    KJ5,    KK5,    KL5,    KC_NO,  KC_NO,  KO5,    KC_NO,  KQ5,    KR5     }, \
+/* 6 */ {   KC_NO,  KB6,    KC6,    KC_NO,  KE6,    KF6,    KG6,    KH6,    KI6,    KJ6,    KK6,    KL6,    KC_NO,  KC_NO,  KO6,    KC_NO,  KQ6,    KR6     }, \
+/* 7 */ {   KA7,    KB7,    KC7,    KD7,    KE7,    KF7,    KG7,    KH7,    KI7,    KJ7,    KC_NO,  KC_NO,  KC_NO,  KC_NO,  KO7,    KC_NO,  KQ7,    KR7     }  \
+}
+
+#endif

+ 21 - 0
keyboards/frosty_flake/keymaps/default/Makefile

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

+ 8 - 0
keyboards/frosty_flake/keymaps/default/config.h

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

+ 11 - 0
keyboards/frosty_flake/keymaps/default/keymap.c

@@ -0,0 +1,11 @@
+#include "frosty_flake.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+[0] = KEYMAP(\
+       KC_ESC,  KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_F6,  KC_F7,  KC_F8,  KC_F9, KC_F10, KC_F11, KC_F12,          KC_PSCR,KC_SLCK,KC_PAUS,                        \
+       KC_GRV,   KC_1,   KC_2,   KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,   KC_9,   KC_0,KC_MINS, KC_EQL,KC_BSPC,   KC_INS,KC_HOME,KC_PGUP,  KC_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, KC_APP,KC_RCTL,  KC_LEFT,KC_DOWN,KC_RGHT,    KC_P0,KC_PDOT)
+};

+ 1 - 0
keyboards/frosty_flake/keymaps/default/readme.md

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

+ 135 - 0
keyboards/frosty_flake/matrix.c

@@ -0,0 +1,135 @@
+/*
+  Copyright 2017 Gabriel Young <gabeplaysdrums@live.com>
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "matrix.h"
+
+#ifndef DEBOUNCING_DELAY
+#   define DEBOUNCING_DELAY 5
+#endif
+static uint8_t debouncing = DEBOUNCING_DELAY;
+
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+static matrix_row_t scan_col(void) {
+    return (
+        (PINC&(1<<7) ? 0 : ((matrix_row_t)1<<0)) |
+        (PINB&(1<<5) ? 0 : ((matrix_row_t)1<<1)) |
+        (PINB&(1<<4) ? 0 : ((matrix_row_t)1<<2)) |
+        (PINB&(1<<6) ? 0 : ((matrix_row_t)1<<3)) |
+        (PINB&(1<<1) ? 0 : ((matrix_row_t)1<<4)) |
+        (PINB&(1<<2) ? 0 : ((matrix_row_t)1<<5)) |
+        (PINB&(1<<3) ? 0 : ((matrix_row_t)1<<6)) |
+        (PINB&(1<<0) ? 0 : ((matrix_row_t)1<<7))
+    );
+}
+
+static void select_col(uint8_t col) {
+    switch (col) {
+        case  0: PORTD = (PORTD & ~0b01111011) | 0b00011011; break;
+        case  1: PORTD = (PORTD & ~0b01111011) | 0b01000011; break;
+        case  2: PORTD = (PORTD & ~0b01111011) | 0b01101010; break;
+        case  3: PORTD = (PORTD & ~0b01111011) | 0b01111001; break;
+        case  4: PORTD = (PORTD & ~0b01111011) | 0b01100010; break;
+        case  5: PORTD = (PORTD & ~0b01111011) | 0b01110001; break;
+        case  6: PORTD = (PORTD & ~0b01111011) | 0b01100001; break;
+        case  7: PORTD = (PORTD & ~0b01111011) | 0b01110000; break;
+        case  8: PORTD = (PORTD & ~0b01111011) | 0b01100000; break;
+        case  9: PORTD = (PORTD & ~0b01111011) | 0b01101000; break;
+        case 10: PORTD = (PORTD & ~0b01111011) | 0b00101011; break;
+        case 11: PORTD = (PORTD & ~0b01111011) | 0b00110011; break;
+        case 12: PORTD = (PORTD & ~0b01111011) | 0b00100011; break;
+        case 13: PORTD = (PORTD & ~0b01111011) | 0b01111000; break;
+        case 14: PORTD = (PORTD & ~0b01111011) | 0b00010011; break;
+        case 15: PORTD = (PORTD & ~0b01111011) | 0b01101001; break;
+        case 16: PORTD = (PORTD & ~0b01111011) | 0b00001011; break;
+        case 17: PORTD = (PORTD & ~0b01111011) | 0b00111011; break;
+    }
+}
+
+void matrix_init(void) {
+    /* Row output pins */
+    DDRD  |=  0b01111011;
+    /* Column input pins */
+    DDRC  &= ~0b10000000;
+    DDRB  &= ~0b01111111;
+    PORTC |=  0b10000000;
+    PORTB |=  0b01111111;
+
+    for (uint8_t i=0; i < MATRIX_ROWS; i++)
+        matrix[i] = matrix_debouncing[i] = 0;
+
+    matrix_init_quantum();
+}
+
+uint8_t matrix_scan(void) {
+    for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+        select_col(col);
+        _delay_us(3);
+        matrix_row_t col_scan = scan_col();
+        for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+            bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
+            bool curr_bit = col_scan & (1<<row);
+            if (prev_bit != curr_bit) {
+                matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
+                debouncing = DEBOUNCING_DELAY;
+            }
+        }
+    }
+
+    if (debouncing) {
+        if (--debouncing)
+            _delay_ms(1);
+        else
+            for (uint8_t i = 0; i < MATRIX_ROWS; i++)
+                matrix[i] = matrix_debouncing[i];
+    }
+
+    matrix_scan_quantum();
+    return 1;
+}
+
+inline matrix_row_t matrix_get_row(uint8_t row) {
+    return matrix[row];
+}
+
+void matrix_print(void) {
+    print("\nr\\c ABCDEFGHIJKLMNOPQR\n");
+    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+        matrix_row_t matrix_row = matrix_get_row(row);
+        xprintf("%02X: ", row);
+        for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+            bool curr_bit = matrix_row & (1<<col);
+            xprintf("%c", curr_bit ? '*' : '.');
+        }
+        print("\n");
+    }
+}
+
+uint8_t matrix_key_count(void) {
+    uint8_t count = 0;
+    for (uint8_t row = 0; row < MATRIX_ROWS; row++)
+        count += bitpop32(matrix[row]);
+    return count;
+}

+ 32 - 0
keyboards/frosty_flake/readme.md

@@ -0,0 +1,32 @@
+frosty_flake keyboard firmware
+======================
+
+This is the firmware for Rev. 20140521 of the Frosty Flake controller by [Bathroom Epiphanies](http://bathroomepiphanies.com/controllers/), a replacement controller for the [Cooler Master Quick Fire Rapid](http://www.coolermaster.com/peripheral/keyboards/quickfirerapid/).
+
+The code was adapted from the [BathroomEpiphanies TMK Firmware](https://github.com/BathroomEpiphanies/epiphanies_tmk_keyboard/tree/master/be_controllers), but has been cleaned up to match the [schematic](https://deskthority.net/wiki/File:Frosty_Flake_Schematics.pdf) and gone through some minor refactoring for QMK.
+
+## Quantum MK Firmware
+
+For the full Quantum feature list, see [the parent readme](/).
+
+## Building
+
+Download or clone the whole firmware and navigate to the keyboards/frosty_flake folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file. 
+
+Depending on which keymap you would like to use, you will have to compile slightly differently.
+
+### Default
+
+To build with the default keymap, simply run `make default`.
+
+### Other Keymaps
+
+Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
+
+To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
+
+```
+$ make [default|jack|<name>]
+```
+
+Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.

+ 71 - 0
keyboards/frosty_flake/rules.mk

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

+ 3 - 0
keyboards/handwired/atreus50/Makefile

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

+ 10 - 0
keyboards/handwired/atreus50/atreus50.c

@@ -0,0 +1,10 @@
+#include "atreus50.h"
+
+void matrix_init_kb(void) {
+
+    // Turn status LED on
+    //DDRE |= (1<<6);
+    PORTE |= (1<<6);
+
+	matrix_init_user();
+};

+ 36 - 0
keyboards/handwired/atreus50/atreus50.h

@@ -0,0 +1,36 @@
+#ifndef ATREUS50_H
+#define ATREUS50_H
+
+#include "quantum.h"
+
+// The first section contains all of the arguements
+// The second converts the arguments into a two-dimensional array
+#define KEYMAP( \
+  k00, k01, k02, k03, k04, k05,           k06, k07, k08, k09, k0a, k0b, \
+  k10, k11, k12, k13, k14, k15,           k16, k17, k18, k19, k1a, k1b, \
+  k20, k21, k22, k23, k24, k25,           k26, k27, k28, k29, k2a, k2b, \
+  k30, k31, k32, k33, k34, k35, km0, km1, k36, k37, k38, k39, k3a, k3b \
+) \
+{ \
+	{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
+	{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
+	{ k20, k21, k22, k23, k24, k25, km0,   k26, k27, k28, k29, k2a, k2b }, \
+	{ k30, k31, k32, k33, k34, k35, km1,   k36, k37, k38, k39, k3a, k3b } \
+}
+
+#define COMPACT_KEYMAP( \
+  k00, k01, k02, k03, k04, k05,           k06, k07, k08, k09, k0a, k0b, \
+  k10, k11, k12, k13, k14, k15,           k16, k17, k18, k19, k1a, k1b, \
+  k20, k21, k22, k23, k24, k25,           k26, k27, k28, k29, k2a, k2b, \
+  k30, k31, k32, k33, k34, k35, km0, km1, k36, k37, k38, k39, k3a, k3b \
+) \
+{ \
+    { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO,    KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \
+    { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO,    KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \
+    { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_##km0, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \
+    { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##km1, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b } \
+}
+
+#define KC_ KC_TRNS
+
+#endif

+ 163 - 0
keyboards/handwired/atreus50/config.h

@@ -0,0 +1,163 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID       0xBB80
+#define PRODUCT_ID      0x040D
+#define DEVICE_VER      0x0001
+#define MANUFACTURER    Hexwire
+#define PRODUCT         Atreus 50 Keyboard
+#define DESCRIPTION     Atreus layout with extra column
+
+/* key matrix size */
+#define MATRIX_ROWS 4
+#define MATRIX_COLS 13
+
+/* Planck PCB default pin-out */
+#define MATRIX_ROW_PINS { D3, D2, D1, D0 }
+#define MATRIX_COL_PINS { D4, D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4 }
+#define UNUSED_PINS
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION COL2ROW
+
+// #define BACKLIGHT_PIN B7
+// #define BACKLIGHT_BREATHING
+// #define BACKLIGHT_LEVELS 3
+
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCING_DELAY 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* number of backlight levels */
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+
+/* ws2812 RGB LED */
+#define RGB_DI_PIN C6
+#define RGBLIGHT_ANIMATIONS
+#define RGBLED_NUM 12     // Number of LEDs
+#define RGBLIGHT_HUE_STEP 10
+#define RGBLIGHT_SAT_STEP 17
+#define RGBLIGHT_VAL_STEP 17
+
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/*
+ * Magic Key Options
+ *
+ * Magic keys are hotkey commands that allow control over firmware functions of
+ * the keyboard. They are best used in combination with the HID Listen program,
+ * found here: https://www.pjrc.com/teensy/hid_listen.html
+ *
+ * The options below allow the magic key functionality to be changed. This is
+ * useful if your keyboard/keypad is missing keys and you want magic key support.
+ *
+ */
+
+/* key combination for magic key command */
+#define IS_COMMAND() ( \
+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/* control how magic key switches layers */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
+
+/* override magic key keymap */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
+//#define MAGIC_KEY_HELP1          H
+//#define MAGIC_KEY_HELP2          SLASH
+//#define MAGIC_KEY_DEBUG          D
+//#define MAGIC_KEY_DEBUG_MATRIX   X
+//#define MAGIC_KEY_DEBUG_KBD      K
+//#define MAGIC_KEY_DEBUG_MOUSE    M
+//#define MAGIC_KEY_VERSION        V
+//#define MAGIC_KEY_STATUS         S
+//#define MAGIC_KEY_CONSOLE        C
+//#define MAGIC_KEY_LAYER0_ALT1    ESC
+//#define MAGIC_KEY_LAYER0_ALT2    GRAVE
+//#define MAGIC_KEY_LAYER0         0
+//#define MAGIC_KEY_LAYER1         1
+//#define MAGIC_KEY_LAYER2         2
+//#define MAGIC_KEY_LAYER3         3
+//#define MAGIC_KEY_LAYER4         4
+//#define MAGIC_KEY_LAYER5         5
+//#define MAGIC_KEY_LAYER6         6
+//#define MAGIC_KEY_LAYER7         7
+//#define MAGIC_KEY_LAYER8         8
+//#define MAGIC_KEY_LAYER9         9
+//#define MAGIC_KEY_BOOTLOADER     PAUSE
+//#define MAGIC_KEY_LOCK           CAPS
+//#define MAGIC_KEY_EEPROM         E
+//#define MAGIC_KEY_NKRO           N
+//#define MAGIC_KEY_SLEEP_LED      Z
+
+/*
+ * Feature disable options
+ *  These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+#endif

+ 6 - 0
keyboards/handwired/atreus50/keymaps/default/Makefile

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

+ 250 - 0
keyboards/handwired/atreus50/keymaps/default/keymap.c

@@ -0,0 +1,250 @@
+#include "atreus50.h"
+#include "action_layer.h"
+#include "eeconfig.h"
+#ifdef AUDIO_ENABLE
+  #include "audio.h"
+#endif
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _MOVEMENT 5
+#define _ADJUST 16
+
+enum custom_keycodes {
+  QWERTY = SAFE_RANGE,
+  COLEMAK,
+  DVORAK,
+  LOWER,
+  RAISE,
+  MOVEMENT,
+  BACKLIT
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+#define KC_X0 MT(MOD_LCTL, KC_ESC)  // Hold for Left Ctrl, Tap for ESC
+#define KC_X1 LOWER
+#define KC_X2 RAISE
+#define KC_X3 MO(_MOVEMENT)
+#define KC_X4 MT(MOD_LSFT, KC_ENT)  // Hold for Left Shift, Tap for Enter
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+  [_QWERTY] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     TAB , Q  , W  , E  , R  , T  ,           Y  , U  , I  , O  , P  ,MINS,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+      X0 , A  , S  , D  , F  , G  ,           H  , J  , K  , L  ,SCLN,QUOT,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     LSFT, Z  , X  , C  , V  , B  ,           N  , M  ,COMM,DOT ,SLSH, X4 ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+     GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+  [_COLEMAK] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     TAB , Q  , W  , F  , P  , G  ,           J  , L  , U  , Y  ,SCLN,MINS,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+      X0 , A  , R  , S  , T  , D  ,           H  , N  , E  , I  , O  ,QUOT,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     LSFT, Z  , X  , C  , V  , B  ,           K  , M  ,COMM,DOT ,SLSH, X4 ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+     GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+  [_DVORAK] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     TAB ,QUOT,COMM,DOT , P  , Y  ,           F  , G  , C  , R  , L  ,MINS,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+      X0 , A  , O  , E  , U  , I  ,           D  , H  , R  , N  , S  ,SLSH,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     LSFT,SCLN, Q  , J  , K  , X  ,           B  , M  , W  , V  , Z  , X4 ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+     GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+  [_LOWER] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     TILD,EXLM, AT ,HASH,DLR ,PERC,          CIRC,AMPR,ASTR,LPRN,RPRN,DEL ,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     DEL , F1 , F2 , F3 , F4 , F5 ,           F6 ,UNDS,PLUS,LCBR,RCBR,PIPE,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+         , F7 , F8 , F9 ,F10 ,F11 ,          F12 ,END ,    ,    ,    ,    ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+         ,    ,    ,    ,    ,    ,    ,    ,    ,    ,MNXT,VOLD,VOLU,MPLY
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+  [_RAISE] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     GRV , 1  , 2  , 3  , 4  , 5  ,           6  , 7  , 8  , 9  , 0  ,DEL ,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     DEL , F1 , F2 , F3 , F4 , F5 ,           F6 ,MINS,EQL ,LBRC,RBRC,BSLS,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+         , F7 , F8 , F9 ,F10 ,F11 ,          F12 ,NUHS,NUBS,    ,    ,    ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+         ,    ,    ,    ,    ,    ,    ,    ,    ,    ,MNXT,VOLD,VOLU,MPLY
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+  [_MOVEMENT] = COMPACT_KEYMAP(
+  //,----+----+----+----+----+----.         ,----+----+----+----+----+----.
+     TILD,EXLM, AT ,HASH,DLR ,PERC,          CIRC,AMPR, UP ,LPRN,RPRN,DEL ,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+     DEL , F1 , F2 , F3 , F4 , F5 ,           F6 ,LEFT,DOWN,RGHT,RCBR,PIPE,
+  //|----+----+----+----+----+----|         |----+----+----+----+----+----|
+         , F7 , F8 , F9 ,F10 ,F11 ,          F12 ,END ,    ,    ,    ,    ,
+  //|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
+         ,    ,    ,    ,    ,    ,    ,    ,PGDN,PGUP,MNXT,VOLD,VOLU,MPLY
+  //`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
+  ),
+
+/* Adjust (Lower + Raise)
+ * |------+------+------+------+------+------.             ,------+------+------+------+------+------|
+ * |      | Reset|      |      |      |      |             |      |      |      |      |      |  Del |
+ * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+ * |      |      |      |Audoff|Aud on|AGnorm|             |AGswap|Qwerty|Colemk|Dvorak|      |      |
+ * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+ * |      |Voice-|Voice+|Musoff|Mus on|      |             |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |      |      |
+ * `-------------------------------------------------------------------------------------------------'
+ */
+  [_ADJUST] = KEYMAP( \
+    _______, RESET,   RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI,                   RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, _______, KC_DEL, \
+    _______, _______, _______, AU_ON,   AU_OFF,  AG_NORM,                   AG_SWAP, QWERTY,  COLEMAK, DVORAK,  _______, _______, \
+    _______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,                     MI_OFF,  _______, _______, _______, _______, _______, \
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
+  )
+
+};
+
+#ifdef AUDIO_ENABLE
+float tone_startup[][2] = {
+  {NOTE_B5, 20},
+  {NOTE_B6, 8},
+  {NOTE_DS6, 20},
+  {NOTE_B6, 8}
+};
+
+float tone_qwerty[][2]     = SONG(QWERTY_SOUND);
+float tone_dvorak[][2]     = SONG(DVORAK_SOUND);
+float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
+
+float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
+
+float music_scale[][2]     = SONG(MUSIC_SCALE_SOUND);
+#endif
+
+void persistant_default_layer_set(uint16_t default_layer) {
+  eeconfig_update_default_layer(default_layer);
+  default_layer_set(default_layer);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+        case QWERTY:
+          if (record->event.pressed) {
+            #ifdef AUDIO_ENABLE
+              PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
+            #endif
+            persistant_default_layer_set(1UL<<_QWERTY);
+          }
+          return false;
+          break;
+        case COLEMAK:
+          if (record->event.pressed) {
+            #ifdef AUDIO_ENABLE
+              PLAY_NOTE_ARRAY(tone_colemak, false, 0);
+            #endif
+            persistant_default_layer_set(1UL<<_COLEMAK);
+          }
+          return false;
+          break;
+        case DVORAK:
+          if (record->event.pressed) {
+            #ifdef AUDIO_ENABLE
+              PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
+            #endif
+            persistant_default_layer_set(1UL<<_DVORAK);
+          }
+          return false;
+          break;
+        case LOWER:
+          if (record->event.pressed) {
+            layer_on(_LOWER);
+            update_tri_layer(_LOWER, _RAISE, _ADJUST);
+          } else {
+            layer_off(_LOWER);
+            update_tri_layer(_LOWER, _RAISE, _ADJUST);
+          }
+          return false;
+          break;
+        case RAISE:
+          if (record->event.pressed) {
+            layer_on(_RAISE);
+            update_tri_layer(_LOWER, _RAISE, _ADJUST);
+          } else {
+            layer_off(_RAISE);
+            update_tri_layer(_LOWER, _RAISE, _ADJUST);
+          }
+          return false;
+          break;
+        case BACKLIT:
+          if (record->event.pressed) {
+            register_code(KC_RSFT);
+            #ifdef BACKLIGHT_ENABLE
+              backlight_step();
+            #endif
+          } else {
+            unregister_code(KC_RSFT);
+          }
+          return false;
+          break;
+      }
+    return true;
+};
+
+void matrix_init_user(void) {
+    #ifdef AUDIO_ENABLE
+        startup_user();
+    #endif
+}
+
+#ifdef AUDIO_ENABLE
+
+void startup_user()
+{
+    _delay_ms(20); // gets rid of tick
+    PLAY_NOTE_ARRAY(tone_startup, false, 0);
+}
+
+void shutdown_user()
+{
+    PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
+    _delay_ms(150);
+    stop_all_notes();
+}
+
+void music_on_user(void)
+{
+    music_scale_user();
+}
+
+void music_scale_user(void)
+{
+    PLAY_NOTE_ARRAY(music_scale, false, 0);
+}
+
+#endif

+ 16 - 0
keyboards/handwired/atreus50/readme.md

@@ -0,0 +1,16 @@
+Handwired Atreus50
+==================
+
+This firmware is for a Handwired Atreus50 using an Arduino Pro Micro.
+
+## Pinout
+
+The following pins are used:
+- Columns 1-13: D4, D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4
+- Rows 1-4: D3, D2, D1, D0
+
+## Compiling and loading the firmware
+
+To build the firmware, run `make`.
+
+To flash the firemware onto the microcontroller, run `make avrdude`, and press the reset button.

+ 81 - 0
keyboards/handwired/atreus50/rules.mk

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

+ 276 - 0
keyboards/lets_split/common/glcdfont.c

@@ -0,0 +1,276 @@
+// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
+// See gfxfont.h for newer custom bitmap font info.
+
+#ifndef FONT5X7_H
+#define FONT5X7_H
+
+#ifdef __AVR__
+ #include <avr/io.h>
+ #include <avr/pgmspace.h>
+#elif defined(ESP8266)
+ #include <pgmspace.h>
+#else
+ #define PROGMEM
+#endif
+
+// Standard ASCII 5x7 font
+
+static const unsigned char font[] PROGMEM = {
+	0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
+	0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
+	0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
+	0x18, 0x3C, 0x7E, 0x3C, 0x18,
+	0x1C, 0x57, 0x7D, 0x57, 0x1C,
+	0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
+	0x00, 0x18, 0x3C, 0x18, 0x00,
+	0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
+	0x00, 0x18, 0x24, 0x18, 0x00,
+	0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
+	0x30, 0x48, 0x3A, 0x06, 0x0E,
+	0x26, 0x29, 0x79, 0x29, 0x26,
+	0x40, 0x7F, 0x05, 0x05, 0x07,
+	0x40, 0x7F, 0x05, 0x25, 0x3F,
+	0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
+	0x7F, 0x3E, 0x1C, 0x1C, 0x08,
+	0x08, 0x1C, 0x1C, 0x3E, 0x7F,
+	0x14, 0x22, 0x7F, 0x22, 0x14,
+	0x5F, 0x5F, 0x00, 0x5F, 0x5F,
+	0x06, 0x09, 0x7F, 0x01, 0x7F,
+	0x00, 0x66, 0x89, 0x95, 0x6A,
+	0x60, 0x60, 0x60, 0x60, 0x60,
+	0x94, 0xA2, 0xFF, 0xA2, 0x94,
+	0x08, 0x04, 0x7E, 0x04, 0x08,
+	0x10, 0x20, 0x7E, 0x20, 0x10,
+	0x08, 0x08, 0x2A, 0x1C, 0x08,
+	0x08, 0x1C, 0x2A, 0x08, 0x08,
+	0x1E, 0x10, 0x10, 0x10, 0x10,
+	0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
+	0x30, 0x38, 0x3E, 0x38, 0x30,
+	0x06, 0x0E, 0x3E, 0x0E, 0x06,
+	0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x5F, 0x00, 0x00,
+	0x00, 0x07, 0x00, 0x07, 0x00,
+	0x14, 0x7F, 0x14, 0x7F, 0x14,
+	0x24, 0x2A, 0x7F, 0x2A, 0x12,
+	0x23, 0x13, 0x08, 0x64, 0x62,
+	0x36, 0x49, 0x56, 0x20, 0x50,
+	0x00, 0x08, 0x07, 0x03, 0x00,
+	0x00, 0x1C, 0x22, 0x41, 0x00,
+	0x00, 0x41, 0x22, 0x1C, 0x00,
+	0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
+	0x08, 0x08, 0x3E, 0x08, 0x08,
+	0x00, 0x80, 0x70, 0x30, 0x00,
+	0x08, 0x08, 0x08, 0x08, 0x08,
+	0x00, 0x00, 0x60, 0x60, 0x00,
+	0x20, 0x10, 0x08, 0x04, 0x02,
+	0x3E, 0x51, 0x49, 0x45, 0x3E,
+	0x00, 0x42, 0x7F, 0x40, 0x00,
+	0x72, 0x49, 0x49, 0x49, 0x46,
+	0x21, 0x41, 0x49, 0x4D, 0x33,
+	0x18, 0x14, 0x12, 0x7F, 0x10,
+	0x27, 0x45, 0x45, 0x45, 0x39,
+	0x3C, 0x4A, 0x49, 0x49, 0x31,
+	0x41, 0x21, 0x11, 0x09, 0x07,
+	0x36, 0x49, 0x49, 0x49, 0x36,
+	0x46, 0x49, 0x49, 0x29, 0x1E,
+	0x00, 0x00, 0x14, 0x00, 0x00,
+	0x00, 0x40, 0x34, 0x00, 0x00,
+	0x00, 0x08, 0x14, 0x22, 0x41,
+	0x14, 0x14, 0x14, 0x14, 0x14,
+	0x00, 0x41, 0x22, 0x14, 0x08,
+	0x02, 0x01, 0x59, 0x09, 0x06,
+	0x3E, 0x41, 0x5D, 0x59, 0x4E,
+	0x7C, 0x12, 0x11, 0x12, 0x7C,
+	0x7F, 0x49, 0x49, 0x49, 0x36,
+	0x3E, 0x41, 0x41, 0x41, 0x22,
+	0x7F, 0x41, 0x41, 0x41, 0x3E,
+	0x7F, 0x49, 0x49, 0x49, 0x41,
+	0x7F, 0x09, 0x09, 0x09, 0x01,
+	0x3E, 0x41, 0x41, 0x51, 0x73,
+	0x7F, 0x08, 0x08, 0x08, 0x7F,
+	0x00, 0x41, 0x7F, 0x41, 0x00,
+	0x20, 0x40, 0x41, 0x3F, 0x01,
+	0x7F, 0x08, 0x14, 0x22, 0x41,
+	0x7F, 0x40, 0x40, 0x40, 0x40,
+	0x7F, 0x02, 0x1C, 0x02, 0x7F,
+	0x7F, 0x04, 0x08, 0x10, 0x7F,
+	0x3E, 0x41, 0x41, 0x41, 0x3E,
+	0x7F, 0x09, 0x09, 0x09, 0x06,
+	0x3E, 0x41, 0x51, 0x21, 0x5E,
+	0x7F, 0x09, 0x19, 0x29, 0x46,
+	0x26, 0x49, 0x49, 0x49, 0x32,
+	0x03, 0x01, 0x7F, 0x01, 0x03,
+	0x3F, 0x40, 0x40, 0x40, 0x3F,
+	0x1F, 0x20, 0x40, 0x20, 0x1F,
+	0x3F, 0x40, 0x38, 0x40, 0x3F,
+	0x63, 0x14, 0x08, 0x14, 0x63,
+	0x03, 0x04, 0x78, 0x04, 0x03,
+	0x61, 0x59, 0x49, 0x4D, 0x43,
+	0x00, 0x7F, 0x41, 0x41, 0x41,
+	0x02, 0x04, 0x08, 0x10, 0x20,
+	0x00, 0x41, 0x41, 0x41, 0x7F,
+	0x04, 0x02, 0x01, 0x02, 0x04,
+	0x40, 0x40, 0x40, 0x40, 0x40,
+	0x00, 0x03, 0x07, 0x08, 0x00,
+	0x20, 0x54, 0x54, 0x78, 0x40,
+	0x7F, 0x28, 0x44, 0x44, 0x38,
+	0x38, 0x44, 0x44, 0x44, 0x28,
+	0x38, 0x44, 0x44, 0x28, 0x7F,
+	0x38, 0x54, 0x54, 0x54, 0x18,
+	0x00, 0x08, 0x7E, 0x09, 0x02,
+	0x18, 0xA4, 0xA4, 0x9C, 0x78,
+	0x7F, 0x08, 0x04, 0x04, 0x78,
+	0x00, 0x44, 0x7D, 0x40, 0x00,
+	0x20, 0x40, 0x40, 0x3D, 0x00,
+	0x7F, 0x10, 0x28, 0x44, 0x00,
+	0x00, 0x41, 0x7F, 0x40, 0x00,
+	0x7C, 0x04, 0x78, 0x04, 0x78,
+	0x7C, 0x08, 0x04, 0x04, 0x78,
+	0x38, 0x44, 0x44, 0x44, 0x38,
+	0xFC, 0x18, 0x24, 0x24, 0x18,
+	0x18, 0x24, 0x24, 0x18, 0xFC,
+	0x7C, 0x08, 0x04, 0x04, 0x08,
+	0x48, 0x54, 0x54, 0x54, 0x24,
+	0x04, 0x04, 0x3F, 0x44, 0x24,
+	0x3C, 0x40, 0x40, 0x20, 0x7C,
+	0x1C, 0x20, 0x40, 0x20, 0x1C,
+	0x3C, 0x40, 0x30, 0x40, 0x3C,
+	0x44, 0x28, 0x10, 0x28, 0x44,
+	0x4C, 0x90, 0x90, 0x90, 0x7C,
+	0x44, 0x64, 0x54, 0x4C, 0x44,
+	0x00, 0x08, 0x36, 0x41, 0x00,
+	0x00, 0x00, 0x77, 0x00, 0x00,
+	0x00, 0x41, 0x36, 0x08, 0x00,
+	0x02, 0x01, 0x02, 0x04, 0x02,
+	0x3C, 0x26, 0x23, 0x26, 0x3C,
+	0x1E, 0xA1, 0xA1, 0x61, 0x12,
+	0x3A, 0x40, 0x40, 0x20, 0x7A,
+	0x38, 0x54, 0x54, 0x55, 0x59,
+	0x21, 0x55, 0x55, 0x79, 0x41,
+	0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
+	0x21, 0x55, 0x54, 0x78, 0x40,
+	0x20, 0x54, 0x55, 0x79, 0x40,
+	0x0C, 0x1E, 0x52, 0x72, 0x12,
+	0x39, 0x55, 0x55, 0x55, 0x59,
+	0x39, 0x54, 0x54, 0x54, 0x59,
+	0x39, 0x55, 0x54, 0x54, 0x58,
+	0x00, 0x00, 0x45, 0x7C, 0x41,
+	0x00, 0x02, 0x45, 0x7D, 0x42,
+	0x00, 0x01, 0x45, 0x7C, 0x40,
+	0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut
+	0xF0, 0x28, 0x25, 0x28, 0xF0,
+	0x7C, 0x54, 0x55, 0x45, 0x00,
+	0x20, 0x54, 0x54, 0x7C, 0x54,
+	0x7C, 0x0A, 0x09, 0x7F, 0x49,
+	0x32, 0x49, 0x49, 0x49, 0x32,
+	0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
+	0x32, 0x4A, 0x48, 0x48, 0x30,
+	0x3A, 0x41, 0x41, 0x21, 0x7A,
+	0x3A, 0x42, 0x40, 0x20, 0x78,
+	0x00, 0x9D, 0xA0, 0xA0, 0x7D,
+	0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut
+	0x3D, 0x40, 0x40, 0x40, 0x3D,
+	0x3C, 0x24, 0xFF, 0x24, 0x24,
+	0x48, 0x7E, 0x49, 0x43, 0x66,
+	0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
+	0xFF, 0x09, 0x29, 0xF6, 0x20,
+	0xC0, 0x88, 0x7E, 0x09, 0x03,
+	0x20, 0x54, 0x54, 0x79, 0x41,
+	0x00, 0x00, 0x44, 0x7D, 0x41,
+	0x30, 0x48, 0x48, 0x4A, 0x32,
+	0x38, 0x40, 0x40, 0x22, 0x7A,
+	0x00, 0x7A, 0x0A, 0x0A, 0x72,
+	0x7D, 0x0D, 0x19, 0x31, 0x7D,
+	0x26, 0x29, 0x29, 0x2F, 0x28,
+	0x26, 0x29, 0x29, 0x29, 0x26,
+	0x30, 0x48, 0x4D, 0x40, 0x20,
+	0x38, 0x08, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x38,
+	0x2F, 0x10, 0xC8, 0xAC, 0xBA,
+	0x2F, 0x10, 0x28, 0x34, 0xFA,
+	0x00, 0x00, 0x7B, 0x00, 0x00,
+	0x08, 0x14, 0x2A, 0x14, 0x22,
+	0x22, 0x14, 0x2A, 0x14, 0x08,
+	0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code
+	0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
+	0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
+	0x00, 0x00, 0x00, 0xFF, 0x00,
+	0x10, 0x10, 0x10, 0xFF, 0x00,
+	0x14, 0x14, 0x14, 0xFF, 0x00,
+	0x10, 0x10, 0xFF, 0x00, 0xFF,
+	0x10, 0x10, 0xF0, 0x10, 0xF0,
+	0x14, 0x14, 0x14, 0xFC, 0x00,
+	0x14, 0x14, 0xF7, 0x00, 0xFF,
+	0x00, 0x00, 0xFF, 0x00, 0xFF,
+	0x14, 0x14, 0xF4, 0x04, 0xFC,
+	0x14, 0x14, 0x17, 0x10, 0x1F,
+	0x10, 0x10, 0x1F, 0x10, 0x1F,
+	0x14, 0x14, 0x14, 0x1F, 0x00,
+	0x10, 0x10, 0x10, 0xF0, 0x00,
+	0x00, 0x00, 0x00, 0x1F, 0x10,
+	0x10, 0x10, 0x10, 0x1F, 0x10,
+	0x10, 0x10, 0x10, 0xF0, 0x10,
+	0x00, 0x00, 0x00, 0xFF, 0x10,
+	0x10, 0x10, 0x10, 0x10, 0x10,
+	0x10, 0x10, 0x10, 0xFF, 0x10,
+	0x00, 0x00, 0x00, 0xFF, 0x14,
+	0x00, 0x00, 0xFF, 0x00, 0xFF,
+	0x00, 0x00, 0x1F, 0x10, 0x17,
+	0x00, 0x00, 0xFC, 0x04, 0xF4,
+	0x14, 0x14, 0x17, 0x10, 0x17,
+	0x14, 0x14, 0xF4, 0x04, 0xF4,
+	0x00, 0x00, 0xFF, 0x00, 0xF7,
+	0x14, 0x14, 0x14, 0x14, 0x14,
+	0x14, 0x14, 0xF7, 0x00, 0xF7,
+	0x14, 0x14, 0x14, 0x17, 0x14,
+	0x10, 0x10, 0x1F, 0x10, 0x1F,
+	0x14, 0x14, 0x14, 0xF4, 0x14,
+	0x10, 0x10, 0xF0, 0x10, 0xF0,
+	0x00, 0x00, 0x1F, 0x10, 0x1F,
+	0x00, 0x00, 0x00, 0x1F, 0x14,
+	0x00, 0x00, 0x00, 0xFC, 0x14,
+	0x00, 0x00, 0xF0, 0x10, 0xF0,
+	0x10, 0x10, 0xFF, 0x10, 0xFF,
+	0x14, 0x14, 0x14, 0xFF, 0x14,
+	0x10, 0x10, 0x10, 0x1F, 0x00,
+	0x00, 0x00, 0x00, 0xF0, 0x10,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+	0xFF, 0xFF, 0xFF, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xFF, 0xFF,
+	0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+	0x38, 0x44, 0x44, 0x38, 0x44,
+	0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
+	0x7E, 0x02, 0x02, 0x06, 0x06,
+	0x02, 0x7E, 0x02, 0x7E, 0x02,
+	0x63, 0x55, 0x49, 0x41, 0x63,
+	0x38, 0x44, 0x44, 0x3C, 0x04,
+	0x40, 0x7E, 0x20, 0x1E, 0x20,
+	0x06, 0x02, 0x7E, 0x02, 0x02,
+	0x99, 0xA5, 0xE7, 0xA5, 0x99,
+	0x1C, 0x2A, 0x49, 0x2A, 0x1C,
+	0x4C, 0x72, 0x01, 0x72, 0x4C,
+	0x30, 0x4A, 0x4D, 0x4D, 0x30,
+	0x30, 0x48, 0x78, 0x48, 0x30,
+	0xBC, 0x62, 0x5A, 0x46, 0x3D,
+	0x3E, 0x49, 0x49, 0x49, 0x00,
+	0x7E, 0x01, 0x01, 0x01, 0x7E,
+	0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+	0x44, 0x44, 0x5F, 0x44, 0x44,
+	0x40, 0x51, 0x4A, 0x44, 0x40,
+	0x40, 0x44, 0x4A, 0x51, 0x40,
+	0x00, 0x00, 0xFF, 0x01, 0x03,
+	0xE0, 0x80, 0xFF, 0x00, 0x00,
+	0x08, 0x08, 0x6B, 0x6B, 0x08,
+	0x36, 0x12, 0x36, 0x24, 0x36,
+	0x06, 0x0F, 0x09, 0x0F, 0x06,
+	0x00, 0x00, 0x18, 0x18, 0x00,
+	0x00, 0x00, 0x10, 0x10, 0x00,
+	0x30, 0x40, 0xFF, 0x01, 0x01,
+	0x00, 0x1F, 0x01, 0x01, 0x1E,
+	0x00, 0x19, 0x1D, 0x17, 0x12,
+	0x00, 0x3C, 0x3C, 0x3C, 0x3C,
+	0x00, 0x00, 0x00, 0x00, 0x00  // #255 NBSP
+};
+#endif // FONT5X7_H

+ 19 - 1
keyboards/lets_split/i2c.h

@@ -16,7 +16,7 @@
 #define SLAVE_BUFFER_SIZE 0x10
 
 // i2c SCL clock frequency
-#define SCL_CLOCK  100000L
+#define SCL_CLOCK  400000L
 
 extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
 
@@ -28,4 +28,22 @@ uint8_t i2c_master_read(int);
 void i2c_reset_state(void);
 void i2c_slave_init(uint8_t address);
 
+
+static inline unsigned char i2c_start_read(unsigned char addr) {
+  return i2c_master_start((addr << 1) | I2C_READ);
+}
+
+static inline unsigned char i2c_start_write(unsigned char addr) {
+  return i2c_master_start((addr << 1) | I2C_WRITE);
+}
+
+// from SSD1306 scrips
+extern unsigned char i2c_rep_start(unsigned char addr);
+extern void i2c_start_wait(unsigned char addr);
+extern unsigned char i2c_readAck(void);
+extern unsigned char i2c_readNak(void);
+extern unsigned char i2c_read(unsigned char ack);
+
+#define i2c_read(ack)  (ack) ? i2c_readAck() : i2c_readNak();
+
 #endif

+ 25 - 0
keyboards/lets_split/keymaps/OLED_sample/Makefile

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

+ 45 - 0
keyboards/lets_split/keymaps/OLED_sample/config.h

@@ -0,0 +1,45 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define USE_I2C
+//#define USE_SERIAL
+//#define MASTER_RIGHT
+#define FLIP_HALF
+
+#define SSD1306OLED
+
+
+#define PREVENT_STUCK_MODIFIERS
+#define TAPPING_FORCE_HOLD
+#define TAPPING_TERM 100
+
+#undef RGBLED_NUM
+#define RGBLIGHT_ANIMATIONS
+#define RGBLED_NUM 6
+#define RGBLIGHT_HUE_STEP 10
+#define RGBLIGHT_SAT_STEP 17
+#define RGBLIGHT_VAL_STEP 17
+
+
+
+
+#ifdef SUBPROJECT_rev1
+    #include "../../rev1/config.h"
+#endif
+#ifdef SUBPROJECT_rev2
+    #include "../../rev2/config.h"
+#endif

+ 356 - 0
keyboards/lets_split/keymaps/OLED_sample/keymap.c

@@ -0,0 +1,356 @@
+#include "lets_split.h"
+#include "bootloader.h"
+#include "action_layer.h"
+#include "eeconfig.h"
+#include "tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/Peripheral/TWI.h"
+#ifdef AUDIO_ENABLE
+  #include "audio.h"
+#endif
+
+extern keymap_config_t keymap_config;
+
+//Following line allows macro to read current RGB settings
+extern rgblight_config_t rgblight_config;
+
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _ADJUST 16
+
+enum custom_keycodes {
+  QWERTY = SAFE_RANGE,
+  COLEMAK,
+  DVORAK,
+  LOWER,
+  RAISE,
+  ADJUST,
+  BACKLIT,
+  RGBLED_TOGGLE,
+  RGBLED_STEP_MODE,
+  RGBLED_INCREASE_HUE,
+  RGBLED_DECREASE_HUE,
+  RGBLED_INCREASE_SAT,
+  RGBLED_DECREASE_SAT,
+  RGBLED_INCREASE_VAL,
+  RGBLED_DECREASE_VAL,
+};
+
+enum macro_keycodes {
+  KC_SAMPLEMACRO,
+};
+
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+//Macros
+#define M_SAMPLE M(KC_SAMPLEMACRO)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |Adjust| Ctrl | Alt  | GUI  |Lower |Space |Space |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = KEYMAP( \
+  KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC, \
+  KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT, \
+  KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT , \
+  ADJUST,  KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT \
+),
+
+/* Colemak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |Adjust| Ctrl | Alt  | GUI  |Lower |Space |Space |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = KEYMAP( \
+  KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC, \
+  KC_ESC,  KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT, \
+  KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT , \
+  ADJUST,  KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT \
+),
+
+/* Dvorak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   "  |   ,  |   .  |   P  |   Y  |   F  |   G  |   C  |   R  |   L  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   O  |   E  |   U  |   I  |   D  |   H  |   T  |   N  |   S  |  /   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   ;  |   Q  |   J  |   K  |   X  |   B  |   M  |   W  |   V  |   Z  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |Adjust| Ctrl | Alt  | GUI  |Lower |Space |Space |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_DVORAK] = KEYMAP( \
+  KC_TAB,  KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,    KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    KC_BSPC, \
+  KC_ESC,  KC_A,    KC_O,    KC_E,    KC_U,    KC_I,    KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    KC_SLSH, \
+  KC_LSFT, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,    KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    KC_ENT , \
+  ADJUST,  KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT \
+),
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   _  |   +  |     |    \  |  |   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO ~ |ISO | |      |      |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = KEYMAP( \
+  KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
+  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
+  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * |   `  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   -  |   =  |   [  |   ]  |  \   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO # |ISO / |      |      |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = KEYMAP( \
+  KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC, \
+  KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS, \
+  _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NUHS, KC_NUBS, _______, _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Adjust (Lower + Raise)
+ * ,-----------------------------------------------------------------------------------.
+ * |      | Reset|      |      |      |      |      |      |      |      |      |  Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |      |      |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|      |      |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] =  KEYMAP( \
+  _______, RESET,   _______, M_SAMPLE, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
+  _______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, AG_SWAP, QWERTY,  COLEMAK, DVORAK,  _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
+)
+
+
+};
+
+
+#ifdef AUDIO_ENABLE
+
+float tone_startup[][2]    = SONG(STARTUP_SOUND);
+float tone_qwerty[][2]     = SONG(QWERTY_SOUND);
+float tone_dvorak[][2]     = SONG(DVORAK_SOUND);
+float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
+float tone_plover[][2]     = SONG(PLOVER_SOUND);
+float tone_plover_gb[][2]  = SONG(PLOVER_GOODBYE_SOUND);
+float music_scale[][2]     = SONG(MUSIC_SCALE_SOUND);
+float tone_goodbye[][2]    = SONG(GOODBYE_SOUND);
+#endif
+
+// define variables for reactive RGB
+bool TOG_STATUS = false;
+int RGB_current_mode;
+
+void persistant_default_layer_set(uint16_t default_layer) {
+  eeconfig_update_default_layer(default_layer);
+  default_layer_set(default_layer);
+}
+
+// Setting ADJUST layer RGB back to default
+void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
+  if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
+    rgblight_mode(RGB_current_mode);
+    layer_on(layer3);
+  } else {
+    layer_off(layer3);
+  }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    case QWERTY:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_QWERTY);
+      }
+      return false;
+      break;
+    case COLEMAK:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_colemak, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_COLEMAK);
+      }
+      return false;
+      break;
+    case DVORAK:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_DVORAK);
+      }
+      return false;
+      break;
+    case LOWER:
+      if (record->event.pressed) {
+          //not sure how to have keyboard check mode and set it to a variable, so my work around
+          //uses another variable that would be set to true after the first time a reactive key is pressed.
+        if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+        } else {
+          TOG_STATUS = !TOG_STATUS;
+          rgblight_mode(16);
+        }
+        layer_on(_LOWER);
+        update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+      } else {
+        rgblight_mode(RGB_current_mode);   // revert RGB to initial mode prior to RGB mode change
+        TOG_STATUS = false;
+        layer_off(_LOWER);
+        update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case RAISE:
+      if (record->event.pressed) {
+        //not sure how to have keyboard check mode and set it to a variable, so my work around
+        //uses another variable that would be set to true after the first time a reactive key is pressed.
+        if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+        } else {
+          TOG_STATUS = !TOG_STATUS;
+          rgblight_mode(15);
+        }
+        layer_on(_RAISE);
+        update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+      } else {
+        rgblight_mode(RGB_current_mode);  // revert RGB to initial mode prior to RGB mode change
+        layer_off(_RAISE);
+        TOG_STATUS = false;
+        update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case BACKLIT:
+      if (record->event.pressed) {
+        register_code(KC_RSFT);
+        #ifdef BACKLIGHT_ENABLE
+          backlight_step();
+        #endif
+      } else {
+        unregister_code(KC_RSFT);
+      }
+      return false;
+      break;
+      //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
+    case RGB_MOD:
+      if (record->event.pressed) {
+        rgblight_mode(RGB_current_mode);
+        rgblight_step();
+        RGB_current_mode = rgblight_config.mode;
+      }
+      return false;
+      break;
+  }
+  return true;
+}
+
+void matrix_init_user(void) {
+    #ifdef AUDIO_ENABLE
+        startup_user();
+    #endif
+    RGB_current_mode = rgblight_config.mode; 
+}
+
+//SSD1306 OLED init and update loop, make sure to add #define SSD1306OLED in config.h
+#ifdef SSD1306OLED
+void matrix_master_OLED_init (void) {
+    TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
+    iota_gfx_init();   // turns on the display   
+}
+
+void matrix_scan_user(void) {
+     iota_gfx_task();  // this is what updates the display continuously
+}
+#endif
+
+#ifdef AUDIO_ENABLE
+
+void startup_user()
+{
+    _delay_ms(20); // gets rid of tick
+    PLAY_NOTE_ARRAY(tone_startup, false, 0);
+}
+
+void shutdown_user()
+{
+    PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
+    _delay_ms(150);
+    stop_all_notes();
+}
+
+void music_on_user(void)
+{
+    music_scale_user();
+}
+
+void music_scale_user(void)
+{
+    PLAY_NOTE_ARRAY(music_scale, false, 0);
+}
+
+#endif
+
+/*
+ * Macro definition
+ */
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+    if (!eeconfig_is_enabled()) {
+      eeconfig_init();
+    }
+
+    switch (id) {
+      case KC_SAMPLEMACRO:
+        if (record->event.pressed){
+          return MACRO (I(10), T(H), T(E), T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
+        }
+ 
+    }
+
+    return MACRO_NONE;
+}

+ 25 - 0
keyboards/lets_split/keymaps/OLED_sample/readme.md

@@ -0,0 +1,25 @@
+SSD1306 OLED Display via I2C
+======
+
+Features
+--------
+
+Some features supported by the firmware:
+
+
+* I2C connection between the two halves is required as the OLED display will use this connection as well. Note this
+  requires pull-up resistors on the data and clock lines.
+* OLED display will connect from either side
+
+
+Wiring
+------
+
+
+Work in progress...
+
+
+OLED Configuration
+-------------------------------
+
+Work in progress...

+ 4 - 0
keyboards/lets_split/keymaps/hexwire/Makefile

@@ -1 +1,5 @@
 RGBLIGHT_ENABLE = yes
+
+ifndef QUANTUM_DIR
+	include ../../../../Makefile
+endif

+ 0 - 23
keyboards/lets_split/keymaps/hexwire/compact_keymap.h

@@ -1,23 +0,0 @@
-#ifndef COMPACT_KEYMAP_H
-#define COMPACT_KEYMAP_H
-
-#define COMPACT_KEYMAP( \
-  k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
-  k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
-  k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
-  k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
-  ) \
-  { \
-    { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05 }, \
-    { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15 }, \
-    { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25 }, \
-    { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35 }, \
-    { KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45 }, \
-    { KC_##k50, KC_##k51, KC_##k52, KC_##k53, KC_##k54, KC_##k55 }, \
-    { KC_##k60, KC_##k61, KC_##k62, KC_##k63, KC_##k64, KC_##k65 }, \
-    { KC_##k70, KC_##k71, KC_##k72, KC_##k73, KC_##k74, KC_##k75 } \
-  }
-
-#define KC_ KC_TRNS
-
-#endif

+ 33 - 2
keyboards/lets_split/keymaps/hexwire/config.h

@@ -18,10 +18,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #define USE_SERIAL
 
-#define EE_HANDS
+#define TAPPING_TERM 150
 
 #undef RGBLED_NUM
-#define RGB_DI_PIN B0
 #define RGBLIGHT_ANIMATIONS
 #define RGBLED_NUM 8
 #define RGBLIGHT_HUE_STEP 8
@@ -30,9 +29,41 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #ifdef SUBPROJECT_rev1
     #include "../../rev1/config.h"
+    #define COMPACT_KEYMAP( \
+      k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
+      k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
+      k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
+      k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
+    ) \
+    { \
+      { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05 }, \
+      { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15 }, \
+      { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25 }, \
+      { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35 }, \
+      { KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45 }, \
+      { KC_##k50, KC_##k51, KC_##k52, KC_##k53, KC_##k54, KC_##k55 }, \
+      { KC_##k60, KC_##k61, KC_##k62, KC_##k63, KC_##k64, KC_##k65 }, \
+      { KC_##k70, KC_##k71, KC_##k72, KC_##k73, KC_##k74, KC_##k75 } \
+    }
 #endif
 #ifdef SUBPROJECT_rev2
     #include "../../rev2/config.h"
+    #define COMPACT_KEYMAP( \
+      k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
+      k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
+      k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
+      k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
+      ) \
+      { \
+        { KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05 }, \
+        { KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15 }, \
+        { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25 }, \
+        { KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35 }, \
+        { KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45 }, \
+        { KC_##k50, KC_##k51, KC_##k52, KC_##k53, KC_##k54, KC_##k55 }, \
+        { KC_##k60, KC_##k61, KC_##k62, KC_##k63, KC_##k64, KC_##k65 }, \
+        { KC_##k70, KC_##k71, KC_##k72, KC_##k73, KC_##k74, KC_##k75 } \
+      }
 #endif
 #ifdef SUBPROJECT_rev2fliphalf
 	#include "../../rev2fliphalf/config.h"

+ 1 - 1
keyboards/lets_split/keymaps/hexwire/keymap.c

@@ -1,7 +1,6 @@
 #include "lets_split.h"
 #include "action_layer.h"
 #include "eeconfig.h"
-#include "compact_keymap.h"
 
 extern keymap_config_t keymap_config;
 
@@ -25,6 +24,7 @@ enum custom_keycodes {
   ADJUST,
 };
 
+#define KC_ KC_TRNS
 #define _______ KC_TRNS
 
 #define KC_CAPW LGUI(LSFT(KC_3))        // Capture whole screen

+ 0 - 2
keyboards/lets_split/matrix.c

@@ -226,9 +226,7 @@ uint8_t matrix_scan(void)
         TXLED0;
         error_count = 0;
     }
-
     matrix_scan_quantum();
-
     return ret;
 }
 

+ 7 - 0
keyboards/lets_split/rev1/config.h

@@ -63,6 +63,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
 )
 
+/* ws2812 RGB LED */
+#define RGB_DI_PIN D3
+#define RGBLIGHT_TIMER
+#define RGBLED_NUM 16    // Number of LEDs
+#define ws2812_PORTREG  PORTD
+#define ws2812_DDRREG   DDRD
+
 /*
  * Feature disable options
  *  These options are also useful to firmware size reduction.

+ 8 - 0
keyboards/lets_split/rev2/rev2.c

@@ -5,6 +5,13 @@
     float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
 #endif
 
+#ifdef SSD1306OLED
+void led_set_kb(uint8_t usb_led) {
+    // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
+    led_set_user(usb_led);
+}
+#endif
+
 void matrix_init_kb(void) {
 
     #ifdef AUDIO_ENABLE
@@ -30,3 +37,4 @@ void shutdown_user(void) {
 	stop_all_notes();
     #endif
 }
+

+ 51 - 8
keyboards/lets_split/rev2/rev2.h

@@ -6,23 +6,66 @@
 //void promicro_bootloader_jmp(bool program);
 #include "quantum.h"
 
+
+#ifdef USE_I2C
+#include <stddef.h>
+#ifdef __AVR__
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#endif
+#ifdef SSD1306OLED
+extern bool iota_gfx_init(void);
+extern void iota_gfx_task(void);
+extern bool iota_gfx_off(void);
+extern bool iota_gfx_on(void);
+extern void iota_gfx_flush(void);
+extern void iota_gfx_write_char(uint8_t c);
+extern void iota_gfx_write(const char *data);
+extern void iota_gfx_write_P(const char *data);
+extern void iota_gfx_clear_screen(void);
+#endif
+#endif
+
 //void promicro_bootloader_jmp(bool program);
 
+#ifndef FLIP_HALF
+//Standard Keymap
 #define KEYMAP( \
-	k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
-	k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
-	k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
-	k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
+	k40, k41, k42, k43, k44, k45, k05, k04, k03, k02, k01, k00, \
+	k50, k51, k52, k53, k54, k55, k15, k14, k13, k12, k11, k10, \
+	k60, k61, k62, k63, k64, k65, k25, k24, k23, k22, k21, k20, \
+	k70, k71, k72, k73, k74, k75, k35, k34, k33, k32, k31, k30 \
+	) \
+	{ \
+		{ k45, k44, k43, k42, k41, k40 }, \
+		{ k55, k54, k53, k52, k51, k50 }, \
+		{ k65, k64, k63, k62, k61, k60 }, \
+		{ k75, k74, k73, k72, k71, k70 }, \
+		{ k00, k01, k02, k03, k04, k05 }, \
+		{ k10, k11, k12, k13, k14, k15 }, \
+		{ k20, k21, k22, k23, k24, k25 }, \
+		{ k30, k31, k32, k33, k34, k35 } \
+	}
+
+#else
+// Keymap with one side flipped
+#define KEYMAP( \
+	k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
+	k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
+	k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
+	k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
 	) \
 	{ \
 		{ k00, k01, k02, k03, k04, k05 }, \
 		{ k10, k11, k12, k13, k14, k15 }, \
 		{ k20, k21, k22, k23, k24, k25 }, \
 		{ k30, k31, k32, k33, k34, k35 }, \
-		{ k40, k41, k42, k43, k44, k45 }, \
-		{ k50, k51, k52, k53, k54, k55 }, \
-		{ k60, k61, k62, k63, k64, k65 }, \
-		{ k70, k71, k72, k73, k74, k75 } \
+		{ k45, k44, k43, k42, k41, k40 }, \
+		{ k55, k54, k53, k52, k51, k50 }, \
+		{ k65, k64, k63, k62, k61, k60 }, \
+		{ k75, k74, k73, k72, k71, k70 } \
 	}
+#endif
+
 
 #endif

+ 0 - 32
keyboards/lets_split/rev2fliphalf/rev2fliphalf.c

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

+ 0 - 28
keyboards/lets_split/rev2fliphalf/rev2fliphalf.h

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

+ 0 - 5
keyboards/lets_split/rev2fliphalf/rules.mk

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

+ 2 - 13
keyboards/lets_split/rules.mk

@@ -1,7 +1,8 @@
 SRC += matrix.c \
 	   i2c.c \
 	   split_util.c \
-	   serial.c
+	   serial.c\
+	   ssd1306.c
 
 # MCU name
 #MCU = at90usb1287
@@ -73,15 +74,3 @@ USE_I2C ?= yes
 SLEEP_LED_ENABLE ?= no    # Breathing sleep LED during USB suspend
 
 CUSTOM_MATRIX = yes
-
-avrdude: build
-	ls /dev/tty* > /tmp/1; \
-	echo "Reset your Pro Micro now"; \
-	while [[ -z $$USB ]]; do \
-	  sleep 1; \
-	  ls /dev/tty* > /tmp/2; \
-	  USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
-	done; \
-	avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
-
-.PHONY: avrdude

+ 4 - 1
keyboards/lets_split/split_util.c

@@ -21,7 +21,7 @@ static void setup_handedness(void) {
   #ifdef EE_HANDS
     isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
   #else
-    // I2C_MASTER_RIGHT is deprecated use MASTER_RIGHT instead since this works for both serial and i2c
+    // I2c_MASTER_RIGHT ish deprecate use MASTER_RIGHT instead since this works for both serial and i2c:
     #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
       isLeftHand = !has_usb();
     #else
@@ -33,6 +33,9 @@ static void setup_handedness(void) {
 static void keyboard_master_setup(void) {
 #ifdef USE_I2C
     i2c_master_init();
+#ifdef SSD1306OLED
+    matrix_master_OLED_init ();
+#endif
 #else
     serial_master_init();
 #endif

+ 2 - 0
keyboards/lets_split/split_util.h

@@ -19,4 +19,6 @@ void split_keyboard_setup(void);
 bool has_usb(void);
 void keyboard_slave_loop(void);
 
+void matrix_master_OLED_init (void);
+
 #endif

+ 468 - 0
keyboards/lets_split/ssd1306.c

@@ -0,0 +1,468 @@
+#include "config.h"
+#include "i2c.h"
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include "print.h"
+#include "lets_split.h"
+#include "common/glcdfont.c"
+#ifdef ADAFRUIT_BLE_ENABLE
+#include "adafruit_ble.h"
+#endif
+#ifdef PROTOCOL_LUFA
+#include "lufa.h"
+#endif
+#include "sendchar.h"
+#include "pincontrol.h"
+
+//assign the right code to your layers
+#define _BASE 0
+#define _LOWER 8
+#define _RAISE 16
+#define _FNLAYER 64
+#define _NUMLAY 128
+#define _NLOWER 136
+#define _NFNLAYER 192
+#define _MOUSECURSOR 256
+#define _ADJUST 65560
+
+// Set this to 1 to help diagnose early startup problems
+// when testing power-on with ble.  Turn it off otherwise,
+// as the latency of printing most of the debug info messes
+// with the matrix scan, causing keys to drop.
+#define DEBUG_TO_SCREEN 0
+
+// Controls the SSD1306 128x32 OLED display via i2c
+
+#define i2cAddress 0x3C
+
+#define DisplayHeight 32
+#define DisplayWidth 128
+
+#define FontHeight 8
+#define FontWidth 6
+
+#define MatrixRows (DisplayHeight / FontHeight)
+#define MatrixCols (DisplayWidth / FontWidth)
+
+struct CharacterMatrix {
+  uint8_t display[MatrixRows][MatrixCols];
+  uint8_t *cursor;
+  bool dirty;
+};
+
+static struct CharacterMatrix display;
+//static uint16_t last_battery_update;
+//static uint32_t vbat;
+//#define BatteryUpdateInterval 10000 /* milliseconds */
+#define ScreenOffInterval 300000 /* milliseconds */
+#if DEBUG_TO_SCREEN
+static uint8_t displaying;
+#endif
+static uint16_t last_flush;
+
+enum ssd1306_cmds {
+  DisplayOff = 0xAE,
+  DisplayOn = 0xAF,
+
+  SetContrast = 0x81,
+  DisplayAllOnResume = 0xA4,
+
+  DisplayAllOn = 0xA5,
+  NormalDisplay = 0xA6,
+  InvertDisplay = 0xA7,
+  SetDisplayOffset = 0xD3,
+  SetComPins = 0xda,
+  SetVComDetect = 0xdb,
+  SetDisplayClockDiv = 0xD5,
+  SetPreCharge = 0xd9,
+  SetMultiPlex = 0xa8,
+  SetLowColumn = 0x00,
+  SetHighColumn = 0x10,
+  SetStartLine = 0x40,
+
+  SetMemoryMode = 0x20,
+  ColumnAddr = 0x21,
+  PageAddr = 0x22,
+
+  ComScanInc = 0xc0,
+  ComScanDec = 0xc8,
+  SegRemap = 0xa0,
+  SetChargePump = 0x8d,
+  ExternalVcc = 0x01,
+  SwitchCapVcc = 0x02,
+
+  ActivateScroll = 0x2f,
+  DeActivateScroll = 0x2e,
+  SetVerticalScrollArea = 0xa3,
+  RightHorizontalScroll = 0x26,
+  LeftHorizontalScroll = 0x27,
+  VerticalAndRightHorizontalScroll = 0x29,
+  VerticalAndLeftHorizontalScroll = 0x2a,
+};
+
+
+// Write command sequence.
+// Returns true on success.
+static inline bool _send_cmd1(uint8_t cmd) {
+  bool res = false;
+
+  if (i2c_start_write(i2cAddress)) {
+    xprintf("failed to start write to %d\n", i2cAddress);
+    goto done;
+  }
+
+  if (i2c_master_write(0x0 /* command byte follows */)) {
+    print("failed to write control byte\n");
+
+    goto done;
+  }
+
+  if (i2c_master_write(cmd)) {
+    xprintf("failed to write command %d\n", cmd);
+    goto done;
+  }
+  res = true;
+done:
+  i2c_master_stop();
+  return res;
+}
+
+// Write 2-byte command sequence.
+// Returns true on success
+static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
+  if (!_send_cmd1(cmd)) {
+    return false;
+  }
+  return _send_cmd1(opr);
+}
+
+// Write 3-byte command sequence.
+// Returns true on success
+static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
+  if (!_send_cmd1(cmd)) {
+    return false;
+  }
+  if (!_send_cmd1(opr1)) {
+    return false;
+  }
+  return _send_cmd1(opr2);
+}
+
+#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
+#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
+#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
+
+static void matrix_clear(struct CharacterMatrix *matrix);
+
+static void clear_display(void) {
+  matrix_clear(&display);
+
+  // Clear all of the display bits (there can be random noise
+  // in the RAM on startup)
+  send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
+  send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
+
+  if (i2c_start_write(i2cAddress)) {
+    goto done;
+  }
+  if (i2c_master_write(0x40)) {
+    // Data mode
+    goto done;
+  }
+  for (uint8_t row = 0; row < MatrixRows; ++row) {
+    for (uint8_t col = 0; col < DisplayWidth; ++col) {
+      i2c_master_write(0);
+    }
+  }
+
+  display.dirty = false;
+
+done:
+  i2c_master_stop();
+}
+
+#if DEBUG_TO_SCREEN
+#undef sendchar
+static int8_t capture_sendchar(uint8_t c) {
+  sendchar(c);
+  iota_gfx_write_char(c);
+
+  if (!displaying) {
+    iota_gfx_flush();
+  }
+  return 0;
+}
+#endif
+
+bool iota_gfx_init(void) {
+  bool success = false;
+
+  send_cmd1(DisplayOff);
+  send_cmd2(SetDisplayClockDiv, 0x80);
+  send_cmd2(SetMultiPlex, DisplayHeight - 1);
+
+  send_cmd2(SetDisplayOffset, 0);
+
+
+  send_cmd1(SetStartLine | 0x0);
+  send_cmd2(SetChargePump, 0x14 /* Enable */);
+  send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
+
+/// Flips the display orientation 0 degrees
+  send_cmd1(SegRemap | 0x1);
+  send_cmd1(ComScanDec);
+/*
+// the following Flip the display orientation 180 degrees
+  send_cmd1(SegRemap);
+  send_cmd1(ComScanInc);
+// end flip */
+  send_cmd2(SetComPins, 0x2);
+  send_cmd2(SetContrast, 0x8f);
+  send_cmd2(SetPreCharge, 0xf1);
+  send_cmd2(SetVComDetect, 0x40);
+  send_cmd1(DisplayAllOnResume);
+  send_cmd1(NormalDisplay);
+  send_cmd1(DeActivateScroll);
+  send_cmd1(DisplayOn);
+
+  send_cmd2(SetContrast, 0); // Dim
+
+  clear_display();
+
+  success = true;
+
+  iota_gfx_flush();
+
+#if DEBUG_TO_SCREEN
+  print_set_sendchar(capture_sendchar);
+#endif
+
+done:
+  return success;
+}
+
+bool iota_gfx_off(void) {
+  bool success = false;
+
+  send_cmd1(DisplayOff);
+  success = true;
+
+done:
+  return success;
+} 
+
+bool iota_gfx_on(void) {
+  bool success = false;
+
+  send_cmd1(DisplayOn);
+  success = true;
+
+done:
+  return success;
+}
+
+static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
+  *matrix->cursor = c;
+  ++matrix->cursor;
+
+  if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
+    // We went off the end; scroll the display upwards by one line
+    memmove(&matrix->display[0], &matrix->display[1],
+            MatrixCols * (MatrixRows - 1));
+    matrix->cursor = &matrix->display[MatrixRows - 1][0];
+    memset(matrix->cursor, ' ', MatrixCols);
+  }
+}
+
+static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
+  matrix->dirty = true;
+
+  if (c == '\n') {
+    // Clear to end of line from the cursor and then move to the
+    // start of the next line
+    uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
+
+    while (cursor_col++ < MatrixCols) {
+      matrix_write_char_inner(matrix, ' ');
+    }
+    return;
+  }
+
+  matrix_write_char_inner(matrix, c);
+}
+
+void iota_gfx_write_char(uint8_t c) {
+  matrix_write_char(&display, c);
+}
+
+static void matrix_write(struct CharacterMatrix *matrix, const char *data) {
+  const char *end = data + strlen(data);
+  while (data < end) {
+    matrix_write_char(matrix, *data);
+    ++data;
+  }
+}
+
+void iota_gfx_write(const char *data) {
+  matrix_write(&display, data);
+}
+
+static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
+  while (true) {
+    uint8_t c = pgm_read_byte(data);
+    if (c == 0) {
+      return;
+    }
+    matrix_write_char(matrix, c);
+    ++data;
+  }
+}
+
+void iota_gfx_write_P(const char *data) {
+  matrix_write_P(&display, data);
+}
+
+static void matrix_clear(struct CharacterMatrix *matrix) {
+  memset(matrix->display, ' ', sizeof(matrix->display));
+  matrix->cursor = &matrix->display[0][0];
+  matrix->dirty = true;
+}
+
+void iota_gfx_clear_screen(void) {
+  matrix_clear(&display);
+}
+
+static void matrix_render(struct CharacterMatrix *matrix) {
+  last_flush = timer_read();
+  iota_gfx_on();
+#if DEBUG_TO_SCREEN
+  ++displaying;
+#endif
+
+  // Move to the home position
+  send_cmd3(PageAddr, 0, MatrixRows - 1);
+  send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
+
+  if (i2c_start_write(i2cAddress)) {
+    goto done;
+  }
+  if (i2c_master_write(0x40)) {
+    // Data mode
+    goto done;
+  }
+
+  for (uint8_t row = 0; row < MatrixRows; ++row) {
+    for (uint8_t col = 0; col < MatrixCols; ++col) {
+      const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1));
+
+      for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) {
+        uint8_t colBits = pgm_read_byte(glyph + glyphCol);
+        i2c_master_write(colBits);
+      }
+
+      // 1 column of space between chars (it's not included in the glyph)
+      i2c_master_write(0);
+    }
+  }
+
+  matrix->dirty = false;
+
+done:
+  i2c_master_stop();
+#if DEBUG_TO_SCREEN
+  --displaying;
+#endif
+}
+
+void iota_gfx_flush(void) {
+  matrix_render(&display);
+}
+
+static void matrix_update(struct CharacterMatrix *dest,
+                          const struct CharacterMatrix *source) {
+  if (memcmp(dest->display, source->display, sizeof(dest->display))) {
+    memcpy(dest->display, source->display, sizeof(dest->display));
+    dest->dirty = true;
+  }
+}
+
+static void render_status_info(void) {
+#if DEBUG_TO_SCREEN
+  if (debug_enable) {
+    return;
+  }
+#endif
+
+  struct CharacterMatrix matrix;
+
+  matrix_clear(&matrix);
+  matrix_write_P(&matrix, PSTR("USB: "));
+#ifdef PROTOCOL_LUFA
+  switch (USB_DeviceState) {
+    case DEVICE_STATE_Unattached:
+      matrix_write_P(&matrix, PSTR("Unattached"));
+      break;
+    case DEVICE_STATE_Suspended:
+      matrix_write_P(&matrix, PSTR("Suspended"));
+      break;
+    case DEVICE_STATE_Configured:
+      matrix_write_P(&matrix, PSTR("Connected"));
+      break;
+    case DEVICE_STATE_Powered:
+      matrix_write_P(&matrix, PSTR("Powered"));
+      break;
+    case DEVICE_STATE_Default:
+      matrix_write_P(&matrix, PSTR("Default"));
+      break;
+    case DEVICE_STATE_Addressed:
+      matrix_write_P(&matrix, PSTR("Addressed"));
+      break;
+    default:
+      matrix_write_P(&matrix, PSTR("Invalid"));
+  }
+#endif
+
+// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
+
+  char buf[40];
+  snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
+  matrix_write_P(&matrix, PSTR("\n\nLayer: "));
+    switch (layer_state) {
+        case _BASE:
+           matrix_write_P(&matrix, PSTR("Default"));
+           break;
+        case _RAISE:
+           matrix_write_P(&matrix, PSTR("Raise"));
+           break;
+        case _LOWER:
+           matrix_write_P(&matrix, PSTR("Lower"));
+           break;
+        case _ADJUST:
+           matrix_write_P(&matrix, PSTR("ADJUST"));
+           break;
+        default:
+           matrix_write(&matrix, buf);
+ }
+  
+  // Host Keyboard LED Status
+  char led[40];
+    snprintf(led, sizeof(led), "\n%s  %s  %s",
+            (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : "       ",
+            (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : "    ",
+            (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : "    ");
+  matrix_write(&matrix, led);
+  matrix_update(&display, &matrix);
+}
+
+void iota_gfx_task(void) {
+  render_status_info();
+
+  if (display.dirty) {
+    iota_gfx_flush();
+  }
+
+  if (timer_elapsed(last_flush) > ScreenOffInterval) {
+    iota_gfx_off();
+  }
+}

+ 29 - 0
keyboards/planck/keymaps/dbroqua/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/default/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 23 - 0
keyboards/planck/keymaps/experimental/config.h

@@ -14,4 +14,27 @@
 #define RGBLIGHT_HUE_STEP 10
 #define RGBLIGHT_SAT_STEP 17
 
+/*
+ * 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
+
 #endif

+ 29 - 0
keyboards/planck/keymaps/impossible/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/jeebak/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 23 - 0
keyboards/planck/keymaps/jhenahan/config.h

@@ -6,4 +6,27 @@
 #define FORCE_NKRO
 #define WORKMAN_SOUND COLEMAK_SOUND
 
+/*
+ * 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
+
 #endif

+ 4 - 0
keyboards/planck/keymaps/khord/Makefile

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

+ 25 - 23
keyboards/lets_split/rev2fliphalf/config.h → keyboards/planck/keymaps/khord/config.h

@@ -22,23 +22,23 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 /* USB Device descriptor parameter */
 #define VENDOR_ID       0xFEED
-#define PRODUCT_ID      0x3060
-#define DEVICE_VER      0x0001
-#define MANUFACTURER    Wootpatoot
-#define PRODUCT         Lets Split v2
-#define DESCRIPTION     A split keyboard for the cheap makers
+#define PRODUCT_ID      0x6060
+#define MANUFACTURER    Ortholinear Keyboards
+#define PRODUCT         The Planck Keyboard
+#define DESCRIPTION     A compact ortholinear keyboard
 
 /* key matrix size */
-// Rows are doubled-up
-#define MATRIX_ROWS 8
-#define MATRIX_COLS 6
+#define MATRIX_ROWS 4
+#define MATRIX_COLS 12
 
-// wiring of each half
-#define MATRIX_ROW_PINS { D7, E6, B4, B5 }
-//#define MATRIX_COL_PINS { F6, F7, B1, B3, B2, B6 }
-#define MATRIX_COL_PINS { B6, B2, B3, B1, F7, F6 } //uncomment this line and comment line above if you need to reverse left-to-right key order
+/* Planck PCB default pin-out */
+#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
+#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
+#define UNUSED_PINS
 
-//#define CATERINA_BOOTLOADER
+#define AUDIO_VOICES
+
+#define BACKLIGHT_PIN B7
 
 /* COL2ROW or ROW2COL */
 #define DIODE_DIRECTION COL2ROW
@@ -47,7 +47,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //#define MATRIX_HAS_GHOST
 
 /* number of backlight levels */
-// #define BACKLIGHT_LEVELS 3
+#define BACKLIGHT_LEVELS 3
 
 /* Set 0 if debouncing isn't needed */
 #define DEBOUNCING_DELAY 5
@@ -62,12 +62,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
     keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
 )
 
-/* ws2812 RGB LED */
-#define RGB_DI_PIN D3
-#define RGBLIGHT_TIMER
-#define RGBLED_NUM 12    // Number of LEDs
-#define ws2812_PORTREG  PORTD
-#define ws2812_DDRREG   DDRD
+/* Tap Dance */
+#define TAPPING_TERM 150
 
 /*
  * Feature disable options
@@ -75,10 +71,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 /* disable debug print */
-// #define NO_DEBUG
+//#define NO_DEBUG
 
 /* disable print */
-// #define NO_PRINT
+//#define NO_PRINT
 
 /* disable action features */
 //#define NO_ACTION_LAYER
@@ -87,5 +83,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //#define NO_ACTION_MACRO
 //#define NO_ACTION_FUNCTION
 
+#ifdef SUBPROJECT_rev3
+    #include "rev3/config.h"
+#endif
+#ifdef SUBPROJECT_rev4
+    #include "rev4/config.h"
+#endif
 
-#endif
+#endif

+ 336 - 0
keyboards/planck/keymaps/khord/keymap.c

@@ -0,0 +1,336 @@
+// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
+// this is the style you want to emulate.
+
+#include "planck.h"
+#include "action_layer.h"
+#ifdef AUDIO_ENABLE
+  #include "audio.h"
+#endif
+#include "eeconfig.h"
+
+extern keymap_config_t keymap_config;
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _PLOVER 5
+#define _ADJUST 16
+
+enum planck_keycodes {
+  QWERTY = SAFE_RANGE,
+  COLEMAK,
+  DVORAK,
+  PLOVER,
+  LOWER,
+  RAISE,
+  BACKLIT,
+  EXT_PLV
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+// Tap Dance Declarations
+enum {
+  ESC_CAP = 0,
+  LFT_HOM,
+  DWN_PDN,
+  UPP_PUP,
+  RGT_END
+};
+
+// Dylan's additions
+#define C_A_DEL LALT(LCTL(KC_DEL))
+#define C_A_INS LALT(LCTL(KC_INS))
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = {
+  {KC_TAB,      KC_Q,    KC_W,    KC_E,    KC_R,  KC_T,   KC_Y,   KC_U,  KC_I,    KC_O,    KC_P,    KC_BSPC      },
+  {TD(ESC_CAP), 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, SFT_T(KC_ENT)},
+  {BACKLIT,     KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT      }
+},
+
+/* Colemak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = {
+  {KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC},
+  {KC_ESC,  KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT},
+  {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT },
+  {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Dvorak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   "  |   ,  |   .  |   P  |   Y  |   F  |   G  |   C  |   R  |   L  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   O  |   E  |   U  |   I  |   D  |   H  |   T  |   N  |   S  |  /   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   ;  |   Q  |   J  |   K  |   X  |   B  |   M  |   W  |   V  |   Z  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_DVORAK] = {
+  {KC_TAB,  KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,    KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    KC_BSPC},
+  {KC_ESC,  KC_A,    KC_O,    KC_E,    KC_U,    KC_I,    KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    KC_SLSH},
+  {KC_LSFT, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,    KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    KC_ENT },
+  {BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   _  |   +  |   {  |   }  |  |   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO ~ |ISO | | END  | HOME |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = {
+  {KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,S(KC_NUHS),S(KC_NUBS),KC_END, KC_HOME, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * |   `  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   -  |   =  |   [  |   ]  |  \   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO # |ISO / |PG DN |PG UP |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = {
+  {KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NUHS, KC_NUBS, KC_PGDN, KC_PGUP, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Plover layer (http://opensteno.org)
+ * ,-----------------------------------------------------------------------------------.
+ * |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |   S  |   T  |   P  |   H  |   *  |   *  |   F  |   P  |   L  |   T  |   D  |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |TogOut|   S  |   K  |   W  |   R  |   *  |   *  |   R  |   B  |   G  |   S  |   Z  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Exit |      |      |   A  |   O  |             |   E  |   U  |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+
+[_PLOVER] = {
+  {KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1   },
+  {XXXXXXX, KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC},
+  {XXXXXXX, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
+  {EXT_PLV, XXXXXXX, XXXXXXX, KC_C,    KC_V,    XXXXXXX, XXXXXXX, KC_N,    KC_M,    XXXXXXX, XXXXXXX, XXXXXXX}
+},
+
+/* Adjust (Lower + Raise)
+ * ,-----------------------------------------------------------------------------------.
+ * |      | Reset|      |      |      |      |      |      |      |      |      |  Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |      |      |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover|      |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] = {
+  {_______, RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
+  {_______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, AG_SWAP, QWERTY,  COLEMAK, DVORAK,  PLOVER,  _______},
+  {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  _______, _______, _______, _______, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, C_A_INS, C_A_DEL}
+}
+
+
+};
+
+
+qk_tap_dance_action_t tap_dance_actions[] = {
+  [ESC_CAP] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
+  [LFT_HOM] = ACTION_TAP_DANCE_DOUBLE(KC_LEFT, KC_HOME),
+  [DWN_PDN] = ACTION_TAP_DANCE_DOUBLE(KC_DOWN, KC_PGDN),
+  [UPP_PUP] = ACTION_TAP_DANCE_DOUBLE(KC_UP, KC_PGUP),
+  [RGT_END] = ACTION_TAP_DANCE_DOUBLE(KC_RGHT, KC_END)
+};
+
+#ifdef AUDIO_ENABLE
+
+float tone_startup[][2]    = SONG(SONIC_RING); //plug in
+float tone_qwerty[][2]     = SONG(QWERTY_SOUND);
+float tone_dvorak[][2]     = SONG(DVORAK_SOUND);
+float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
+float tone_plover[][2]     = SONG(PLOVER_SOUND);
+float tone_plover_gb[][2]  = SONG(PLOVER_GOODBYE_SOUND);
+float music_scale[][2]     = SONG(ZELDA_PUZZLE); //music mode
+
+float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
+#endif
+
+
+void persistant_default_layer_set(uint16_t default_layer) {
+  eeconfig_update_default_layer(default_layer);
+  default_layer_set(default_layer);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    case QWERTY:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_QWERTY);
+      }
+      return false;
+      break;
+    case COLEMAK:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_colemak, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_COLEMAK);
+      }
+      return false;
+      break;
+    case DVORAK:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_DVORAK);
+      }
+      return false;
+      break;
+    case LOWER:
+      if (record->event.pressed) {
+        layer_on(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case RAISE:
+      if (record->event.pressed) {
+        layer_on(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case BACKLIT:
+      if (record->event.pressed) {
+        register_code(KC_RSFT);
+        #ifdef BACKLIGHT_ENABLE
+          backlight_step();
+        #endif
+      } else {
+        unregister_code(KC_RSFT);
+      }
+      return false;
+      break;
+    case PLOVER:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          stop_all_notes();
+          PLAY_NOTE_ARRAY(tone_plover, false, 0);
+        #endif
+        layer_off(_RAISE);
+        layer_off(_LOWER);
+        layer_off(_ADJUST);
+        layer_on(_PLOVER);
+        if (!eeconfig_is_enabled()) {
+            eeconfig_init();
+        }
+        keymap_config.raw = eeconfig_read_keymap();
+        keymap_config.nkro = 1;
+        eeconfig_update_keymap(keymap_config.raw);
+      }
+      return false;
+      break;
+    case EXT_PLV:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_plover_gb, false, 0);
+        #endif
+        layer_off(_PLOVER);
+      }
+      return false;
+      break;
+  }
+  return true;
+}
+
+void matrix_init_user(void) {
+    #ifdef AUDIO_ENABLE
+        startup_user();
+    #endif
+}
+
+#ifdef AUDIO_ENABLE
+
+void startup_user()
+{
+    _delay_ms(20); // gets rid of tick
+    PLAY_NOTE_ARRAY(tone_startup, false, 0);
+}
+
+void shutdown_user()
+{
+    PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
+    _delay_ms(150);
+    stop_all_notes();
+}
+
+void music_on_user(void)
+{
+    music_scale_user();
+}
+
+void music_scale_user(void)
+{
+    PLAY_NOTE_ARRAY(music_scale, false, 0);
+}
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/premek/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/sgoodwin/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/smt/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 23 - 0
keyboards/planck/keymaps/thermal_printer/config.h

@@ -20,4 +20,27 @@
             sei(); \
         } while(0)
 
+/*
+ * 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
+
  #endif

+ 29 - 0
keyboards/planck/keymaps/unicode/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/planck/keymaps/xyverz/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/preonic/keymaps/CMD-Preonic/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/preonic/keymaps/default/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 29 - 0
keyboards/preonic/keymaps/smt/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 21 - 0
keyboards/satan/keymaps/midi/Makefile

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

+ 29 - 0
keyboards/satan/keymaps/midi/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 77 - 0
keyboards/satan/keymaps/midi/keymap.c

@@ -0,0 +1,77 @@
+#include "satan.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 _BL 0
+#define _ML 1
+
+// readability
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+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 |Midi|Ctrl |
+   * `-----------------------------------------------------------'
+   */
+[_BL] = KEYMAP_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_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, TG(_ML), KC_RCTL),
+
+#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
+/* Keymap _ML: MIDI Layer (Advanced)
+   * ,------------------------------------------------------------------------.
+   * | Exit |    |    |    |    |    |    |    |    |    |    |    |    |     |
+   * |------------------------------------------------------------------------|
+   * |  Ch+ |    | C# | D# |    | F# | G# | A# |    | C# | D# |    |    |     |
+   * |------------------------------------------------------------------------|
+   * |  Mod  | C  | D  | E  | F  | G  | A  | B  | C  | D  | E  | F  |         |
+   * |------------------------------------------------------------------------|
+   * | Sustain |Oct-|Oct+|Mod-|Mod+|    |    |    |Tns-|Tns+|Tns0|   Sustain  |
+   * |------------------------------------------------------------------------|
+   * |     |     |     |         All notes off        |     |     |     |     |
+   * `------------------------------------------------------------------------'
+   */
+[_ML] = KEYMAP_ANSI(
+  TG(_ML), MI_VEL_1, MI_VEL_2, MI_VEL_3, MI_VEL_4, MI_VEL_5, MI_VEL_6, MI_VEL_7, MI_VEL_8, MI_VEL_9, MI_VEL_10, XXXXXXX, XXXXXXX, XXXXXXX, \
+  MI_CHU,  XXXXXXX, MI_Cs,   MI_Ds,   XXXXXXX, MI_Fs,   MI_Gs,   MI_As,   XXXXXXX, MI_Cs_1, MI_Ds_1, XXXXXXX, XXXXXXX, XXXXXXX, \
+  MI_MOD,  MI_C,    MI_D,    MI_E,    MI_F,    MI_G,    MI_A,    MI_B,    MI_C_1,  MI_D_1,  MI_E_1,  MI_F_1,           _______, \
+  MI_SUS,  MI_OCTD, MI_OCTU, MI_MODSD, MI_MODSU, XXXXXXX, XXXXXXX, XXXXXXX, MI_TRNSD, MI_TRNSU, MI_TRNS_0,             MI_SUS, \
+  _______, _______, _______,                          MI_ALLOFF,                            _______, _______, _______, _______),
+#elif defined(MIDI_ENABLE) && defined(MIDI_BASIC)
+/* Keymap _ML: MIDI Layer (Advanced)
+   * ,------------------------------------------------------------------------.
+   * | Exit |    |    |    |    |    |    |    |    |    |    |    |    |     |
+   * |------------------------------------------------------------------------|
+   * |      |    |    |    |    |    |    |    |    |    |    |    |    |     |
+   * |------------------------------------------------------------------------|
+   * |       |    |    |    |    |    |    |    |    |    |    |    |         |
+   * |------------------------------------------------------------------------|
+   * |         |MuOn|MuOf|MiOn|MiOf|    |    |    |    |    |    |            |
+   * |------------------------------------------------------------------------|
+   * |     |     |     |                              |     |     |     |     |
+   * `------------------------------------------------------------------------'
+   */
+
+[_ML] = KEYMAP_ANSI(
+  TG(_ML), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, \
+  _______, MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  _______, _______, _______, _______, _______, _______,                   _______, \
+  _______, _______, _______,                          _______,                              _______, _______, _______, _______),
+#endif
+};

+ 1 - 0
keyboards/satan/keymaps/midi/readme.md

@@ -0,0 +1 @@
+# Satan GH60 layout demonstrating MIDI key mapping

+ 21 - 0
keyboards/satan/keymaps/smt/Makefile

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

+ 141 - 0
keyboards/satan/keymaps/smt/keymap.c

@@ -0,0 +1,141 @@
+#include "satan.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 _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _FUNC 3
+
+enum planck_keycodes {
+  QWERTY = SAFE_RANGE,
+  COLEMAK,
+  DVORAK
+};
+
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+// Custom macros
+#define ALT_GRV     ALT_T(KC_GRV)               // Tap for Backtick, hold for Alt
+#define CTL_ESC     CTL_T(KC_ESC)               // Tap for Esc, hold for Ctrl
+#define HPR_TAB     ALL_T(KC_TAB)               // Tap for Tab, hold for Hyper (Super+Ctrl+Shift+Alt)
+#define SFT_ENT     SFT_T(KC_ENT)               // Tap for Enter, hold for Shift
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+  /* Keymap _QWERTY: (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 |
+   * `-----------------------------------------------------------'
+   */
+[_QWERTY] = KEYMAP_ANSI(
+  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, \
+  HPR_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, \
+  CTL_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,         SFT_ENT, \
+  KC_LCTL, KC_LGUI,KC_LALT,                      KC_SPC,                           KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
+
+  /* Keymap _COLEMAK: (Base Layer) Default Layer
+   * ,-----------------------------------------------------------.
+   * |Esc~| 1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backsp |
+   * |-----------------------------------------------------------|
+   * |Tab  |  Q|  W|  F|  P|  G|  J|  L|  U|  Y|  ;|  [|  ]|  \  |
+   * |-----------------------------------------------------------|
+   * |CAPS   |  A|  R|  S|  T|  D|  H|  N|  E|  I|  O|  '|Return |
+   * |-----------------------------------------------------------|
+   * |Shift   |  Z|  X|  C|  V|  B|  K|  M|  ,|  .|  /|Shift     |
+   * |-----------------------------------------------------------|
+   * |Ctrl|Gui |Alt |         Space         |Alt |Gui |Fn  |Ctrl |
+   * `-----------------------------------------------------------'
+   */
+[_COLEMAK] = KEYMAP_ANSI(
+  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, \
+  HPR_TAB, KC_Q,   KC_W,   KC_F,   KC_P,   KC_G,   KC_J,   KC_L,   KC_U,   KC_Y,   KC_SCLN,KC_LBRC, KC_RBRC,KC_BSLS, \
+  CTL_ESC, KC_A,   KC_R,   KC_S,   KC_T,   KC_D,   KC_H,   KC_N,   KC_E,   KC_I,   KC_O   ,KC_QUOT,         KC_ENT,  \
+  KC_LSFT,         KC_Z,   KC_X,   KC_C,   KC_V,   KC_B,   KC_K,   KC_M,   KC_COMM,KC_DOT, KC_SLSH,         SFT_ENT, \
+  KC_LCTL, KC_LGUI,KC_LALT,                      KC_SPC,                           KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
+
+  /* Keymap _DVORAK: (Base Layer) Default Layer
+   * ,-----------------------------------------------------------.
+   * |Esc~| 1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  [|  ]|Backsp |
+   * |-----------------------------------------------------------|
+   * |HypTb|  '|  ,|  .|  P|  Y|  F|  G|  C|  R|  L|  /|  =|  \  |
+   * |-----------------------------------------------------------|
+   * |CtrlEsc|  A|  O|  E|  U|  I|  D|  H|  T|  N|  S|  -|Return |
+   * |-----------------------------------------------------------|
+   * |Shift   |  ;|  Q|  J|  K|  X|  B|  M|  W|  V|  Z|ShiftEnter|
+   * |-----------------------------------------------------------|
+   * |Ctrl|Gui |Alt |         Space         |Alt |Gui |Fn  |Ctrl |
+   * `-----------------------------------------------------------'
+   */
+[_DVORAK] = KEYMAP_ANSI(
+  KC_GRV,  KC_1,   KC_2,   KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,   KC_9,   KC_0,   KC_LBRC, KC_RBRC,KC_BSPC, \
+  HPR_TAB, KC_QUOT,KC_COMM,KC_DOT, KC_P,   KC_Y,   KC_F,   KC_G,   KC_C,   KC_R,   KC_L,   KC_SLSH, KC_EQL, KC_BSLS, \
+  CTL_ESC, KC_A,   KC_O,   KC_E,   KC_U,   KC_I,   KC_D,   KC_H,   KC_T,   KC_N,   KC_S,   KC_MINS,         KC_ENT,  \
+  KC_LSFT,         KC_SCLN,KC_Q,   KC_J,   KC_K,   KC_X,   KC_B,   KC_M,   KC_W,   KC_V,   KC_Z,            SFT_ENT, \
+  KC_LCTL, KC_LGUI,KC_LALT,                      KC_SPC,                           KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
+
+  /* Keymap _FUNC: Function Layer
+   * ,-----------------------------------------------------------.
+   * |   | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete |
+   * |-----------------------------------------------------------|
+   * |     |Hom| UP|End|   |   |   |Qwt|Cmk|Dvk|   |BL-|BL+|BL   |
+   * |-----------------------------------------------------------|
+   * |      |LFT| DN| RT|   |   |LFT| DN| UP| RT|Vo+|Pg+|        |
+   * |-----------------------------------------------------------|
+   * |        |   |   |Prv|Ply|Nxt|   |   |   |Vo-|Pg-|          |
+   * |-----------------------------------------------------------|
+   * |RESET|    |    |                       |    |    |    |    |
+   * `-----------------------------------------------------------'
+   */
+[_FUNC] = KEYMAP_ANSI(
+  _______,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_HOME,KC_UP  ,KC_END ,_______,_______,_______,QWERTY ,COLEMAK,DVORAK ,_______,BL_DEC ,BL_INC ,BL_TOGG, \
+  _______,KC_LEFT,KC_DOWN,KC_RGHT,_______,_______,KC_LEFT,KC_DOWN,KC_UP  ,KC_RGHT,KC_VOLU,KC_PGUP        ,_______, \
+  _______        ,_______,_______,KC_MPRV,KC_MPLY,KC_MNXT,_______,_______,_______,KC_VOLD,KC_PGDN        ,_______, \
+  RESET  ,_______,_______                        ,_______                        ,_______,_______,_______,_______
+  )
+};
+
+void persistant_default_layer_set(uint16_t default_layer) {
+  eeconfig_update_default_layer(default_layer);
+  default_layer_set(default_layer);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    case QWERTY:
+      if (record->event.pressed) {
+        persistant_default_layer_set(1UL<<_QWERTY);
+      }
+      return false;
+      break;
+    case COLEMAK:
+      if (record->event.pressed) {
+        persistant_default_layer_set(1UL<<_COLEMAK);
+      }
+      return false;
+      break;
+    case DVORAK:
+      if (record->event.pressed) {
+        persistant_default_layer_set(1UL<<_DVORAK);
+      }
+      return false;
+      break;
+  }
+  return true;
+}

+ 1 - 0
keyboards/satan/keymaps/smt/readme.md

@@ -0,0 +1 @@
+# smt's Satan GH60 layout

+ 29 - 0
keyboards/subatomic/keymaps/default/config.h

@@ -0,0 +1,29 @@
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+/*
+ * 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
+
+#endif

+ 10 - 56
keyboards/tada68/keymaps/default/keymap.c

@@ -1,9 +1,5 @@
 #include "tada68.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
@@ -36,63 +32,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 
   /* Keymap _FL: Function Layer
    * ,----------------------------------------------------------------.
-   * |   |   |   |   |   |   |   |   |   |   |   |   |   |  RESET|    |
+   * |   | F1|F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del    |Ins |
    * |----------------------------------------------------------------|
-   * |     |   |   |   |   |   |   |   |   |   |   |BL-|BL+|BL   |    |
+   * |     |   |Up |   |   |   |   |   |   |   |   |   |   |     |Hme |
    * |----------------------------------------------------------------|
-   * |      |   |   |   |   |   |   |       |   |   |   |        |    |
+   * |      |<- |Dn | ->|   |   |   |   |   |   |   |   |        |End |
    * |----------------------------------------------------------------|
-   * |        | F1|F2 | F3|F4 | F5| F6| F7| F8|   |   |      |   |    |
+   * |        |   |   |Bl-|BL |BL+|   |VU-|VU+|MUT|   |MouseL|MsU|Rck |
    * |----------------------------------------------------------------|
-   * |    |    |    |                       |   |   |    |   |   |    |
+   * |    |    |    |                       |   |   |    |MsL|MsD|MsR |
    * `----------------------------------------------------------------'
    */
 [_FL] = KEYMAP_ANSI(
-  #ifdef RGBLIGHT_ENABLE
-  _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,RESET,_______,  \
-  _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,_______, \
-  _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,        _______,_______, \
-  _______,RGB_TOG,RGB_MOD,RGB_HUI,RGB_HUD,RGB_SAI,RGB_SAD,RGB_VAI,RGB_VAD,_______,_______,_______,_______,_______, \
-  _______,_______,_______,                 _______,               _______,_______,_______,_______,_______, _______),
-  #else
-  _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,RESET,_______,  \
-  _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,_______, \
-  _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,        _______,_______, \
-  _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, \
-  _______,_______,_______,                 _______,               _______,_______,_______,_______,_______, _______),
-  #endif
-};
-
-/*enum function_id {
-    //SHIFT_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_INS ,  \
+  _______,_______,KC_UP, _______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,KC_HOME, \
+  _______,KC_LEFT,KC_DOWN,KC_RIGHT,_______,_______,_______,_______,_______,_______,_______,_______,        _______,KC_END, \
+  _______,_______,_______,BL_DEC, BL_TOGG,BL_INC, _______,KC_VOLD,KC_VOLU,KC_MUTE,_______,KC_BTN1, KC_MS_U, KC_BTN2, \
+  _______,_______,_______,                 _______,               _______,_______,_______,KC_MS_L,KC_MS_D, KC_MS_R),
 };
-
-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;
-  }
-}*/

+ 2 - 0
keyboards/tada68/keymaps/default/readme.md

@@ -1 +1,3 @@
 # default TADA68 layout
+
+This layout replicates the default factory layout of the TADA68.

+ 13 - 2
keyboards/tada68/readme.md

@@ -1,4 +1,15 @@
 TADA68 keyboard firmware
-======================
+========================
 
-TODO: to be updated.
+1) from the keyboards/tada68 directory run:
+```
+$ make flashbin
+```
+
+2) hit the reset button on the TADA, the lights will start flashing.
+
+3) You'll see a new drive on your computer called TADA68. Backup the original factory `FLASH.BIN` file thats inside it.
+
+4) Delete `FLASH.BIN` from the TADA drive and copy `tada68_default.bin` that was generated at the root of the qmk directory into the TADA drive.
+
+5) Hit ESC on the keyboard. The lights will stop flashing and your firmware is loaded!

+ 13 - 0
keyboards/xd60/keymaps/cheese/README.md

@@ -0,0 +1,13 @@
+# cheese's Layout
+Customized xd60 keymap 
+
+![Base Layout](base_layout.png "Base Layout")
+![Fn Layout](fn_layout.png "Fn Layout")
+
+## Programming Instructions:
+`cd` into keymap directory, `make dfu`
+
+## Features
+- Media keys and movement keys setup like on the pok3r
+- Lower right movement keys setup like on the fc660m (fn+direction for home/end/page up and down)
+- Caps lock can be triggered by pressing both shift keys at the same time (and deactivated the same way)

二进制
keyboards/xd60/keymaps/cheese/base_layout.png


二进制
keyboards/xd60/keymaps/cheese/fn_layout.png


+ 67 - 0
keyboards/xd60/keymaps/cheese/keymap.c

@@ -0,0 +1,67 @@
+#include "xd60.h"
+#include "action_layer.h"
+
+// Each layer gets a name for readability.
+// 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, and you can also skip them entirely
+// and just use numbers.
+#define _BL 0
+#define _FL 1
+#define _LS 2
+#define _RS 3
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+  /* (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|  [|  ]|  \  |
+   * |-----------------------------------------------------------|
+   * |FUNCTION|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|
+   * |-----------------------------------------------------------|
+   * |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  .|  /|Shift     |
+   * |-----------------------------------------------------------|
+   * |Ctrl|Gui |Alt |      Space           |FN|Left|Up|Down|Right|
+   * `-----------------------------------------------------------'
+   */
+  [_BL] = KEYMAP(
+      KC_ESC,  KC_1,    KC_2,    KC_3,    KC_4,   KC_5,   KC_6,   KC_7,   KC_8,   KC_9,    KC_0,    KC_MINS,  KC_EQL,   KC_BSPC,  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,            \
+      MO(_FL), 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,             \
+      F(0), KC_NO,   KC_Z,    KC_X,    KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM, KC_DOT,  KC_SLSH,  F(1),  F(1),  F(1),  \
+      KC_LCTL, KC_LGUI, KC_LALT,                          KC_SPC,                          MO(_FL), KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT),
+
+// Function Layer
+  [_FL] = KEYMAP(
+      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_DEL,  \
+      KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_CALC, KC_INS,  KC_PGUP,  KC_UP,   KC_PGDN, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, \
+      KC_TRNS, KC_VOLD, KC_MUTE, KC_VOLU,  KC_TRNS,  KC_TRNS, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_TRNS, KC_TRNS, KC_APP,  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_HOME, KC_PGUP, KC_PGDN, KC_END),
+
+// Left Shift Layer
+  [_LS] = KEYMAP(
+      KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  \
+      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPS, KC_CAPS, KC_CAPS, \
+      KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Right Shift Layer
+  [_RS] = KEYMAP(
+      KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,  \
+      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+      KC_TRNS, KC_TRNS, KC_TRNS,                            KC_TRNS,                        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
+
+// Custom Actions
+const uint16_t PROGMEM fn_actions[] = {
+    [0] = ACTION_LAYER_MODS(_LS, MOD_LSFT),
+    [1] = ACTION_LAYER_MODS(_RS, MOD_RSFT),
+};

+ 164 - 158
quantum/audio/audio.c

@@ -89,15 +89,15 @@ void audio_init()
     }
     audio_config.raw = eeconfig_read_audio();
 
-	// Set port PC6 (OC3A and /OC4A) as output
+    // Set port PC6 (OC3A and /OC4A) as output
     DDRC |= _BV(PORTC6);
 
     DISABLE_AUDIO_COUNTER_3_ISR;
 
-	// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
-	// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
-	// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
-	// Clock Select (CS3n) = 0b010 = Clock / 8
+    // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
+    // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
+    // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
+    // Clock Select (CS3n) = 0b010 = Clock / 8
     TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
     TCCR3B = (1 << WGM33)  | (1 << WGM32)  | (0 << CS32)  | (1 << CS31) | (0 << CS30);
 
@@ -106,6 +106,8 @@ void audio_init()
 
 void stop_all_notes()
 {
+    dprintf("audio stop all notes");
+
     if (!audio_initialized) {
         audio_init();
     }
@@ -128,6 +130,8 @@ void stop_all_notes()
 
 void stop_note(float freq)
 {
+    dprintf("audio stop note freq=%d", (int)freq);
+
     if (playing_note) {
         if (!audio_initialized) {
             audio_init();
@@ -183,159 +187,161 @@ float vibrato(float average_freq) {
 
 ISR(TIMER3_COMPA_vect)
 {
-	float freq;
-
-	if (playing_note) {
-		if (voices > 0) {
-			if (polyphony_rate > 0) {
-				if (voices > 1) {
-					voice_place %= voices;
-					if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
-						voice_place = (voice_place + 1) % voices;
-						place = 0.0;
-					}
-				}
-
-				#ifdef VIBRATO_ENABLE
-					if (vibrato_strength > 0) {
-						freq = vibrato(frequencies[voice_place]);
-					} else {
-						freq = frequencies[voice_place];
-					}
-				#else
-					freq = frequencies[voice_place];
-				#endif
-			} else {
-				if (glissando) {
-					if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
-						frequency = frequency * pow(2, 440/frequency/12/2);
-					} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
-						frequency = frequency * pow(2, -440/frequency/12/2);
-					} else {
-						frequency = frequencies[voices - 1];
-					}
-				} else {
-					frequency = frequencies[voices - 1];
-				}				
-
-				#ifdef VIBRATO_ENABLE
-					if (vibrato_strength > 0) {
-						freq = vibrato(frequency);
-					} else {
-						freq = frequency;
-					}
-				#else
-					freq = frequency;
-				#endif
-			}
-
-			if (envelope_index < 65535) {
-				envelope_index++;
-			}
-
-			freq = voice_envelope(freq);
-
-			if (freq < 30.517578125) {
-				freq = 30.52;
-			}
-
-			TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
-			TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
-		}
-	}
-
-	if (playing_notes) {
-		if (note_frequency > 0) {
-			#ifdef VIBRATO_ENABLE
-				if (vibrato_strength > 0) {
-					freq = vibrato(note_frequency);
-				} else {
-					freq = note_frequency;
-				}
-			#else
-					freq = note_frequency;
-			#endif
-
-			if (envelope_index < 65535) {
-				envelope_index++;
-			}
-			freq = voice_envelope(freq);
-
-			TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
-			TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
-		} else {
-			TIMER_3_PERIOD = 0;
-			TIMER_3_DUTY_CYCLE = 0;
-		}
-
-		note_position++;
-		bool end_of_note = false;
-		if (TIMER_3_PERIOD > 0) {
-			end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
-		} else {
-			end_of_note = (note_position >= (note_length * 0x7FF));
-		}
-
-		if (end_of_note) {
-			current_note++;
-			if (current_note >= notes_count) {
-				if (notes_repeat) {
-					current_note = 0;
-				} else {
-					DISABLE_AUDIO_COUNTER_3_ISR;
-					DISABLE_AUDIO_COUNTER_3_OUTPUT;
-					playing_notes = false;
-					return;
-				}
-			}
-			if (!note_resting && (notes_rest > 0)) {
-				note_resting = true;
-				note_frequency = 0;
-				note_length = notes_rest;
-				current_note--;
-			} else {
-				note_resting = false;
-				envelope_index = 0;
-				note_frequency = (*notes_pointer)[current_note][0];
-				note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
-			}
-
-			note_position = 0;
-		}
-	}
-
-	if (!audio_config.enable) {
-		playing_notes = false;
-		playing_note = false;
-	}
+    float freq;
+
+    if (playing_note) {
+        if (voices > 0) {
+            if (polyphony_rate > 0) {
+                if (voices > 1) {
+                    voice_place %= voices;
+                    if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
+                        voice_place = (voice_place + 1) % voices;
+                        place = 0.0;
+                    }
+                }
+
+                #ifdef VIBRATO_ENABLE
+                    if (vibrato_strength > 0) {
+                        freq = vibrato(frequencies[voice_place]);
+                    } else {
+                        freq = frequencies[voice_place];
+                    }
+                #else
+                    freq = frequencies[voice_place];
+                #endif
+            } else {
+                if (glissando) {
+                    if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
+                        frequency = frequency * pow(2, 440/frequency/12/2);
+                    } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
+                        frequency = frequency * pow(2, -440/frequency/12/2);
+                    } else {
+                        frequency = frequencies[voices - 1];
+                    }
+                } else {
+                    frequency = frequencies[voices - 1];
+                }
+
+                #ifdef VIBRATO_ENABLE
+                    if (vibrato_strength > 0) {
+                        freq = vibrato(frequency);
+                    } else {
+                        freq = frequency;
+                    }
+                #else
+                    freq = frequency;
+                #endif
+            }
+
+            if (envelope_index < 65535) {
+                envelope_index++;
+            }
+
+            freq = voice_envelope(freq);
+
+            if (freq < 30.517578125) {
+                freq = 30.52;
+            }
+
+            TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
+            TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
+        }
+    }
+
+    if (playing_notes) {
+        if (note_frequency > 0) {
+            #ifdef VIBRATO_ENABLE
+                if (vibrato_strength > 0) {
+                    freq = vibrato(note_frequency);
+                } else {
+                    freq = note_frequency;
+                }
+            #else
+                    freq = note_frequency;
+            #endif
+
+            if (envelope_index < 65535) {
+                envelope_index++;
+            }
+            freq = voice_envelope(freq);
+
+            TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
+            TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
+        } else {
+            TIMER_3_PERIOD = 0;
+            TIMER_3_DUTY_CYCLE = 0;
+        }
+
+        note_position++;
+        bool end_of_note = false;
+        if (TIMER_3_PERIOD > 0) {
+            end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
+        } else {
+            end_of_note = (note_position >= (note_length * 0x7FF));
+        }
+
+        if (end_of_note) {
+            current_note++;
+            if (current_note >= notes_count) {
+                if (notes_repeat) {
+                    current_note = 0;
+                } else {
+                    DISABLE_AUDIO_COUNTER_3_ISR;
+                    DISABLE_AUDIO_COUNTER_3_OUTPUT;
+                    playing_notes = false;
+                    return;
+                }
+            }
+            if (!note_resting && (notes_rest > 0)) {
+                note_resting = true;
+                note_frequency = 0;
+                note_length = notes_rest;
+                current_note--;
+            } else {
+                note_resting = false;
+                envelope_index = 0;
+                note_frequency = (*notes_pointer)[current_note][0];
+                note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
+            }
+
+            note_position = 0;
+        }
+    }
+
+    if (!audio_config.enable) {
+        playing_notes = false;
+        playing_note = false;
+    }
 }
 
 void play_note(float freq, int vol) {
 
+    dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
+
     if (!audio_initialized) {
         audio_init();
     }
 
-	if (audio_config.enable && voices < 8) {
-	    DISABLE_AUDIO_COUNTER_3_ISR;
+    if (audio_config.enable && voices < 8) {
+        DISABLE_AUDIO_COUNTER_3_ISR;
 
-	    // Cancel notes if notes are playing
-	    if (playing_notes)
-	        stop_all_notes();
+        // Cancel notes if notes are playing
+        if (playing_notes)
+            stop_all_notes();
 
-	    playing_note = true;
+        playing_note = true;
 
-	    envelope_index = 0;
+        envelope_index = 0;
 
-	    if (freq > 0) {
-	        frequencies[voices] = freq;
-	        volumes[voices] = vol;
-	        voices++;
-	    }
+        if (freq > 0) {
+            frequencies[voices] = freq;
+            volumes[voices] = vol;
+            voices++;
+        }
 
         ENABLE_AUDIO_COUNTER_3_ISR;
         ENABLE_AUDIO_COUNTER_3_OUTPUT;
-	}
+    }
 
 }
 
@@ -346,37 +352,37 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
         audio_init();
     }
 
-	if (audio_config.enable) {
+    if (audio_config.enable) {
 
-	    DISABLE_AUDIO_COUNTER_3_ISR;
+        DISABLE_AUDIO_COUNTER_3_ISR;
 
-		// Cancel note if a note is playing
-	    if (playing_note)
-	        stop_all_notes();
+        // Cancel note if a note is playing
+        if (playing_note)
+            stop_all_notes();
 
-	    playing_notes = true;
+        playing_notes = true;
 
-	    notes_pointer = np;
-	    notes_count = n_count;
-	    notes_repeat = n_repeat;
-	    notes_rest = n_rest;
+        notes_pointer = np;
+        notes_count = n_count;
+        notes_repeat = n_repeat;
+        notes_rest = n_rest;
 
-	    place = 0;
-	    current_note = 0;
+        place = 0;
+        current_note = 0;
 
         note_frequency = (*notes_pointer)[current_note][0];
         note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
-	    note_position = 0;
+        note_position = 0;
 
 
         ENABLE_AUDIO_COUNTER_3_ISR;
         ENABLE_AUDIO_COUNTER_3_OUTPUT;
-	}
+    }
 
 }
 
 bool is_playing_notes(void) {
-	return playing_notes;
+    return playing_notes;
 }
 
 bool is_audio_on(void) {

+ 27 - 0
quantum/audio/song_list.h

@@ -122,4 +122,31 @@
     E__NOTE(_E5),          \
     E__NOTE(_D5),
 
+#define COIN_SOUND \
+    E__NOTE(_A5  ),      \
+    HD_NOTE(_E6  ),
+
+#define ONE_UP_SOUND \
+    Q__NOTE(_E6  ),  \
+    Q__NOTE(_G6  ),  \
+    Q__NOTE(_E7  ),  \
+    Q__NOTE(_C7  ),  \
+    Q__NOTE(_D7  ),  \
+    Q__NOTE(_G7  ),
+
+#define SONIC_RING \
+    E__NOTE(_E6),  \
+    E__NOTE(_G6),  \
+    HD_NOTE(_C7),
+
+#define ZELDA_PUZZLE \
+    Q__NOTE(_G5),     \
+    Q__NOTE(_FS5),    \
+    Q__NOTE(_DS5),     \
+    Q__NOTE(_A4),    \
+    Q__NOTE(_GS4),     \
+    Q__NOTE(_E5),     \
+    Q__NOTE(_GS5),     \
+    HD_NOTE(_C6),
+
 #endif

+ 62 - 0
quantum/process_keycode/process_audio.c

@@ -0,0 +1,62 @@
+#include "audio.h"
+#include "process_audio.h"
+
+static float compute_freq_for_midi_note(uint8_t note)
+{
+    // https://en.wikipedia.org/wiki/MIDI_tuning_standard
+    return pow(2.0, (note - 69) / 12.0) * 440.0f;
+}
+
+bool process_audio(uint16_t keycode, keyrecord_t *record) {
+
+    if (keycode == AU_ON && record->event.pressed) {
+      audio_on();
+      return false;
+    }
+
+    if (keycode == AU_OFF && record->event.pressed) {
+      audio_off();
+      return false;
+    }
+
+    if (keycode == AU_TOG && record->event.pressed) {
+        if (is_audio_on())
+        {
+            audio_off();
+        }
+        else
+        {
+            audio_on();
+        }
+        return false;
+    }
+
+    if (keycode == MUV_IN && record->event.pressed) {
+        voice_iterate();
+        music_scale_user();
+        return false;
+    }
+
+    if (keycode == MUV_DE && record->event.pressed) {
+        voice_deiterate();
+        music_scale_user();
+        return false;
+    }
+
+    return true;
+}
+
+void process_audio_noteon(uint8_t note) {
+    play_note(compute_freq_for_midi_note(note), 0xF);
+}
+
+void process_audio_noteoff(uint8_t note) {
+    stop_note(compute_freq_for_midi_note(note));
+}
+
+void process_audio_all_notes_off(void) {
+    stop_all_notes();
+}
+
+__attribute__ ((weak))
+void audio_on_user() {}

+ 11 - 0
quantum/process_keycode/process_audio.h

@@ -0,0 +1,11 @@
+#ifndef PROCESS_AUDIO_H
+#define PROCESS_AUDIO_H
+
+bool process_audio(uint16_t keycode, keyrecord_t *record);
+void process_audio_noteon(uint8_t note);
+void process_audio_noteoff(uint8_t note);
+void process_audio_all_notes_off(void);
+
+void audio_on_user(void);
+
+#endif

+ 231 - 61
quantum/process_keycode/process_midi.c

@@ -1,68 +1,238 @@
 #include "process_midi.h"
 
-bool midi_activated = false;
-uint8_t midi_starting_note = 0x0C;
-int midi_offset = 7;
-
-bool process_midi(uint16_t keycode, keyrecord_t *record) {
-    if (keycode == MI_ON && record->event.pressed) {
-      midi_activated = true;
-#ifdef AUDIO_ENABLE
-      music_scale_user();
-#endif
-      return false;
-    }
+#ifdef MIDI_ENABLE
+#include "midi.h"
+
+#ifdef MIDI_BASIC
+
+void process_midi_basic_noteon(uint8_t note) 
+{
+    midi_send_noteon(&midi_device, 0, note, 128);
+}
+
+void process_midi_basic_noteoff(uint8_t note)
+{
+    midi_send_noteoff(&midi_device, 0, note, 0);
+}
+
+void process_midi_all_notes_off(void)
+{
+    midi_send_cc(&midi_device, 0, 0x7B, 0);
+}
+
+#endif // MIDI_BASIC
+
+#ifdef MIDI_ADVANCED
+
+#include "timer.h"
+
+static uint8_t tone_status[MIDI_TONE_COUNT];
+
+static uint8_t midi_modulation;
+static int8_t midi_modulation_step;
+static uint16_t midi_modulation_timer;
+
+inline uint8_t compute_velocity(uint8_t setting)
+{
+    return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
+}
 
-    if (keycode == MI_OFF && record->event.pressed) {
-      midi_activated = false;
-      midi_send_cc(&midi_device, 0, 0x7B, 0);
-      return false;
+void midi_init(void)
+{
+    midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
+    midi_config.transpose = 0;
+    midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
+    midi_config.channel = 0;
+    midi_config.modulation_interval = 8;
+
+    for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
+    {
+        tone_status[i] = MIDI_INVALID_NOTE;
     }
 
-    if (midi_activated) {
-      if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
-          if (record->event.pressed) {
-              midi_starting_note++; // Change key
-              midi_send_cc(&midi_device, 0, 0x7B, 0);
-          }
-          return false;
-      }
-      if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
-          if (record->event.pressed) {
-              midi_starting_note--; // Change key
-              midi_send_cc(&midi_device, 0, 0x7B, 0);
-          }
-          return false;
-      }
-      if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
-          midi_offset++; // Change scale
-          midi_send_cc(&midi_device, 0, 0x7B, 0);
-          return false;
-      }
-      if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
-          midi_offset--; // Change scale
-          midi_send_cc(&midi_device, 0, 0x7B, 0);
-          return false;
-      }
-      // basic
-      // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row);
-      // advanced
-      // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row);
-      // guitar
-      uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row);
-      // violin
-      // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row);
-
-      if (record->event.pressed) {
-        // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
-        midi_send_noteon(&midi_device, 0, note, 127);
-      } else {
-        // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
-        midi_send_noteoff(&midi_device, 0, note, 127);
-      }
-
-      if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
-        return false;
+    midi_modulation = 0;
+    midi_modulation_step = 0;
+    midi_modulation_timer = 0;
+}
+
+void midi_task(void)
+{
+    if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
+        return;
+    midi_modulation_timer = timer_read();
+
+    if (midi_modulation_step != 0)
+    {
+        dprintf("midi modulation %d\n", midi_modulation);
+        midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
+
+        if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
+            midi_modulation = 0;
+            midi_modulation_step = 0;
+            return;
+        }
+
+        midi_modulation += midi_modulation_step;
+
+        if (midi_modulation > 127)
+            midi_modulation = 127;
     }
-  return true;
 }
+
+uint8_t midi_compute_note(uint16_t keycode)
+{
+    return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
+}
+
+bool process_midi(uint16_t keycode, keyrecord_t *record)
+{
+    switch (keycode) {
+        case MIDI_TONE_MIN ... MIDI_TONE_MAX:
+        {
+            uint8_t channel = midi_config.channel;
+            uint8_t tone = keycode - MIDI_TONE_MIN;
+            uint8_t velocity = compute_velocity(midi_config.velocity);
+            if (record->event.pressed) {
+                uint8_t note = midi_compute_note(keycode);
+                midi_send_noteon(&midi_device, channel, note, velocity);
+                dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
+                tone_status[tone] = note;
+            }
+            else {
+                uint8_t note = tone_status[tone];
+                if (note != MIDI_INVALID_NOTE)
+                {
+                    midi_send_noteoff(&midi_device, channel, note, velocity);
+                    dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
+                }
+                tone_status[tone] = MIDI_INVALID_NOTE;
+            }
+            return false;
+        }
+        case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
+            if (record->event.pressed) {
+                midi_config.octave = keycode - MIDI_OCTAVE_MIN;
+                dprintf("midi octave %d\n", midi_config.octave);
+            }
+            return false;
+        case MI_OCTD:
+            if (record->event.pressed && midi_config.octave > 0) {
+                midi_config.octave--;
+                dprintf("midi octave %d\n", midi_config.octave);
+            }
+            return false;
+        case MI_OCTU:
+            if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
+                midi_config.octave++;
+                dprintf("midi octave %d\n", midi_config.octave);
+            }
+            return false;
+        case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
+            if (record->event.pressed) {
+                midi_config.transpose = keycode - MI_TRNS_0;
+                dprintf("midi transpose %d\n", midi_config.transpose);
+            }
+            return false;
+        case MI_TRNSD:
+            if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
+                midi_config.transpose--;
+                dprintf("midi transpose %d\n", midi_config.transpose);
+            }
+            return false;
+        case MI_TRNSU:
+            if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
+                const bool positive = midi_config.transpose > 0;
+                midi_config.transpose++;
+                if (positive && midi_config.transpose < 0)
+                    midi_config.transpose--;
+                dprintf("midi transpose %d\n", midi_config.transpose);
+            }
+            return false;
+        case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
+            if (record->event.pressed) {
+                midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
+                dprintf("midi velocity %d\n", midi_config.velocity);
+            }
+            return false;
+        case MI_VELD:
+            if (record->event.pressed && midi_config.velocity > 0) {
+                midi_config.velocity--;
+                dprintf("midi velocity %d\n", midi_config.velocity);
+            }
+            return false;
+        case MI_VELU:
+            if (record->event.pressed) {
+                midi_config.velocity++;
+                dprintf("midi velocity %d\n", midi_config.velocity);
+            }
+            return false;
+        case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
+            if (record->event.pressed) {
+                midi_config.channel = keycode - MIDI_CHANNEL_MIN;
+                dprintf("midi channel %d\n", midi_config.channel);
+            }
+            return false;
+        case MI_CHD:
+            if (record->event.pressed) {
+                midi_config.channel--;
+                dprintf("midi channel %d\n", midi_config.channel);
+            }
+            return false;
+        case MI_CHU:
+            if (record->event.pressed) {
+                midi_config.channel++;
+                dprintf("midi channel %d\n", midi_config.channel);
+            }
+            return false;
+        case MI_ALLOFF:
+            if (record->event.pressed) {
+                midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
+                dprintf("midi all notes off\n");
+            }
+            return false;
+        case MI_SUS:
+            midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
+            dprintf("midi sustain %d\n", record->event.pressed);
+            return false;
+        case MI_PORT:
+            midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
+            dprintf("midi portamento %d\n", record->event.pressed);
+            return false;
+        case MI_SOST:
+            midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
+            dprintf("midi sostenuto %d\n", record->event.pressed);
+            return false;
+        case MI_SOFT:
+            midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
+            dprintf("midi soft %d\n", record->event.pressed);
+            return false;
+        case MI_LEG:
+            midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
+            dprintf("midi legato %d\n", record->event.pressed);
+            return false;
+        case MI_MOD:
+            midi_modulation_step = record->event.pressed ? 1 : -1;
+            return false;
+        case MI_MODSD:
+            if (record->event.pressed) {
+                midi_config.modulation_interval++;
+                // prevent overflow
+                if (midi_config.modulation_interval == 0)
+                    midi_config.modulation_interval--;
+                dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
+            }
+            return false;
+        case MI_MODSU:
+            if (record->event.pressed && midi_config.modulation_interval > 0) {
+                midi_config.modulation_interval--;
+                dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
+            }
+            return false;
+    };
+
+    return true;
+}
+
+#endif // MIDI_ADVANCED
+
+#endif // MIDI_ENABLE

+ 29 - 196
quantum/process_keycode/process_midi.h

@@ -3,205 +3,38 @@
 
 #include "quantum.h"
 
-bool process_midi(uint16_t keycode, keyrecord_t *record);
+#ifdef MIDI_ENABLE
+
+#ifdef MIDI_BASIC
+void process_midi_basic_noteon(uint8_t note);
+void process_midi_basic_noteoff(uint8_t note);
+void process_midi_all_notes_off(void);
+#endif
+
+#ifdef MIDI_ADVANCED
+typedef union {
+  uint32_t raw;
+  struct {
+    uint8_t octave              :4;
+    int8_t transpose            :4;
+    uint8_t velocity            :4;
+    uint8_t channel             :4;
+    uint8_t modulation_interval :4;
+  };
+} midi_config_t;
 
-#define MIDI(n) ((n) | 0x6000)
-#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000
+midi_config_t midi_config;
+
+void midi_init(void);
+void midi_task(void);
+bool process_midi(uint16_t keycode, keyrecord_t *record);
 
-#define CHNL(note, channel) (note + (channel << 8))
+#define MIDI_INVALID_NOTE 0xFF
+#define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1)
 
-#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
-                           0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
-                           0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
-                           0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
-                           0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
+uint8_t midi_compute_note(uint16_t keycode);
+#endif // MIDI_ADVANCED
 
-#define N_CN1  (0x600C + (12 * -1) + 0 )
-#define N_CN1S (0x600C + (12 * -1) + 1 )
-#define N_DN1F (0x600C + (12 * -1) + 1 )
-#define N_DN1  (0x600C + (12 * -1) + 2 )
-#define N_DN1S (0x600C + (12 * -1) + 3 )
-#define N_EN1F (0x600C + (12 * -1) + 3 )
-#define N_EN1  (0x600C + (12 * -1) + 4 )
-#define N_FN1  (0x600C + (12 * -1) + 5 )
-#define N_FN1S (0x600C + (12 * -1) + 6 )
-#define N_GN1F (0x600C + (12 * -1) + 6 )
-#define N_GN1  (0x600C + (12 * -1) + 7 )
-#define N_GN1S (0x600C + (12 * -1) + 8 )
-#define N_AN1F (0x600C + (12 * -1) + 8 )
-#define N_AN1  (0x600C + (12 * -1) + 9 )
-#define N_AN1S (0x600C + (12 * -1) + 10)
-#define N_BN1F (0x600C + (12 * -1) + 10)
-#define N_BN1  (0x600C + (12 * -1) + 11)
-#define N_C0   (0x600C + (12 *  0) + 0 )
-#define N_C0S  (0x600C + (12 *  0) + 1 )
-#define N_D0F  (0x600C + (12 *  0) + 1 )
-#define N_D0   (0x600C + (12 *  0) + 2 )
-#define N_D0S  (0x600C + (12 *  0) + 3 )
-#define N_E0F  (0x600C + (12 *  0) + 3 )
-#define N_E0   (0x600C + (12 *  0) + 4 )
-#define N_F0   (0x600C + (12 *  0) + 5 )
-#define N_F0S  (0x600C + (12 *  0) + 6 )
-#define N_G0F  (0x600C + (12 *  0) + 6 )
-#define N_G0   (0x600C + (12 *  0) + 7 )
-#define N_G0S  (0x600C + (12 *  0) + 8 )
-#define N_A0F  (0x600C + (12 *  0) + 8 )
-#define N_A0   (0x600C + (12 *  0) + 9 )
-#define N_A0S  (0x600C + (12 *  0) + 10)
-#define N_B0F  (0x600C + (12 *  0) + 10)
-#define N_B0   (0x600C + (12 *  0) + 11)
-#define N_C1   (0x600C + (12 *  1) + 0 )
-#define N_C1S  (0x600C + (12 *  1) + 1 )
-#define N_D1F  (0x600C + (12 *  1) + 1 )
-#define N_D1   (0x600C + (12 *  1) + 2 )
-#define N_D1S  (0x600C + (12 *  1) + 3 )
-#define N_E1F  (0x600C + (12 *  1) + 3 )
-#define N_E1   (0x600C + (12 *  1) + 4 )
-#define N_F1   (0x600C + (12 *  1) + 5 )
-#define N_F1S  (0x600C + (12 *  1) + 6 )
-#define N_G1F  (0x600C + (12 *  1) + 6 )
-#define N_G1   (0x600C + (12 *  1) + 7 )
-#define N_G1S  (0x600C + (12 *  1) + 8 )
-#define N_A1F  (0x600C + (12 *  1) + 8 )
-#define N_A1   (0x600C + (12 *  1) + 9 )
-#define N_A1S  (0x600C + (12 *  1) + 10)
-#define N_B1F  (0x600C + (12 *  1) + 10)
-#define N_B1   (0x600C + (12 *  1) + 11)
-#define N_C2   (0x600C + (12 *  2) + 0 )
-#define N_C2S  (0x600C + (12 *  2) + 1 )
-#define N_D2F  (0x600C + (12 *  2) + 1 )
-#define N_D2   (0x600C + (12 *  2) + 2 )
-#define N_D2S  (0x600C + (12 *  2) + 3 )
-#define N_E2F  (0x600C + (12 *  2) + 3 )
-#define N_E2   (0x600C + (12 *  2) + 4 )
-#define N_F2   (0x600C + (12 *  2) + 5 )
-#define N_F2S  (0x600C + (12 *  2) + 6 )
-#define N_G2F  (0x600C + (12 *  2) + 6 )
-#define N_G2   (0x600C + (12 *  2) + 7 )
-#define N_G2S  (0x600C + (12 *  2) + 8 )
-#define N_A2F  (0x600C + (12 *  2) + 8 )
-#define N_A2   (0x600C + (12 *  2) + 9 )
-#define N_A2S  (0x600C + (12 *  2) + 10)
-#define N_B2F  (0x600C + (12 *  2) + 10)
-#define N_B2   (0x600C + (12 *  2) + 11)
-#define N_C3   (0x600C + (12 *  3) + 0 )
-#define N_C3S  (0x600C + (12 *  3) + 1 )
-#define N_D3F  (0x600C + (12 *  3) + 1 )
-#define N_D3   (0x600C + (12 *  3) + 2 )
-#define N_D3S  (0x600C + (12 *  3) + 3 )
-#define N_E3F  (0x600C + (12 *  3) + 3 )
-#define N_E3   (0x600C + (12 *  3) + 4 )
-#define N_F3   (0x600C + (12 *  3) + 5 )
-#define N_F3S  (0x600C + (12 *  3) + 6 )
-#define N_G3F  (0x600C + (12 *  3) + 6 )
-#define N_G3   (0x600C + (12 *  3) + 7 )
-#define N_G3S  (0x600C + (12 *  3) + 8 )
-#define N_A3F  (0x600C + (12 *  3) + 8 )
-#define N_A3   (0x600C + (12 *  3) + 9 )
-#define N_A3S  (0x600C + (12 *  3) + 10)
-#define N_B3F  (0x600C + (12 *  3) + 10)
-#define N_B3   (0x600C + (12 *  3) + 11)
-#define N_C4   (0x600C + (12 *  4) + 0 )
-#define N_C4S  (0x600C + (12 *  4) + 1 )
-#define N_D4F  (0x600C + (12 *  4) + 1 )
-#define N_D4   (0x600C + (12 *  4) + 2 )
-#define N_D4S  (0x600C + (12 *  4) + 3 )
-#define N_E4F  (0x600C + (12 *  4) + 3 )
-#define N_E4   (0x600C + (12 *  4) + 4 )
-#define N_F4   (0x600C + (12 *  4) + 5 )
-#define N_F4S  (0x600C + (12 *  4) + 6 )
-#define N_G4F  (0x600C + (12 *  4) + 6 )
-#define N_G4   (0x600C + (12 *  4) + 7 )
-#define N_G4S  (0x600C + (12 *  4) + 8 )
-#define N_A4F  (0x600C + (12 *  4) + 8 )
-#define N_A4   (0x600C + (12 *  4) + 9 )
-#define N_A4S  (0x600C + (12 *  4) + 10)
-#define N_B4F  (0x600C + (12 *  4) + 10)
-#define N_B4   (0x600C + (12 *  4) + 11)
-#define N_C5   (0x600C + (12 *  5) + 0 )
-#define N_C5S  (0x600C + (12 *  5) + 1 )
-#define N_D5F  (0x600C + (12 *  5) + 1 )
-#define N_D5   (0x600C + (12 *  5) + 2 )
-#define N_D5S  (0x600C + (12 *  5) + 3 )
-#define N_E5F  (0x600C + (12 *  5) + 3 )
-#define N_E5   (0x600C + (12 *  5) + 4 )
-#define N_F5   (0x600C + (12 *  5) + 5 )
-#define N_F5S  (0x600C + (12 *  5) + 6 )
-#define N_G5F  (0x600C + (12 *  5) + 6 )
-#define N_G5   (0x600C + (12 *  5) + 7 )
-#define N_G5S  (0x600C + (12 *  5) + 8 )
-#define N_A5F  (0x600C + (12 *  5) + 8 )
-#define N_A5   (0x600C + (12 *  5) + 9 )
-#define N_A5S  (0x600C + (12 *  5) + 10)
-#define N_B5F  (0x600C + (12 *  5) + 10)
-#define N_B5   (0x600C + (12 *  5) + 11)
-#define N_C6   (0x600C + (12 *  6) + 0 )
-#define N_C6S  (0x600C + (12 *  6) + 1 )
-#define N_D6F  (0x600C + (12 *  6) + 1 )
-#define N_D6   (0x600C + (12 *  6) + 2 )
-#define N_D6S  (0x600C + (12 *  6) + 3 )
-#define N_E6F  (0x600C + (12 *  6) + 3 )
-#define N_E6   (0x600C + (12 *  6) + 4 )
-#define N_F6   (0x600C + (12 *  6) + 5 )
-#define N_F6S  (0x600C + (12 *  6) + 6 )
-#define N_G6F  (0x600C + (12 *  6) + 6 )
-#define N_G6   (0x600C + (12 *  6) + 7 )
-#define N_G6S  (0x600C + (12 *  6) + 8 )
-#define N_A6F  (0x600C + (12 *  6) + 8 )
-#define N_A6   (0x600C + (12 *  6) + 9 )
-#define N_A6S  (0x600C + (12 *  6) + 10)
-#define N_B6F  (0x600C + (12 *  6) + 10)
-#define N_B6   (0x600C + (12 *  6) + 11)
-#define N_C7   (0x600C + (12 *  7) + 0 )
-#define N_C7S  (0x600C + (12 *  7) + 1 )
-#define N_D7F  (0x600C + (12 *  7) + 1 )
-#define N_D7   (0x600C + (12 *  7) + 2 )
-#define N_D7S  (0x600C + (12 *  7) + 3 )
-#define N_E7F  (0x600C + (12 *  7) + 3 )
-#define N_E7   (0x600C + (12 *  7) + 4 )
-#define N_F7   (0x600C + (12 *  7) + 5 )
-#define N_F7S  (0x600C + (12 *  7) + 6 )
-#define N_G7F  (0x600C + (12 *  7) + 6 )
-#define N_G7   (0x600C + (12 *  7) + 7 )
-#define N_G7S  (0x600C + (12 *  7) + 8 )
-#define N_A7F  (0x600C + (12 *  7) + 8 )
-#define N_A7   (0x600C + (12 *  7) + 9 )
-#define N_A7S  (0x600C + (12 *  7) + 10)
-#define N_B7F  (0x600C + (12 *  7) + 10)
-#define N_B7   (0x600C + (12 *  7) + 11)
-#define N_C8   (0x600C + (12 *  8) + 0 )
-#define N_C8S  (0x600C + (12 *  8) + 1 )
-#define N_D8F  (0x600C + (12 *  8) + 1 )
-#define N_D8   (0x600C + (12 *  8) + 2 )
-#define N_D8S  (0x600C + (12 *  8) + 3 )
-#define N_E8F  (0x600C + (12 *  8) + 3 )
-#define N_E8   (0x600C + (12 *  8) + 4 )
-#define N_F8   (0x600C + (12 *  8) + 5 )
-#define N_F8S  (0x600C + (12 *  8) + 6 )
-#define N_G8F  (0x600C + (12 *  8) + 6 )
-#define N_G8   (0x600C + (12 *  8) + 7 )
-#define N_G8S  (0x600C + (12 *  8) + 8 )
-#define N_A8F  (0x600C + (12 *  8) + 8 )
-#define N_A8   (0x600C + (12 *  8) + 9 )
-#define N_A8S  (0x600C + (12 *  8) + 10)
-#define N_B8F  (0x600C + (12 *  8) + 10)
-#define N_B8   (0x600C + (12 *  8) + 11)
-#define N_C8   (0x600C + (12 *  8) + 0 )
-#define N_C8S  (0x600C + (12 *  8) + 1 )
-#define N_D8F  (0x600C + (12 *  8) + 1 )
-#define N_D8   (0x600C + (12 *  8) + 2 )
-#define N_D8S  (0x600C + (12 *  8) + 3 )
-#define N_E8F  (0x600C + (12 *  8) + 3 )
-#define N_E8   (0x600C + (12 *  8) + 4 )
-#define N_F8   (0x600C + (12 *  8) + 5 )
-#define N_F8S  (0x600C + (12 *  8) + 6 )
-#define N_G8F  (0x600C + (12 *  8) + 6 )
-#define N_G8   (0x600C + (12 *  8) + 7 )
-#define N_G8S  (0x600C + (12 *  8) + 8 )
-#define N_A8F  (0x600C + (12 *  8) + 8 )
-#define N_A8   (0x600C + (12 *  8) + 9 )
-#define N_A8S  (0x600C + (12 *  8) + 10)
-#define N_B8F  (0x600C + (12 *  8) + 10)
-#define N_B8   (0x600C + (12 *  8) + 11)
+#endif // MIDI_ENABLE
 
 #endif

+ 61 - 57
quantum/process_keycode/process_music.c

@@ -1,5 +1,14 @@
 #include "process_music.h"
 
+#ifdef AUDIO_ENABLE
+#include "process_audio.h"
+#endif
+#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
+#include "process_midi.h"
+#endif
+
+#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
+
 bool music_activated = false;
 uint8_t music_starting_note = 0x0C;
 int music_offset = 7;
@@ -8,36 +17,41 @@ int music_offset = 7;
 static bool music_sequence_recording = false;
 static bool music_sequence_recorded = false;
 static bool music_sequence_playing = false;
-static float music_sequence[16] = {0};
+static uint8_t music_sequence[16] = {0};
 static uint8_t music_sequence_count = 0;
 static uint8_t music_sequence_position = 0;
 
 static uint16_t music_sequence_timer = 0;
 static uint16_t music_sequence_interval = 100;
 
-bool process_music(uint16_t keycode, keyrecord_t *record) {
+static void music_noteon(uint8_t note) {
+    #ifdef AUDIO_ENABLE
+    process_audio_noteon(note);
+    #endif
+    #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
+    process_midi_basic_noteon(note);
+    #endif
+}
 
-    if (keycode == AU_ON && record->event.pressed) {
-      audio_on();
-      return false;
-    }
+static void music_noteoff(uint8_t note) {
+    #ifdef AUDIO_ENABLE
+    process_audio_noteoff(note);
+    #endif
+    #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
+    process_midi_basic_noteoff(note);
+    #endif
+}
 
-    if (keycode == AU_OFF && record->event.pressed) {
-      audio_off();
-      return false;
-    }
+void music_all_notes_off(void) {
+    #ifdef AUDIO_ENABLE
+    process_audio_all_notes_off();
+    #endif
+    #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
+    process_midi_all_notes_off();
+    #endif
+}
 
-    if (keycode == AU_TOG && record->event.pressed) {
-        if (is_audio_on())
-        {
-            audio_off();
-        }
-        else
-        {
-            audio_on();
-        }
-      return false;
-    }
+bool process_music(uint16_t keycode, keyrecord_t *record) {
 
     if (keycode == MU_ON && record->event.pressed) {
         music_on();
@@ -61,22 +75,10 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
         return false;
     }
 
-    if (keycode == MUV_IN && record->event.pressed) {
-        voice_iterate();
-        music_scale_user();
-        return false;
-    }
-
-    if (keycode == MUV_DE && record->event.pressed) {
-        voice_deiterate();
-        music_scale_user();
-        return false;
-    }
-
     if (music_activated) {
 
       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
-        stop_all_notes();
+        music_all_notes_off();
         music_sequence_recording = true;
         music_sequence_recorded = false;
         music_sequence_playing = false;
@@ -85,7 +87,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
       }
 
       if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
-        stop_all_notes();
+        music_all_notes_off();
         if (music_sequence_recording) { // was recording
           music_sequence_recorded = true;
         }
@@ -95,7 +97,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
       }
 
       if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing
-        stop_all_notes();
+        music_all_notes_off();
         music_sequence_recording = false;
         music_sequence_playing = true;
         music_sequence_position = 0;
@@ -114,32 +116,34 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
             music_sequence_interval+=10;
         return false;
       }
+
       #define MUSIC_MODE_GUITAR
 
       #ifdef MUSIC_MODE_CHROMATIC
-      float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(MATRIX_ROWS - record->event.key.row));
+      uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
       #elif defined(MUSIC_MODE_GUITAR)
-      float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 7)*5.0/12);
+      uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
       #elif defined(MUSIC_MODE_VIOLIN)
-      float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 5)*7.0/12);
+      uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
       #else
-      float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + SCALE[record->event.key.col + music_offset])/12.0+(MATRIX_ROWS - record->event.key.row));
+      uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
       #endif
 
       if (record->event.pressed) {
-        play_note(freq, 0xF);
+        music_noteon(note);
         if (music_sequence_recording) {
-          music_sequence[music_sequence_count] = freq;
+          music_sequence[music_sequence_count] = note;
           music_sequence_count++;
         }
       } else {
-        stop_note(freq);
+        music_noteoff(note);
       }
 
       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
         return false;
     }
-  return true;
+
+    return true;
 }
 
 bool is_music_on(void) {
@@ -161,26 +165,26 @@ void music_on(void) {
 
 void music_off(void) {
     music_activated = 0;
-    stop_all_notes();
+    music_all_notes_off();
 }
 
-
-__attribute__ ((weak))
-void music_on_user() {}
-
-__attribute__ ((weak))
-void audio_on_user() {}
-
-__attribute__ ((weak))
-void music_scale_user() {}
-
 void matrix_scan_music(void) {
   if (music_sequence_playing) {
     if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
       music_sequence_timer = timer_read();
-      stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
-      play_note(music_sequence[music_sequence_position], 0xF);
+      uint8_t prev_note = music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)];
+      uint8_t next_note = music_sequence[music_sequence_position];
+      music_noteoff(prev_note);
+      music_noteon(next_note);
       music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
     }
   }
 }
+
+__attribute__ ((weak))
+void music_on_user() {}
+
+__attribute__ ((weak))
+void music_scale_user() {}
+
+#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))

+ 5 - 1
quantum/process_keycode/process_music.h

@@ -3,6 +3,8 @@
 
 #include "quantum.h"
 
+#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
+
 bool process_music(uint16_t keycode, keyrecord_t *record);
 
 bool is_music_on(void);
@@ -10,9 +12,9 @@ void music_toggle(void);
 void music_on(void);
 void music_off(void);
 
-void audio_on_user(void);
 void music_on_user(void);
 void music_scale_user(void);
+void music_all_notes_off(void);
 
 void matrix_scan_music(void);
 
@@ -24,4 +26,6 @@ void matrix_scan_music(void);
                            0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
 #endif
 
+#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
+
 #endif

+ 6 - 11
quantum/quantum.c

@@ -98,8 +98,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 
 void reset_keyboard(void) {
   clear_keyboard();
-#ifdef AUDIO_ENABLE
-  stop_all_notes();
+#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
+  music_all_notes_off();
   shutdown_user();
 #endif
   wait_ms(250);
@@ -153,10 +153,13 @@ bool process_record_quantum(keyrecord_t *record) {
 
   if (!(
     process_record_kb(keycode, record) &&
-  #ifdef MIDI_ENABLE
+  #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
     process_midi(keycode, record) &&
   #endif
   #ifdef AUDIO_ENABLE
+    process_audio(keycode, record) &&
+  #endif
+  #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
     process_music(keycode, record) &&
   #endif
   #ifdef TAP_DANCE_ENABLE
@@ -294,14 +297,6 @@ bool process_record_quantum(keyrecord_t *record) {
       return false;
       break;
     #endif
-    #ifdef ADAFRUIT_BLE_ENABLE
-    case OUT_BLE:
-      if (record->event.pressed) {
-        set_output(OUTPUT_ADAFRUIT_BLE);
-      }
-      return false;
-      break;
-    #endif
     #endif
     case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
       if (record->event.pressed) {

+ 6 - 1
quantum/quantum.h

@@ -35,11 +35,16 @@ extern uint32_t default_layer_state;
 
 #ifdef MIDI_ENABLE
 	#include <lufa.h>
+#ifdef MIDI_ADVANCED
 	#include "process_midi.h"
 #endif
+#endif // MIDI_ENABLE
 
 #ifdef AUDIO_ENABLE
- 	#include "audio.h"
+ 	#include "process_audio.h"
+#endif
+
+#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
 	#include "process_music.h"
 #endif
 

+ 234 - 10
quantum/quantum_keycodes.h

@@ -1,7 +1,16 @@
-
 #ifndef QUANTUM_KEYCODES_H
 #define QUANTUM_KEYCODES_H
 
+#ifndef MIDI_ENABLE_STRICT
+#define MIDI_ENABLE_STRICT 0
+#endif
+
+#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
+#ifndef MIDI_TONE_KEYCODE_OCTAVES
+#define MIDI_TONE_KEYCODE_OCTAVES 3
+#endif
+#endif
+
 enum quantum_keycodes {
     // Ranges used in shortucuts - not to be used directly
     QK_TMK                = 0x0000,
@@ -107,9 +116,230 @@ enum quantum_keycodes {
     MUV_IN,
     MUV_DE,
 
-    // Midi mode on/off
-    MIDI_ON,
-    MIDI_OFF,
+    // Midi
+#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
+    MI_ON,  // send midi notes when music mode is enabled
+    MI_OFF, // don't send midi notes when music mode is enabled
+#endif
+
+#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
+    MIDI_TONE_MIN,
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 0
+    MI_C = MIDI_TONE_MIN,
+    MI_Cs,
+    MI_Db = MI_Cs,
+    MI_D,
+    MI_Ds,
+    MI_Eb = MI_Ds,
+    MI_E,
+    MI_F,
+    MI_Fs,
+    MI_Gb = MI_Fs,
+    MI_G,
+    MI_Gs,
+    MI_Ab = MI_Gs,
+    MI_A,
+    MI_As,
+    MI_Bb = MI_As,
+    MI_B,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 1
+    MI_C_1,
+    MI_Cs_1,
+    MI_Db_1 = MI_Cs_1,
+    MI_D_1,
+    MI_Ds_1,
+    MI_Eb_1 = MI_Ds_1,
+    MI_E_1,
+    MI_F_1,
+    MI_Fs_1,
+    MI_Gb_1 = MI_Fs_1,
+    MI_G_1,
+    MI_Gs_1,
+    MI_Ab_1 = MI_Gs_1,
+    MI_A_1,
+    MI_As_1,
+    MI_Bb_1 = MI_As_1,
+    MI_B_1,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 2
+    MI_C_2,
+    MI_Cs_2,
+    MI_Db_2 = MI_Cs_2,
+    MI_D_2,
+    MI_Ds_2,
+    MI_Eb_2 = MI_Ds_2,
+    MI_E_2,
+    MI_F_2,
+    MI_Fs_2,
+    MI_Gb_2 = MI_Fs_2,
+    MI_G_2,
+    MI_Gs_2,
+    MI_Ab_2 = MI_Gs_2,
+    MI_A_2,
+    MI_As_2,
+    MI_Bb_2 = MI_As_2,
+    MI_B_2,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 3
+    MI_C_3,
+    MI_Cs_3,
+    MI_Db_3 = MI_Cs_3,
+    MI_D_3,
+    MI_Ds_3,
+    MI_Eb_3 = MI_Ds_3,
+    MI_E_3,
+    MI_F_3,
+    MI_Fs_3,
+    MI_Gb_3 = MI_Fs_3,
+    MI_G_3,
+    MI_Gs_3,
+    MI_Ab_3 = MI_Gs_3,
+    MI_A_3,
+    MI_As_3,
+    MI_Bb_3 = MI_As_3,
+    MI_B_3,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 4
+    MI_C_4,
+    MI_Cs_4,
+    MI_Db_4 = MI_Cs_4,
+    MI_D_4,
+    MI_Ds_4,
+    MI_Eb_4 = MI_Ds_4,
+    MI_E_4,
+    MI_F_4,
+    MI_Fs_4,
+    MI_Gb_4 = MI_Fs_4,
+    MI_G_4,
+    MI_Gs_4,
+    MI_Ab_4 = MI_Gs_4,
+    MI_A_4,
+    MI_As_4,
+    MI_Bb_4 = MI_As_4,
+    MI_B_4,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
+    MI_C_5,
+    MI_Cs_5,
+    MI_Db_5 = MI_Cs_5,
+    MI_D_5,
+    MI_Ds_5,
+    MI_Eb_5 = MI_Ds_5,
+    MI_E_5,
+    MI_F_5,
+    MI_Fs_5,
+    MI_Gb_5 = MI_Fs_5,
+    MI_G_5,
+    MI_Gs_5,
+    MI_Ab_5 = MI_Gs_5,
+    MI_A_5,
+    MI_As_5,
+    MI_Bb_5 = MI_As_5,
+    MI_B_5,
+#endif
+
+#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
+    MIDI_TONE_MAX = MI_B_5,
+#elif MIDI_TONE_KEYCODE_OCTAVES > 4
+    MIDI_TONE_MAX = MI_B_4,
+#elif MIDI_TONE_KEYCODE_OCTAVES > 3
+    MIDI_TONE_MAX = MI_B_3,
+#elif MIDI_TONE_KEYCODE_OCTAVES > 2
+    MIDI_TONE_MAX = MI_B_2,
+#elif MIDI_TONE_KEYCODE_OCTAVES > 1
+    MIDI_TONE_MAX = MI_B_1,
+#elif MIDI_TONE_KEYCODE_OCTAVES > 0
+    MIDI_TONE_MAX = MI_B,
+#endif
+
+    MIDI_OCTAVE_MIN,
+    MI_OCT_N2 = MIDI_OCTAVE_MIN,
+    MI_OCT_N1,
+    MI_OCT_0,
+    MI_OCT_1,
+    MI_OCT_2,
+    MI_OCT_3,
+    MI_OCT_4,
+    MI_OCT_5,
+    MI_OCT_6,
+    MI_OCT_7,
+    MIDI_OCTAVE_MAX = MI_OCT_7,
+    MI_OCTD, // octave down
+    MI_OCTU, // octave up
+
+    MIDI_TRANSPOSE_MIN,
+    MI_TRNS_N6 = MIDI_TRANSPOSE_MIN,
+    MI_TRNS_N5,
+    MI_TRNS_N4,
+    MI_TRNS_N3,
+    MI_TRNS_N2,
+    MI_TRNS_N1,
+    MI_TRNS_0,
+    MI_TRNS_1,
+    MI_TRNS_2,
+    MI_TRNS_3,
+    MI_TRNS_4,
+    MI_TRNS_5,
+    MI_TRNS_6,
+    MIDI_TRANSPOSE_MAX = MI_TRNS_6,
+    MI_TRNSD, // transpose down
+    MI_TRNSU, // transpose up
+
+    MIDI_VELOCITY_MIN,
+    MI_VEL_1 = MIDI_VELOCITY_MIN,
+    MI_VEL_2,
+    MI_VEL_3,
+    MI_VEL_4,
+    MI_VEL_5,
+    MI_VEL_6,
+    MI_VEL_7,
+    MI_VEL_8,
+    MI_VEL_9,
+    MI_VEL_10,
+    MIDI_VELOCITY_MAX = MI_VEL_10,
+    MI_VELD, // velocity down
+    MI_VELU, // velocity up
+
+    MIDI_CHANNEL_MIN,
+    MI_CH1 = MIDI_CHANNEL_MIN,
+    MI_CH2,
+    MI_CH3,
+    MI_CH4,
+    MI_CH5,
+    MI_CH6,
+    MI_CH7,
+    MI_CH8,
+    MI_CH9,
+    MI_CH10,
+    MI_CH11,
+    MI_CH12,
+    MI_CH13,
+    MI_CH14,
+    MI_CH15,
+    MI_CH16,
+    MIDI_CHANNEL_MAX = MI_CH16,
+    MI_CHD, // previous channel
+    MI_CHU, // next channel
+
+    MI_ALLOFF, // all notes off
+
+    MI_SUS, // sustain
+    MI_PORT, // portamento
+    MI_SOST, // sostenuto
+    MI_SOFT, // soft pedal
+    MI_LEG,  // legato
+
+    MI_MOD, // modulation
+    MI_MODSD, // decrease modulation speed
+    MI_MODSU, // increase modulation speed
+#endif // MIDI_ADVANCED
 
     // Backlight functionality
     BL_0,
@@ -159,9 +389,6 @@ enum quantum_keycodes {
 #ifdef BLUETOOTH_ENABLE
     OUT_BT,
 #endif
-#ifdef ADAFRUIT_BLE_ENABLE
-    OUT_BLE,
-#endif
 
     // always leave at the end
     SAFE_RANGE
@@ -282,9 +509,6 @@ enum quantum_keycodes {
 #define BL_ON  BL_9
 #define BL_OFF BL_0
 
-#define MI_ON MIDI_ON
-#define MI_OFF MIDI_OFF
-
 // GOTO layer - 16 layers max
 // when:
 // ON_PRESS    = 1

+ 23 - 0
quantum/template/config.h

@@ -159,4 +159,27 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //#define NO_ACTION_MACRO
 //#define NO_ACTION_FUNCTION
 
+/*
+ * 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
+
 #endif

+ 1 - 1
quantum/template/keymaps/default/Makefile

@@ -9,7 +9,7 @@ CONSOLE_ENABLE = no         # Console for debug(+400)
 COMMAND_ENABLE = yes        # Commands for debug and configuration
 NKRO_ENABLE = yes           # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
 BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
-MIDI_ENABLE = no            # MIDI controls
+MIDI_ENABLE = no            # MIDI support (+2400 to 4200, depending on config)
 AUDIO_ENABLE = no           # Audio output on port C6
 UNICODE_ENABLE = no         # Unicode
 BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID

+ 1 - 1
quantum/template/rules.mk

@@ -61,7 +61,7 @@ SLEEP_LED_ENABLE ?= no       # Breathing sleep LED during USB suspend
 # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
 NKRO_ENABLE ?= no            # USB Nkey Rollover
 BACKLIGHT_ENABLE ?= no       # Enable keyboard backlight functionality on B7 by default
-MIDI_ENABLE ?= no            # MIDI controls
+MIDI_ENABLE ?= no            # MIDI support (+2400 to 4200, depending on config)
 UNICODE_ENABLE ?= no         # Unicode
 BLUETOOTH_ENABLE ?= no       # Enable Bluetooth with the Adafruit EZ-Key HID
 AUDIO_ENABLE ?= no           # Audio output on port C6

+ 10 - 4
tmk_core/common.mk

@@ -93,14 +93,20 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
     TMK_COMMON_DEFS += -DBACKLIGHT_ENABLE
 endif
 
-ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
-    TMK_COMMON_DEFS += -DADAFRUIT_BLE_ENABLE
-endif
-
 ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
     TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
 endif
 
+ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
+		TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+		TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE
+endif
+
+ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
+		TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
+		TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_EZKEY
+endif
+
 ifeq ($(strip $(ONEHAND_ENABLE)), yes)
     TMK_COMMON_DEFS += -DONEHAND_ENABLE
 endif

+ 5 - 4
tmk_core/common/action_tapping.c

@@ -228,6 +228,7 @@ bool process_tapping(keyrecord_t *keyp)
         if (WITHIN_TAPPING_TERM(event)) {
             if (event.pressed) {
                 if (IS_TAPPING_KEY(event.key)) {
+#ifndef TAPPING_FORCE_HOLD
                     if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
                         // sequential tap.
                         keyp->tap = tapping_key.tap;
@@ -237,11 +238,11 @@ bool process_tapping(keyrecord_t *keyp)
                         tapping_key = *keyp;
                         debug_tapping_key();
                         return true;
-                    } else {
-                        // FIX: start new tap again
-                        tapping_key = *keyp;
-                        return true;
                     }
+#endif
+                    // FIX: start new tap again
+                    tapping_key = *keyp;
+                    return true;
                 } else if (is_tap_key(event.key)) {
                     // Sequential tap can be interfered with other tap key.
                     debug("Tapping: Start with interfering other tap.\n");

+ 9 - 3
tmk_core/protocol/lufa.mk

@@ -22,11 +22,16 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)
 	include $(TMK_PATH)/protocol/midi.mk
 endif
 
-ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
-	LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
+ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+	LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
+	$(TMK_DIR)/protocol/serial_uart.c
 endif
 
-ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
+		LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
+endif
+
+ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
 	LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
 	$(TMK_DIR)/protocol/serial_uart.c
 endif
@@ -54,6 +59,7 @@ LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
 LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
 #LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
 LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 
+LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
 LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
 
 # Remote wakeup fix for ATmega32U2        https://github.com/tmk/tmk_keyboard/issues/361

+ 2 - 2
tmk_core/protocol/lufa/adafruit_ble.h

@@ -3,7 +3,7 @@
  * Supports the Adafruit BLE board built around the nRF51822 chip.
  */
 #pragma once
-#ifdef ADAFRUIT_BLE_ENABLE
+#ifdef MODULE_ADAFRUIT_BLE
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
@@ -57,4 +57,4 @@ extern bool adafruit_ble_set_power_level(int8_t level);
 }
 #endif
 
-#endif // ADAFRUIT_BLE_ENABLE
+#endif // MODULE_ADAFRUIT_BLE

+ 48 - 44
tmk_core/protocol/lufa/lufa.c

@@ -67,10 +67,11 @@
 #endif
 
 #ifdef BLUETOOTH_ENABLE
-    #include "bluetooth.h"
-#endif
-#ifdef ADAFRUIT_BLE_ENABLE
+  #ifdef MODULE_ADAFRUIT_BLE
     #include "adafruit_ble.h"
+  #else
+    #include "bluetooth.h"
+  #endif
 #endif
 
 #ifdef VIRTSER_ENABLE
@@ -602,18 +603,16 @@ static void send_keyboard(report_keyboard_t *report)
     uint8_t where = where_to_send();
 
 #ifdef BLUETOOTH_ENABLE
-    if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
-        bluefruit_serial_send(0xFD);
-        for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
-            bluefruit_serial_send(report->raw[i]);
-        }
-    }
-#endif
-
-#ifdef ADAFRUIT_BLE_ENABLE
-    if (where == OUTPUT_ADAFRUIT_BLE) {
+  if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+    #ifdef MODULE_ADAFRUIT_BLE
       adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
-    }
+    #else
+      bluefruit_serial_send(0xFD);
+      for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
+        bluefruit_serial_send(report->raw[i]);
+      }
+    #endif
+  }
 #endif
 
     if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
@@ -660,24 +659,22 @@ static void send_mouse(report_mouse_t *report)
     uint8_t where = where_to_send();
 
 #ifdef BLUETOOTH_ENABLE
-    if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
-        bluefruit_serial_send(0xFD);
-        bluefruit_serial_send(0x00);
-        bluefruit_serial_send(0x03);
-        bluefruit_serial_send(report->buttons);
-        bluefruit_serial_send(report->x);
-        bluefruit_serial_send(report->y);
-        bluefruit_serial_send(report->v); // should try sending the wheel v here
-        bluefruit_serial_send(report->h); // should try sending the wheel h here
-        bluefruit_serial_send(0x00);
-    }
-#endif
-
-#ifdef ADAFRUIT_BLE_ENABLE
-    if (where == OUTPUT_ADAFRUIT_BLE) {
+  if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+    #ifdef MODULE_ADAFRUIT_BLE
       // FIXME: mouse buttons
       adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
-    }
+    #else
+      bluefruit_serial_send(0xFD);
+      bluefruit_serial_send(0x00);
+      bluefruit_serial_send(0x03);
+      bluefruit_serial_send(report->buttons);
+      bluefruit_serial_send(report->x);
+      bluefruit_serial_send(report->y);
+      bluefruit_serial_send(report->v); // should try sending the wheel v here
+      bluefruit_serial_send(report->h); // should try sending the wheel h here
+      bluefruit_serial_send(0x00);
+    #endif
+  }
 #endif
 
     if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
@@ -727,6 +724,9 @@ static void send_consumer(uint16_t data)
 
 #ifdef BLUETOOTH_ENABLE
     if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+      #ifdef MODULE_ADAFRUIT_BLE
+        adafruit_ble_send_consumer_key(data, 0);
+      #else
         static uint16_t last_data = 0;
         if (data == last_data) return;
         last_data = data;
@@ -740,12 +740,7 @@ static void send_consumer(uint16_t data)
         bluefruit_serial_send(0x00);
         bluefruit_serial_send(0x00);
         bluefruit_serial_send(0x00);
-    }
-#endif
-
-#ifdef ADAFRUIT_BLE_ENABLE
-    if (where == OUTPUT_ADAFRUIT_BLE) {
-      adafruit_ble_send_consumer_key(data, 0);
+      #endif
     }
 #endif
 
@@ -1101,16 +1096,23 @@ void cc_callback(MidiDevice * device,
     uint8_t chan, uint8_t num, uint8_t val);
 void sysex_callback(MidiDevice * device,
     uint16_t start, uint8_t length, uint8_t * data);
+
+void setup_midi(void)
+{
+#ifdef MIDI_ADVANCED
+	midi_init();
+#endif
+	midi_device_init(&midi_device);
+    midi_device_set_send_func(&midi_device, usb_send_func);
+    midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
+}
 #endif
 
 int main(void)  __attribute__ ((weak));
 int main(void)
 {
-
 #ifdef MIDI_ENABLE
-    midi_device_init(&midi_device);
-    midi_device_set_send_func(&midi_device, usb_send_func);
-    midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
+    setup_midi();
 #endif
 
     setup_mcu();
@@ -1130,7 +1132,7 @@ int main(void)
     // midi_send_noteoff(&midi_device, 0, 64, 127);
 #endif
 
-#ifdef BLUETOOTH_ENABLE
+#ifdef MODULE_ADAFRUIT_EZKEY
     serial_init();
 #endif
 
@@ -1161,7 +1163,7 @@ int main(void)
 
     print("Keyboard start.\n");
     while (1) {
-        #if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE)
+        #if !defined(BLUETOOTH_ENABLE)
         while (USB_DeviceState == DEVICE_STATE_Suspended) {
             print("[s]");
             suspend_power_down();
@@ -1175,14 +1177,16 @@ int main(void)
 
 #ifdef MIDI_ENABLE
         midi_device_process(&midi_device);
-        // MIDI_Task();
+#ifdef MIDI_ADVANCED
+        midi_task();
+#endif
 #endif
 
 #if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
         rgblight_task();
 #endif
 
-#ifdef ADAFRUIT_BLE_ENABLE
+#ifdef MODULE_ADAFRUIT_BLE
         adafruit_ble_task();
 #endif
 

+ 1 - 1
tmk_core/protocol/lufa/lufa.h

@@ -49,7 +49,7 @@
 #include <LUFA/Drivers/USB/USB.h>
 #include "host.h"
 #ifdef MIDI_ENABLE
-  #include "midi.h"
+  #include "process_midi.h"
 #endif
 #ifdef __cplusplus
 extern "C" {

+ 3 - 3
tmk_core/protocol/lufa/outputselect.c

@@ -14,7 +14,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "lufa.h"
 #include "outputselect.h"
-#ifdef ADAFRUIT_BLE_ENABLE
+#ifdef MODULE_ADAFRUIT_BLE
     #include "adafruit_ble.h"
 #endif
 
@@ -34,9 +34,9 @@ uint8_t auto_detect_output(void) {
         return OUTPUT_USB;
     }
 
-#ifdef ADAFRUIT_BLE_ENABLE
+#ifdef MODULE_ADAFRUIT_BLE
     if (adafruit_ble_is_connected()) {
-        return OUTPUT_ADAFRUIT_BLE;
+        return OUTPUT_BLUETOOTH;
     }
 #endif
 

部分文件因为文件数量过多而无法显示