Jack Humbert %!s(int64=7) %!d(string=hai) anos
pai
achega
5112eab859
Modificáronse 100 ficheiros con 5245 adicións e 1916 borrados
  1. 3 3
      CODE_OF_CONDUCT.md
  2. 13 18
      Makefile
  3. 1 1
      Vagrantfile
  4. 82 29
      build_keyboard.mk
  5. 1 0
      common.mk
  6. 23 17
      common_features.mk
  7. 4 0
      docs/LANGS.md
  8. 37 38
      docs/_sidebar.md
  9. 38 41
      docs/_summary.md
  10. 87 0
      docs/arm_debugging.md
  11. 6 4
      docs/becoming_a_qmk_collaborator.md
  12. 65 7
      docs/config_options.md
  13. 22 2
      docs/contributing.md
  14. 161 21
      docs/custom_quantum_functions.md
  15. 1 1
      docs/documentation_templates.md
  16. 12 2
      docs/faq_build.md
  17. 11 29
      docs/faq_keymap.md
  18. 143 106
      docs/feature_advanced_keycodes.md
  19. 8 8
      docs/feature_audio.md
  20. 55 19
      docs/feature_backlight.md
  21. 31 1
      docs/feature_bluetooth.md
  22. 151 89
      docs/feature_bootmagic.md
  23. 89 0
      docs/feature_combo.md
  24. 41 43
      docs/feature_command.md
  25. 3 3
      docs/feature_dynamic_macros.md
  26. 48 0
      docs/feature_encoders.md
  27. 15 8
      docs/feature_grave_esc.md
  28. 18 7
      docs/feature_key_lock.md
  29. 6 0
      docs/feature_layouts.md
  30. 9 1
      docs/feature_leader_key.md
  31. 4 0
      docs/feature_macros.md
  32. 18 0
      docs/feature_ps2_mouse.md
  33. 78 5
      docs/feature_rgb_matrix.md
  34. 120 121
      docs/feature_rgblight.md
  35. 0 24
      docs/feature_space_cadet.md
  36. 33 0
      docs/feature_space_cadet_shift.md
  37. 31 0
      docs/feature_space_cadet_shift_enter.md
  38. 0 26
      docs/feature_space_shift_cadet.md
  39. 4 4
      docs/feature_swap_hands.md
  40. 10 10
      docs/feature_tap_dance.md
  41. 94 18
      docs/feature_unicode.md
  42. 138 36
      docs/feature_userspace.md
  43. 6 2
      docs/features.md
  44. 34 5
      docs/flashing.md
  45. 6 4
      docs/getting_started_build_tools.md
  46. 5 7
      docs/getting_started_github.md
  47. 4 0
      docs/getting_started_make_guide.md
  48. 21 23
      docs/hardware_avr.md
  49. 8 0
      docs/hardware_drivers.md
  50. 7 7
      docs/how_keyboards_work.md
  51. 82 0
      docs/i2c_driver.md
  52. 2 1
      docs/index.html
  53. 23 0
      docs/internals_gpio_control.md
  54. 50 29
      docs/isp_flashing_guide.md
  55. 2 0
      docs/keycode.txt
  56. 163 146
      docs/keycodes.md
  57. 163 138
      docs/keycodes_basic.md
  58. 32 26
      docs/keycodes_us_ansi_shifted.md
  59. 9 3
      docs/keymap.md
  60. 2 2
      docs/newbs.md
  61. 163 0
      docs/newbs_best_practices.md
  62. 15 1
      docs/newbs_building_firmware.md
  63. 38 40
      docs/newbs_getting_started.md
  64. 9 7
      docs/newbs_learn_more_resources.md
  65. 1 1
      docs/newbs_testing_debugging.md
  66. 13 12
      docs/quantum_keycodes.md
  67. 1 1
      docs/redirects.json
  68. 119 0
      docs/ref_functions.md
  69. 195 0
      docs/reference_configurator_support.md
  70. 2 2
      docs/reference_glossary.md
  71. 28 23
      docs/understanding_qmk.md
  72. 32 0
      docs/zh/README.md
  73. 99 0
      docs/zh/_sidebar.md
  74. 107 0
      drivers/arm/i2c_master.c
  75. 39 0
      drivers/arm/i2c_master.h
  76. 1 1
      drivers/arm/ws2812.c
  77. 1 1
      drivers/arm/ws2812.h
  78. 57 55
      drivers/avr/i2c_master.c
  79. 1 1
      drivers/avr/i2c_master.h
  80. 51 83
      drivers/avr/i2c_slave.c
  81. 7 3
      drivers/avr/i2c_slave.h
  82. 0 262
      drivers/avr/is31fl3731.c
  83. 0 214
      drivers/avr/is31fl3731.h
  84. 0 3
      drivers/avr/ws2812.h
  85. 102 0
      drivers/issi/is31fl3218.c
  86. 24 0
      drivers/issi/is31fl3218.h
  87. 270 0
      drivers/issi/is31fl3731.c
  88. 214 0
      drivers/issi/is31fl3731.h
  89. 252 0
      drivers/issi/is31fl3733.c
  90. 255 0
      drivers/issi/is31fl3733.h
  91. 306 0
      drivers/issi/is31fl3736.c
  92. 172 0
      drivers/issi/is31fl3736.h
  93. 0 58
      keyboards/1up60rgb/config.h
  94. 0 13
      keyboards/1up60rgb/readme.md
  95. 43 0
      keyboards/1upkeyboards/1up60hse/1up60hse.c
  96. 39 0
      keyboards/1upkeyboards/1up60hse/1up60hse.h
  97. 224 0
      keyboards/1upkeyboards/1up60hse/config.h
  98. 12 0
      keyboards/1upkeyboards/1up60hse/info.json
  99. 20 0
      keyboards/1upkeyboards/1up60hse/keymaps/default/config.h
  100. 0 0
      keyboards/1upkeyboards/1up60hse/keymaps/default/keymap.c

+ 3 - 3
CODE_OF_CONDUCT.md

@@ -1,10 +1,10 @@
 # Code Of Conduct
 
-QMK strives to be an inclusive and tolerant community. We welcome participation from anyone regardless of age, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, political belief, race, religion, or sexual identity and orientation. 
+QMK strives to be an inclusive, tolerant, and welcoming community. We encourage participation from anyone regardless of age, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, political belief, race, religion, or sexual identity and orientation.
 
-> “A gentle word turns away wrath, but a harsh word stirs up anger.
+> “A gentle word turns away wrath, but a harsh word stirs up anger."
 
-Our users, contributors, and collaborators are expected to treat each other with respect, to assume good intentions, and to gently correct, where possible, rather than react with escalation. Some examples of behavior we will not tolerate include, but is not limited to:
+Our users, contributors, and collaborators are expected to treat each other with kindness and respect, to assume good intentions, and to gently correct, where possible, rather than react with escalation. While our goal is to be as accurate as possible, kindness and understanding are more valuable than correctness. Some examples of behavior we will not tolerate include, but is not limited to:
 
 * The use of sexualized language or imagery
 * Unwelcome advances, sexual or otherwise

+ 13 - 18
Makefile

@@ -67,7 +67,7 @@ $(eval $(call NEXT_PATH_ELEMENT))
 # It's really a very simple if else chain, if you squint enough,
 # but the makefile syntax makes it very verbose.
 # If we are in a subfolder of keyboards
-# 
+#
 # *** No longer needed **
 #
 # ifeq ($(CURRENT_PATH_ELEMENT),keyboards)
@@ -307,11 +307,6 @@ define PARSE_KEYBOARD
     KEYBOARD_FOLDER_PATH_3 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_2)))
     KEYBOARD_FOLDER_PATH_4 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_3)))
     KEYBOARD_FOLDER_PATH_5 := $$(patsubst %/,%,$$(dir $$(KEYBOARD_FOLDER_PATH_4)))
-    KEYBOARD_FOLDER_1 := $$(notdir $$(KEYBOARD_FOLDER_PATH_1))
-    KEYBOARD_FOLDER_2 := $$(notdir $$(KEYBOARD_FOLDER_PATH_2))
-    KEYBOARD_FOLDER_3 := $$(notdir $$(KEYBOARD_FOLDER_PATH_3))
-    KEYBOARD_FOLDER_4 := $$(notdir $$(KEYBOARD_FOLDER_PATH_4))
-    KEYBOARD_FOLDER_5 := $$(notdir $$(KEYBOARD_FOLDER_PATH_5))
 
     KEYMAPS :=
     # get a list of all keymaps
@@ -325,35 +320,35 @@ define PARSE_KEYBOARD
         $$(KEYBOARD_FOLDER_3) $$(KEYBOARD_FOLDER_4) $$(KEYBOARD_FOLDER_5), $$(KEYMAPS)))
 
     KEYBOARD_LAYOUTS :=
-    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_5)/rules.mk)","")
+    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/rules.mk)","")
       LAYOUTS :=
-      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_5)/rules.mk)
+      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/rules.mk)
       KEYBOARD_LAYOUTS := $$(sort $$(LAYOUTS) $$(KEYBOARD_LAYOUTS))
     endif
-    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_4)/rules.mk)","")
+    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/rules.mk)","")
       LAYOUTS :=
-      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_4)/rules.mk)
+      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/rules.mk)
       KEYBOARD_LAYOUTS := $$(sort $$(LAYOUTS) $$(KEYBOARD_LAYOUTS))
     endif
-    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_3)/rules.mk)","")
+    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/rules.mk)","")
       LAYOUTS :=
-      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_3)/rules.mk)
+      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/rules.mk)
       KEYBOARD_LAYOUTS := $$(sort $$(LAYOUTS) $$(KEYBOARD_LAYOUTS))
     endif
-    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_2)/rules.mk)","")
+    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/rules.mk)","")
       LAYOUTS :=
-      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_2)/rules.mk)
+      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/rules.mk)
       KEYBOARD_LAYOUTS := $$(sort $$(LAYOUTS) $$(KEYBOARD_LAYOUTS))
     endif
-    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_1)/rules.mk)","")
+    ifneq ("$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/rules.mk)","")
       LAYOUTS :=
-      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_1)/rules.mk)
+      $$(eval include $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/rules.mk)
       KEYBOARD_LAYOUTS := $$(sort $$(LAYOUTS) $$(KEYBOARD_LAYOUTS))
     endif
 
     LAYOUT_KEYMAPS :=
     $$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.)))))
-    
+
     KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
 
     # if the rule after removing the start of it is empty (we haven't specified a kemap or target)
@@ -583,7 +578,7 @@ lib/%:
 
 git-submodule:
 	git submodule sync --recursive
-	git submodule update --init --recursive
+	git submodule update --init --recursive --progress
 
 ifdef SKIP_VERSION
 SKIP_GIT := yes

+ 1 - 1
Vagrantfile

@@ -59,7 +59,7 @@ Vagrant.configure(2) do |config|
   # add a # before ,args: and run 'vagrant up' to get a working
   # non-updated box and then attempt to troubleshoot or open a Github issue
 
-  config.vm.provision "shell", run: "always", path: "./util/install_dependencies.sh", args: "-update"
+  config.vm.provision "shell", run: "always", path: "./util/qmk_install.sh", args: "-update"
 
   config.vm.post_up_message = <<-EOT
 

+ 82 - 29
build_keyboard.mk

@@ -1,3 +1,9 @@
+# Determine what keyboard we are building and setup the build environment.
+#
+# We support folders up to 5 levels deep below `keyboards/`. This file is
+# responsible for determining which folder is being used and doing the
+# corresponding environment setup.
+
 ifndef VERBOSE
 .SILENT:
 endif
@@ -6,26 +12,15 @@ endif
 
 include common.mk
 
-# 5/4/3/2/1
-KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
-KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
-KEYBOARD_FOLDER_PATH_3 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_2)))
-KEYBOARD_FOLDER_PATH_4 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_3)))
-KEYBOARD_FOLDER_PATH_5 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_4)))
-KEYBOARD_FOLDER_1 := $(notdir $(KEYBOARD_FOLDER_PATH_1))
-KEYBOARD_FOLDER_2 := $(notdir $(KEYBOARD_FOLDER_PATH_2))
-KEYBOARD_FOLDER_3 := $(notdir $(KEYBOARD_FOLDER_PATH_3))
-KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
-KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
-
+# Set the filename for the final firmware binary
 KEYBOARD_FILESAFE := $(subst /,_,$(KEYBOARD))
-
 TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP)
 KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD_FILESAFE)
 
 # Force expansion
 TARGET := $(TARGET)
 
+# For split boards we need to set a master half.
 MASTER ?= left
 ifdef master
     MASTER = $(master)
@@ -39,35 +34,58 @@ $(error MASTER does not have a valid value(left/right))
     endif
 endif
 
+# Determine which subfolders exist.
+KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
+KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
+KEYBOARD_FOLDER_PATH_3 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_2)))
+KEYBOARD_FOLDER_PATH_4 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_3)))
+KEYBOARD_FOLDER_PATH_5 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_4)))
+KEYBOARD_FOLDER_1 := $(notdir $(KEYBOARD_FOLDER_PATH_1))
+KEYBOARD_FOLDER_2 := $(notdir $(KEYBOARD_FOLDER_PATH_2))
+KEYBOARD_FOLDER_3 := $(notdir $(KEYBOARD_FOLDER_PATH_3))
+KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
+KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
 KEYBOARD_PATHS :=
-
 KEYBOARD_PATH_1 := keyboards/$(KEYBOARD_FOLDER_PATH_1)
 KEYBOARD_PATH_2 := keyboards/$(KEYBOARD_FOLDER_PATH_2)
 KEYBOARD_PATH_3 := keyboards/$(KEYBOARD_FOLDER_PATH_3)
 KEYBOARD_PATH_4 := keyboards/$(KEYBOARD_FOLDER_PATH_4)
 KEYBOARD_PATH_5 := keyboards/$(KEYBOARD_FOLDER_PATH_5)
 
-ifneq ("$(wildcard $(KEYBOARD_PATH_5)/rules.mk)","")
+ifneq ("$(wildcard $(KEYBOARD_PATH_5)/)","")
     KEYBOARD_PATHS += $(KEYBOARD_PATH_5)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_4)/)","")
+    KEYBOARD_PATHS += $(KEYBOARD_PATH_4)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_3)/)","")
+    KEYBOARD_PATHS += $(KEYBOARD_PATH_3)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_2)/)","")
+    KEYBOARD_PATHS += $(KEYBOARD_PATH_2)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_1)/)","")
+    KEYBOARD_PATHS += $(KEYBOARD_PATH_1)
+endif
+
+# Pull in rules.mk files from all our subfolders
+ifneq ("$(wildcard $(KEYBOARD_PATH_5)/rules.mk)","")
     include $(KEYBOARD_PATH_5)/rules.mk
 endif
 ifneq ("$(wildcard $(KEYBOARD_PATH_4)/rules.mk)","")
-    KEYBOARD_PATHS += $(KEYBOARD_PATH_4)
     include $(KEYBOARD_PATH_4)/rules.mk
 endif
 ifneq ("$(wildcard $(KEYBOARD_PATH_3)/rules.mk)","")
-    KEYBOARD_PATHS += $(KEYBOARD_PATH_3)
     include $(KEYBOARD_PATH_3)/rules.mk
 endif
 ifneq ("$(wildcard $(KEYBOARD_PATH_2)/rules.mk)","")
-    KEYBOARD_PATHS += $(KEYBOARD_PATH_2)
     include $(KEYBOARD_PATH_2)/rules.mk
 endif
 ifneq ("$(wildcard $(KEYBOARD_PATH_1)/rules.mk)","")
-    KEYBOARD_PATHS += $(KEYBOARD_PATH_1)
     include $(KEYBOARD_PATH_1)/rules.mk
 endif
 
+# Find all the C source files to be compiled in subfolders.
 KEYBOARD_SRC :=
 
 KEYBOARD_C_1 := $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).c
@@ -92,9 +110,38 @@ ifneq ("$(wildcard $(KEYBOARD_C_1))","")
     KEYBOARD_SRC += $(KEYBOARD_C_1)
 endif
 
-OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE)
+# Generate KEYBOARD_name_subname for all levels of the keyboard folder
+KEYBOARD_FILESAFE_1 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_1)))
+KEYBOARD_FILESAFE_2 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_2)))
+KEYBOARD_FILESAFE_3 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_3)))
+KEYBOARD_FILESAFE_4 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_4)))
+KEYBOARD_FILESAFE_5 := $(subst .,,$(subst /,_,$(KEYBOARD_FOLDER_PATH_5)))
 
+ifneq ("$(wildcard $(KEYBOARD_PATH_5)/)","")
+    OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_5)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_4)/)","")
+    OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_4)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_3)/)","")
+    OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_3)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_2)/)","")
+    OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_2)
+endif
+ifneq ("$(wildcard $(KEYBOARD_PATH_1)/)","")
+    OPT_DEFS += -DKEYBOARD_$(KEYBOARD_FILESAFE_1)
+endif
 
+# Setup the define for QMK_KEYBOARD_H. This is used inside of keymaps so
+# that the same keymap may be used on multiple keyboards.
+#
+# We grab the most top-level include file that we can. That file should
+# use #ifdef statements to include all the neccesary subfolder includes,
+# as described here:
+#
+#    https://docs.qmk.fm/#/feature_layouts?id=tips-for-making-layouts-keyboard-agnostic
+#
 ifneq ("$(wildcard $(KEYBOARD_PATH_1)/$(KEYBOARD_FOLDER_1).h)","")
     QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_1).h
 endif
@@ -111,13 +158,18 @@ ifneq ("$(wildcard $(KEYBOARD_PATH_5)/$(KEYBOARD_FOLDER_5).h)","")
     QMK_KEYBOARD_H = $(KEYBOARD_FOLDER_5).h
 endif
 
-# We can assume a ChibiOS target When MCU_FAMILY is defined , since it's not used for LUFA
+# Determine and set parameters based on the keyboard's processor family.
+# We can assume a ChibiOS target When MCU_FAMILY is defined since it's
+# not used for LUFA
 ifdef MCU_FAMILY
-    FIRMWARE_FORMAT=bin
+    FIRMWARE_FORMAT?=bin
     PLATFORM=CHIBIOS
+else ifdef ARM_ATSAM
+    PLATFORM=ARM_ATSAM
+    FIRMWARE_FORMAT=bin
 else
     PLATFORM=AVR
-    FIRMWARE_FORMAT=hex
+    FIRMWARE_FORMAT?=hex
 endif
 
 ifeq ($(PLATFORM),CHIBIOS)
@@ -148,6 +200,7 @@ ifeq ($(PLATFORM),CHIBIOS)
     endif
 endif
 
+# Find all of the config.h files and add them to our CONFIG_H define.
 CONFIG_H :=
 ifneq ("$(wildcard $(KEYBOARD_PATH_5)/config.h)","")
     CONFIG_H += $(KEYBOARD_PATH_5)/config.h
@@ -203,7 +256,7 @@ else
     # this state should never be reached
 endif
 
-# User space stuff
+# Userspace setup and definitions
 ifeq ("$(USER_NAME)","")
     USER_NAME := $(KEYMAP)
 endif
@@ -256,6 +309,11 @@ endif
     include $(TMK_PATH)/avr.mk
 endif
 
+ifeq ($(PLATFORM),ARM_ATSAM)
+    include $(TMK_PATH)/arm_atsam.mk
+    include $(TMK_PATH)/protocol/arm_atsam.mk
+endif
+
 ifeq ($(PLATFORM),CHIBIOS)
     include $(TMK_PATH)/protocol/chibios.mk
 endif
@@ -283,11 +341,6 @@ $(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG)
 
 # Default target.
 all: build check-size
-
-# Change the build target to build a HEX file or a library.
 build: elf cpfirmware
-#build: elf hex eep lss sym
-#build: lib
-
 
 include $(TMK_PATH)/rules.mk

+ 1 - 0
common.mk

@@ -21,4 +21,5 @@ COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
 COMMON_VPATH += $(QUANTUM_PATH)/audio
 COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
 COMMON_VPATH += $(QUANTUM_PATH)/api
+COMMON_VPATH += $(QUANTUM_PATH)/split_common
 COMMON_VPATH += $(DRIVER_PATH)

+ 23 - 17
common_features.mk

@@ -114,26 +114,29 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
     endif
 endif
 
-ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
+RGB_MATRIX_ENABLE ?= no
+VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 WS2812 custom
+ifneq ($(strip $(RGB_MATRIX_ENABLE)), no)
+ifeq ($(filter $(RGB_MATRIX_ENABLE),$(VALID_MATRIX_TYPES)),)
+    $(error RGB_MATRIX_ENABLE="$(RGB_MATRIX_ENABLE)" is not a valid matrix type)
+endif
     OPT_DEFS += -DRGB_MATRIX_ENABLE
-    OPT_DEFS += -DIS31FL3731
-    COMMON_VPATH += $(DRIVER_PATH)/issi
-    SRC += is31fl3731.c
-    SRC += i2c_master.c
     SRC += $(QUANTUM_DIR)/color.c
     SRC += $(QUANTUM_DIR)/rgb_matrix.c
+    SRC += $(QUANTUM_DIR)/rgb_matrix_drivers.c
     CIE1931_CURVE = yes
 endif
 
+ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
+  RGB_MATRIX_ENABLE = IS31FL3731
+endif
+
 ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731)
     OPT_DEFS += -DRGB_MATRIX_ENABLE
     OPT_DEFS += -DIS31FL3731
     COMMON_VPATH += $(DRIVER_PATH)/issi
     SRC += is31fl3731.c
     SRC += i2c_master.c
-    SRC += $(QUANTUM_DIR)/color.c
-    SRC += $(QUANTUM_DIR)/rgb_matrix.c
-    CIE1931_CURVE = yes
 endif
 
 ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3733)
@@ -142,18 +145,12 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3733)
     COMMON_VPATH += $(DRIVER_PATH)/issi
     SRC += is31fl3733.c
     SRC += i2c_master.c
-    SRC += $(QUANTUM_DIR)/color.c
-    SRC += $(QUANTUM_DIR)/rgb_matrix.c
-    CIE1931_CURVE = yes
 endif
 
 ifeq ($(strip $(RGB_MATRIX_ENABLE)), WS2812)
     OPT_DEFS += -DRGB_MATRIX_ENABLE
     OPT_DEFS += -DWS2812
     SRC += ws2812.c
-    SRC += $(QUANTUM_DIR)/color.c
-    SRC += $(QUANTUM_DIR)/rgb_matrix.c
-    CIE1931_CURVE = yes
 endif
 
 ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
@@ -224,12 +221,17 @@ endif
 ifeq ($(strip $(TERMINAL_ENABLE)), yes)
     SRC += $(QUANTUM_DIR)/process_keycode/process_terminal.c
     OPT_DEFS += -DTERMINAL_ENABLE
+    OPT_DEFS += -DUSER_PRINT
 endif
 
 ifeq ($(strip $(USB_HID_ENABLE)), yes)
     include $(TMK_DIR)/protocol/usb_hid.mk
 endif
 
+ifeq ($(strip $(ENCODER_ENABLE)), yes)
+    SRC += $(QUANTUM_DIR)/encoder.c
+    OPT_DEFS += -DENCODER_ENABLE
+endif
 
 ifeq ($(strip $(HD44780_ENABLE)), yes)
     SRC += drivers/avr/hd44780.c
@@ -241,13 +243,17 @@ ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
     SRC += $(QUANTUM_DIR)/dynamic_keymap.c
 endif
 
+ifeq ($(strip $(LEADER_ENABLE)), yes)
+  SRC += $(QUANTUM_DIR)/process_keycode/process_leader.c
+  OPT_DEFS += -DLEADER_ENABLE
+endif
+
 QUANTUM_SRC:= \
     $(QUANTUM_DIR)/quantum.c \
     $(QUANTUM_DIR)/keymap_common.c \
-    $(QUANTUM_DIR)/keycode_config.c \
-    $(QUANTUM_DIR)/process_keycode/process_leader.c
+    $(QUANTUM_DIR)/keycode_config.c
 
-ifndef CUSTOM_MATRIX
+ifneq ($(strip $(CUSTOM_MATRIX)), yes)
     ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
         QUANTUM_SRC += $(QUANTUM_DIR)/split_common/matrix.c
     else

+ 4 - 0
docs/LANGS.md

@@ -0,0 +1,4 @@
+# Languages
+
+* [English](/)
+* [Chinese](zh/)

+ 37 - 38
docs/_sidebar.md

@@ -1,18 +1,16 @@
-* [Getting Started](README.md)
-  * [QMK Introduction](getting_started_introduction.md)
-  * [Install Build Tools](getting_started_build_tools.md)
-    * Alternative: [Vagrant Guide](getting_started_vagrant.md)
-  * [Build/Compile Instructions](getting_started_make_guide.md)
-  * [Flashing Firmware](flashing.md)
-  * [Contributing to QMK](contributing.md)
-  * [How to Use Github](getting_started_github.md)
-  * [Getting Help](getting_started_getting_help.md)
-
 * [Complete Newbs Guide](newbs.md)
   * [Getting Started](newbs_getting_started.md)
   * [Building Your First Firmware](newbs_building_firmware.md)
   * [Flashing Firmware](newbs_flashing.md)
   * [Testing and Debugging](newbs_testing_debugging.md)
+  * [Best Practices](newbs_best_practices.md)
+  * [Learning Resources](newbs_learn_more_resources.md)
+
+* [QMK Basics](README.md)
+  * [QMK Introduction](getting_started_introduction.md)
+  * [Contributing to QMK](contributing.md)
+  * [How to Use Github](getting_started_github.md)
+  * [Getting Help](getting_started_getting_help.md)
 
 * [FAQ](faq.md)
   * [General FAQ](faq_general.md)
@@ -20,32 +18,55 @@
   * [Debugging/Troubleshooting QMK](faq_debug.md)
   * [Keymap](faq_keymap.md)
 
+* Detailed Guides
+  * [Install Build Tools](getting_started_build_tools.md)
+  * [Vagrant Guide](getting_started_vagrant.md)
+  * [Build/Compile Instructions](getting_started_make_guide.md)
+  * [Flashing Firmware](flashing.md)
+  * [Customizing Functionality](custom_quantum_functions.md)
+  * [Keymap Overview](keymap.md)
+
 * [Hardware](hardware.md)
-  * [Keyboard Guidelines](hardware_keyboard_guidelines.md)
   * [AVR Processors](hardware_avr.md)
-  * ARM Processors (TBD)
   * [Drivers](hardware_drivers.md)
 
+* Reference
+  * [Keyboard Guidelines](hardware_keyboard_guidelines.md)
+  * [Config Options](config_options.md)
+  * [Keycodes](keycodes.md)
+  * [Documentation Best Practices](documentation_best_practices.md)
+  * [Documentation Templates](documentation_templates.md)
+  * [Glossary](reference_glossary.md)
+  * [Unit Testing](unit_testing.md)
+  * [Useful Functions](ref_functions.md)
+  * [Configurator Support](reference_configurator_support.md)
+
 * [Features](features.md)
+  * [Basic Keycodes](keycodes_basic.md)
+  * [Quantum Keycodes](quantum_keycodes.md)
   * [Advanced Keycodes](feature_advanced_keycodes.md)
   * [Audio](feature_audio.md)
   * [Auto Shift](feature_auto_shift.md)
   * [Backlight](feature_backlight.md)
+  * [Bluetooth](feature_bluetooth.md)
   * [Bootmagic](feature_bootmagic.md)
+  * [Combos](feature_combo)
   * [Command](feature_command.md)
   * [Dynamic Macros](feature_dynamic_macros.md)
+  * [Encoders](feature_encoders.md)
   * [Grave Escape](feature_grave_esc.md)
   * [Key Lock](feature_key_lock.md)
   * [Layouts](feature_layouts.md)
   * [Leader Key](feature_leader_key.md)
   * [Macros](feature_macros.md)
   * [Mouse Keys](feature_mouse_keys.md)
+  * [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
   * [Pointing Device](feature_pointing_device.md)
   * [PS/2 Mouse](feature_ps2_mouse.md)
   * [RGB Lighting](feature_rgblight.md)
   * [RGB Matrix](feature_rgb_matrix.md)
-  * [Space Cadet Shift](feature_space_cadet.md)
-  * [Space Cadet Shift Enter](feature_space_shift_cadet.md)
+  * [Space Cadet Shift](feature_space_cadet_shift.md)
+  * [Space Cadet Shift Enter](feature_space_cadet_shift_enter.md)
   * [Stenography](feature_stenography.md)
   * [Swap Hands](feature_swap_hands.md)
   * [Tap Dance](feature_tap_dance.md)
@@ -53,35 +74,13 @@
   * [Thermal Printer](feature_thermal_printer.md)
   * [Unicode](feature_unicode.md)
   * [Userspace](feature_userspace.md)
-
-* [Keycodes](keycodes.md)
-  * [Backlight](feature_backlight.md#backlight-keycodes)
-  * [Basic](keycodes_basic.md)
-  * [Bluetooth](feature_bluetooth.md#bluetooth-keycodes)
-  * [Bootmagic](feature_bootmagic.md#bootmagic-keycodes)
-  * [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers)
-  * [Mod+Key](feature_advanced_keycodes.md#modifier-keys)
-  * [Mod Tap](feature_advanced_keycodes.md#mod-tap)
-  * [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
-  * [Quantum](quantum_keycodes.md)
-  * [RGB Light](feature_rgblight.md#rgblight-keycodes)
-  * [Shifted Keys](feature_advanced_keycodes.md#shifted-keycodes)
-  * [Stenography](feature_stenography.md#keycode-reference)
-  * [Thermal Printer](feature_thermal_printer.md#thermal-printer-keycodes)
   * [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
 
-* Reference
-  * [Config Options](config_options.md)
-  * [Customizing Functionality](custom_quantum_functions.md)
-  * [Documentation Best Practices](documentation_best_practices.md)
-  * [Documentation Templates](documentation_templates.md)
-  * [Glossary](reference_glossary.md)
-  * [Keymap Overview](keymap.md)
-  * [Unit Testing](unit_testing.md)
-
 * For Makers and Modders
   * [Hand Wiring Guide](hand_wire.md)
   * [ISP Flashing Guide](isp_flashing_guide.md)
+  * [ARM Debugging Guide](arm_debugging.md)
+  * [I2C Driver](i2c_driver.md)
 
 * For a Deeper Understanding
   * [How Keyboards Work](how_keyboards_work.md)

+ 38 - 41
docs/_summary.md

@@ -1,18 +1,16 @@
-* [Getting Started](README.md)
-  * [QMK Introduction](getting_started_introduction.md)
-  * [Install Build Tools](getting_started_build_tools.md)
-    * Alternative: [Vagrant Guide](getting_started_vagrant.md)
-  * [Build/Compile Instructions](getting_started_make_guide.md)
-  * [Flashing Firmware](flashing.md)
-  * [Contributing to QMK](contributing.md)
-  * [How to Use Github](getting_started_github.md)
-  * [Getting Help](getting_started_getting_help.md)
-
 * [Complete Newbs Guide](newbs.md)
   * [Getting Started](newbs_getting_started.md)
   * [Building Your First Firmware](newbs_building_firmware.md)
   * [Flashing Firmware](newbs_flashing.md)
   * [Testing and Debugging](newbs_testing_debugging.md)
+  * [Best Practices](newbs_best_practices.md)
+  * [Learning Resources](newbs_learn_more_resources.md)
+
+* [QMK Basics](README.md)
+  * [QMK Introduction](getting_started_introduction.md)
+  * [Contributing to QMK](contributing.md)
+  * [How to Use Github](getting_started_github.md)
+  * [Getting Help](getting_started_getting_help.md)
 
 * [FAQ](faq.md)
   * [General FAQ](faq_general.md)
@@ -20,30 +18,55 @@
   * [Debugging/Troubleshooting QMK](faq_debug.md)
   * [Keymap](faq_keymap.md)
 
+* Detailed Guides
+  * [Install Build Tools](getting_started_build_tools.md)
+  * [Vagrant Guide](getting_started_vagrant.md)
+  * [Build/Compile Instructions](getting_started_make_guide.md)
+  * [Flashing Firmware](flashing.md)
+  * [Customizing Functionality](custom_quantum_functions.md)
+  * [Keymap Overview](keymap.md)
+
 * [Hardware](hardware.md)
-  * [Keyboard Guidelines](hardware_keyboard_guidelines.md)
   * [AVR Processors](hardware_avr.md)
-  * ARM Processors (TBD)
   * [Drivers](hardware_drivers.md)
 
+* Reference
+  * [Keyboard Guidelines](hardware_keyboard_guidelines.md)
+  * [Config Options](config_options.md)
+  * [Keycodes](keycodes.md)
+  * [Documentation Best Practices](documentation_best_practices.md)
+  * [Documentation Templates](documentation_templates.md)
+  * [Glossary](reference_glossary.md)
+  * [Unit Testing](unit_testing.md)
+  * [Useful Functions](ref_functions.md)
+  * [Configurator Support](reference_configurator_support.md)
+
 * [Features](features.md)
+  * [Basic Keycodes](keycodes_basic.md)
+  * [Quantum Keycodes](quantum_keycodes.md)
   * [Advanced Keycodes](feature_advanced_keycodes.md)
   * [Audio](feature_audio.md)
   * [Auto Shift](feature_auto_shift.md)
   * [Backlight](feature_backlight.md)
+  * [Bluetooth](feature_bluetooth.md)
   * [Bootmagic](feature_bootmagic.md)
+  * [Combos](feature_combo)
   * [Command](feature_command.md)
   * [Dynamic Macros](feature_dynamic_macros.md)
+  * [Encoders](feature_encoders.md)
   * [Grave Escape](feature_grave_esc.md)
   * [Key Lock](feature_key_lock.md)
   * [Layouts](feature_layouts.md)
   * [Leader Key](feature_leader_key.md)
   * [Macros](feature_macros.md)
   * [Mouse Keys](feature_mouse_keys.md)
+  * [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
   * [Pointing Device](feature_pointing_device.md)
   * [PS/2 Mouse](feature_ps2_mouse.md)
   * [RGB Lighting](feature_rgblight.md)
-  * [Space Cadet](feature_space_cadet.md)
+  * [RGB Matrix](feature_rgb_matrix.md)
+  * [Space Cadet Shift](feature_space_cadet_shift.md)
+  * [Space Cadet Shift Enter](feature_space_cadet_shift_enter.md)
   * [Stenography](feature_stenography.md)
   * [Swap Hands](feature_swap_hands.md)
   * [Tap Dance](feature_tap_dance.md)
@@ -51,39 +74,13 @@
   * [Thermal Printer](feature_thermal_printer.md)
   * [Unicode](feature_unicode.md)
   * [Userspace](feature_userspace.md)
-
-* [Keycodes](keycodes.md)
-  * [Basic](keycodes_basic.md)
-  * [Quantum](quantum_keycodes.md)
-  * [Audio](feature_audio.md#audio-keycodes)
-  * [Backlight](feature_backlight.md#backlight-keycodes)
-  * [Bootmagic](feature_bootmagic.md#bootmagic-keycodes)
-  * [Bluetooth](feature_bluetooth.md#bluetooth-keycodes)
-  * [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers)
-  * [Mod+Key](feature_advanced_keycodes.md#modifier-keys)
-  * [Mod Tap](feature_advanced_keycodes.md#mod-tap)
-  * [Mouse Keys](feature_mouse_keys.md#mapping-mouse-actions-to-keyboard-keys)
-  * [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
-  * [RGB Light](feature_rgblight.md#rgblight-keycodes)
-  * [RGB Matrix](feature_rgb_matrix.md#keycodes)
-  * [Shifted Keys](feature_advanced_keycodes.md#shifted-keycodes)
-  * [Stenography](feature_stenography.md#keycode-reference)
-  * [Swap Hands](feature_swap_hands.md#swap-keycodes)
-  * [Thermal Printer](feature_thermal_printer.md#thermal-printer-keycodes)
   * [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
 
-* Reference
-  * [Config Options](config_options.md)
-  * [Customizing Functionality](custom_quantum_functions.md)
-  * [Documentation Best Practices](documentation_best_practices.md)
-  * [Documentation Templates](documentation_templates.md)
-  * [Glossary](reference_glossary.md)
-  * [Keymap Overview](keymap.md)
-  * [Unit Testing](unit_testing.md)
-
 * For Makers and Modders
   * [Hand Wiring Guide](hand_wire.md)
   * [ISP Flashing Guide](isp_flashing_guide.md)
+  * [ARM Debugging Guide](arm_debugging.md)
+  * [I2C Driver](i2c_driver.md)
 
 * For a Deeper Understanding
   * [How Keyboards Work](how_keyboards_work.md)

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 87 - 0
docs/arm_debugging.md


+ 6 - 4
docs/becoming_a_qmk_collaborator.md

@@ -1,7 +1,9 @@
-A QMK collaborator is a keyboard maker/designer that is interested in helping QMK grow and fully support their keyboard(s), and encouraging their users/customers to submit features, ideas, and keymaps. We're always looking to add more keyboards and collaborators, but we ask that they fulfill these requirements:
+# Becoming a QMK Collaborator
 
-* **Have a PCB available for sale** - unfortunately there's just too much variation and complications with handwired keyboards.
-* **Maintain the your keyboard's directory** - this may just require an initial setup to get your keyboard working, but it could also include accommodating changes made to QMK's core.
-* **Approve and merge your keyboard's keymap pull requests** - we like to encourage users to contribute their keymaps for others to see and work from when creating their own.
+A QMK collaborator is a keyboard maker or designer that is interested in helping QMK grow and fully support their keyboard(s), and encouraging their users and customers to submit features, ideas, and keymaps. We're always looking to add more keyboards and collaborators, but we ask that they fulfill these requirements:
+
+* **Have a PCB available for sale.** Unfortunately there's just too much variation and complications with handwired keyboards.
+* **Maintain your keyboard in QMK.** This may just require an initial setup to get your keyboard working, but it could also include accommodating changes made to QMK's core that might break or render any custom code redundant.
+* **Approve and merge keymap pull requests for your keyboard.** We like to encourage users to contribute their keymaps for others to see and work from when creating their own.
 
 If you feel you meet these requirements, shoot us an email at hello@qmk.fm with an introduction and some links to your keyboard!

+ 65 - 7
docs/config_options.md

@@ -91,6 +91,8 @@ This is a C header file that is one of the first things included, and will persi
   * key combination that allows the use of magic commands (useful for debugging)
 * `#define USB_MAX_POWER_CONSUMPTION`
   * sets the maximum power (in mA) over USB for the device (default: 500)
+* `#define SCL_CLOCK 100000L`
+  * sets the SCL_CLOCK speed for split keyboards. The default is `100000L` but some boards can be set to `400000L`.
 
 ## Features That Can Be Disabled
 
@@ -117,8 +119,8 @@ If you define these options you will enable the associated feature, which may in
 
 * `#define FORCE_NKRO`
   * NKRO by default requires to be turned on, this forces it on during keyboard startup regardless of EEPROM setting. NKRO can still be turned off but will be turned on again if the keyboard reboots.
-* `#define PREVENT_STUCK_MODIFIERS`
-  * stores the layer a key press came from so the same layer is used when the key is released, regardless of which layers are enabled
+* `#define STRICT_LAYER_RELEASE`
+  * force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases)
 
 ## Behaviors That Can Be Configured
 
@@ -130,14 +132,15 @@ If you define these options you will enable the associated feature, which may in
 * `#define TAPPING_TOGGLE 2`
   * how many taps before triggering the toggle
 * `#define PERMISSIVE_HOLD`
-  * makes tap and hold keys work better for fast typers who don't want tapping term set above 500
+  * makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM`
   * See [Permissive Hold](feature_advanced_keycodes.md#permissive-hold) for details
 * `#define IGNORE_MOD_TAP_INTERRUPT`
-  * makes it possible to do rolling combos (zx) with keys that convert to other keys on hold
-  * See [Mod tap interrupt](feature_advanced_keycodes.md#mod-tap-interrupt) for details
+  * makes it possible to do rolling combos (zx) with keys that convert to other keys on hold, by enforcing the `TAPPING_TERM` for both keys.
+  * See [Mod tap interrupt](feature_advanced_keycodes.md#ignore-mod-tap-interrupt) for details
 * `#define TAPPING_FORCE_HOLD`
   * makes it possible to use a dual role key as modifier shortly after having been tapped
-  * See [Hold after tap](feature_advanced_keycodes.md#hold-after-tap)
+  * See [Hold after tap](feature_advanced_keycodes.md#tapping-force-hold)
+  * Breaks any Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
 * `#define LEADER_TIMEOUT 300`
   * how long before the leader key times out
 * `#define ONESHOT_TIMEOUT 300`
@@ -153,6 +156,10 @@ If you define these options you will enable the associated feature, which may in
     going to produce the 500 keystrokes a second needed to actually get more than a
     few ms of delay from this. But if you're doing chording on something with 3-4ms
     scan times? You probably want this.
+* `#define COMBO_COUNT 2`
+  * Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature.
+* `#define COMBO_TERM 200`
+  * how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined.
 
 ## RGB Light Configuration
 
@@ -179,6 +186,16 @@ If you define these options you will enable the associated feature, which may in
 * `#define MOUSEKEY_MAX_SPEED 7`
 * `#define MOUSEKEY_WHEEL_DELAY 0`
 
+## Split Keyboard Options
+
+Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk
+
+* `#define SPLIT_HAND_PIN B7`
+  * For using high/low pin to determine handedness, low = right hand, high = left hand. Replace 'B7' with the pin you are using. This is optional and you can still use the EEHANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses.
+  
+* `#define USE_I2C`
+  * For using I2C instead of Serial (defaults to serial)
+
 # The `rules.mk` File
 
 This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features.
@@ -187,6 +204,8 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
 
 * `DEFAULT_FOLDER`
   * Used to specify a default folder when a keyboard has more than one sub-folder.
+* `FIRMWARE_FORMAT`
+  * Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building.
 * `SRC`
   * Used to add files to the compilation/linking list.
 * `LAYOUTS`
@@ -220,6 +239,8 @@ Use these to enable or disable building certain features. The more you have enab
   * Console for debug(+400)
 * `COMMAND_ENABLE`
   * Commands for debug and configuration
+* `COMBO_ENABLE`
+  * Key combo feature
 * `NKRO_ENABLE`
   * USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
 * `AUDIO_ENABLE`
@@ -231,4 +252,41 @@ Use these to enable or disable building certain features. The more you have enab
 * `UNICODE_ENABLE`
   * Unicode
 * `BLUETOOTH_ENABLE`
-  * Enable Bluetooth with the Adafruit EZ-Key HID
+  * Legacy option to Enable Bluetooth with the Adafruit EZ-Key HID. See BLUETOOTH
+* `BLUETOOTH`
+  * Current options are AdafruitEzKey, AdafruitBLE, RN42
+* `SPLIT_KEYBOARD`
+  * Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
+* `WAIT_FOR_USB`
+  * Forces the keyboard to wait for a USB connection to be established before it starts up
+* `NO_USB_STARTUP_CHECK`
+  * Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
+
+## USB Endpoint Limitations
+
+In order to provide services over USB, QMK has to use USB endpoints.
+These are a finite resource: each microcontroller has only a certain number.
+This limits what features can be enabled together.
+If the available endpoints are exceeded, a build error is thrown.
+
+The following features can require separate endpoints:
+
+* `MOUSEKEY_ENABLE`
+* `EXTRAKEY_ENABLE`
+* `CONSOLE_ENABLE`
+* `NKRO_ENABLE`
+* `MIDI_ENABLE`
+* `RAW_ENABLE`
+* `VIRTSER_ENABLE`
+
+In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint.
+By default, `MOUSEKEY`, `EXTRAKEY`, and `NKRO` are combined into a single endpoint.
+
+The base keyboard functionality can also be combined into the endpoint,
+by setting `KEYBOARD_SHARED_EP = yes`.
+This frees up one more endpoint,
+but it can prevent the keyboard working in some BIOSes,
+as they do not implement Boot Keyboard protocol switching.
+
+Combining the mouse also breaks Boot Mouse compatibility.
+The mouse can be uncombined by setting `MOUSE_SHARED_EP = no` if this functionality is required.

+ 22 - 2
docs/contributing.md

@@ -57,19 +57,39 @@ Never made an open source contribution before? Wondering how contributions work
 Most of our style is pretty easy to pick up on, but right now it's not entirely consistent. You should match the style of the code surrounding your change, but if that code is inconsistent or unclear use the following guidelines:
 
 * We indent using two spaces (soft tabs)
-* We use One True Brace Style
+* We use a modified One True Brace Style
   * Opening Brace: At the end of the same line as the statement that opens the block
   * Closing Brace: Lined up with the first character of the statement that opens the block
   * Else If: Place the closing brace at the beginning of the line and the next opening brace at the end of the same line.
   * Optional Braces: Always include optional braces.
     * Good: if (condition) { return false; }
     * Bad: if (condition) return false;
-* We use C style comments: `/* */`
+* We encourage use of C style comments: `/* */`
   * Think of them as a story describing the feature
   * Use them liberally to explain why particular decisions were made.
   * Do not write obvious comments
   * If you not sure if a comment is obvious, go ahead and include it.
 * In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns.
+* We use `#pragma once` at the start of header files rather than old-style include guards (`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`)
+
+Here is an example for easy reference:
+
+```c
+/* Enums for foo */
+enum foo_state {
+  FOO_BAR,
+  FOO_BAZ,
+};
+
+/* Returns a value */
+int foo(void) {
+  if (some_condition) {
+    return FOO_BAR;
+  } else {
+    return -1;
+  }
+}
+```
 
 # General Guidelines
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 161 - 21
docs/custom_quantum_functions.md


+ 1 - 1
docs/documentation_templates.md

@@ -36,7 +36,7 @@ Make example for this keyboard (after setting up your build environment):
 
     make planck/rev4:default
 
-See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
 ```
 
 There needs to be two spaces at the end of the `Keyboard Maintainer` and `Hardware Supported` lines for it to render correctly with Markdown.

+ 12 - 2
docs/faq_build.md

@@ -17,7 +17,7 @@ or just:
 
 Note that running `make` with `sudo` is generally *not* a good idea, and you should use one of the former methods, if possible.
 
-## Linux `udev` Rules
+### Linux `udev` Rules
 On Linux, you'll need proper privileges to access the MCU. You can either use
 `sudo` when flashing firmware, or place these files in `/etc/udev/rules.d/`.
 
@@ -37,6 +37,14 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2ff0", MODE:="066
 SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666"
 ```
 
+## Unknown Device for DFU Bootloader
+
+If you're using Windows to flash your keyboard, and you are running into issues, check the Device Manager.  If you see an "Unknown Device" when the keyboard is in "bootloader mode", then you may have a driver issue. 
+
+Re-running the installation script for MSYS2 may help (eg run `./util/qmk_install.sh` from MSYS2/WSL) or reinstalling the QMK Toolbox may fix the issue. 
+
+If that doesn't work, then you may need to grab the [Zadig Utility](https://zadig.akeo.ie/). Download this, find the device in question, and select the `WinUS(libusb-1.0)` option, and hit "Reinstall driver". Once you've done that, try flashing your board, again. 
+
 ## WINAVR is Obsolete
 It is no longer recommended and may cause some problem.
 See [TMK Issue #99](https://github.com/tmk/tmk_keyboard/issues/99).
@@ -97,10 +105,12 @@ The solution is to remove and reinstall all affected modules.
 ```
 brew rm avr-gcc
 brew rm dfu-programmer
+brew rm dfu-util
 brew rm gcc-arm-none-eabi
 brew rm avrdude
 brew install avr-gcc
 brew install dfu-programmer
+brew install dfu-util
 brew install gcc-arm-none-eabi
 brew install avrdude
 ```
@@ -116,5 +126,5 @@ For now, you need to rollback avr-gcc to 7 in brew.
 ```
 brew uninstall --force avr-gcc
 brew install avr-gcc@7
-brew link avr-gcc@7
+brew link --force avr-gcc@7
 ```

+ 11 - 29
docs/faq_keymap.md

@@ -11,8 +11,8 @@ Keycodes are actually defined in [common/keycode.h](https://github.com/qmk/qmk_f
 
 There are 3 standard keyboard layouts in use around the world- ANSI, ISO, and JIS. North America primarily uses ANSI, Europe and Africa primarily use ISO, and Japan uses JIS. Regions not mentioned typically use either ANSI or ISO. The keycodes corresponding to these layouts are shown here:
 
-<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/9ce023dc6caadc0cf11c88c782350a8c -->
-![Keyboard Layout Image](https://i.imgur.com/45m4mRf.png)
+<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/bf431647d1001cff5eff20ae55621e9a -->
+![Keyboard Layout Image](https://i.imgur.com/5wsh5wM.png)
 
 ## Some Of My Keys Are Swapped Or Not Working
 
@@ -34,12 +34,11 @@ See [issue #168](https://github.com/tmk/tmk_keyboard/issues/168) and
 * http://en.wikipedia.org/wiki/Magic_SysRq_key
 * http://en.wikipedia.org/wiki/System_request
 
-## Power Key Doesn't Work
-Use `KC_PWR` instead of `KC_POWER` or vice versa.
-* `KC_PWR` works with Windows and Linux, not with OSX.
-* `KC_POWER` works with OSX and Linux, not with Windows.
+## Power Keys Aren't Working
 
-More info: http://geekhack.org/index.php?topic=14290.msg1327264#msg1327264
+Somewhat confusingly, there are two "Power" keycodes in QMK: `KC_POWER` in the Keyboard/Keypad HID usage page, and `KC_SYSTEM_POWER` (or `KC_PWR`) in the Consumer page.
+
+The former is only recognized on macOS, while the latter, `KC_SLEP` and `KC_WAKE` are supported by all three major operating systems, so it is recommended to use those instead. Under Windows, these keys take effect immediately, however on macOS they must be held down until a dialog appears.
 
 ## One Shot Modifier
 Solves my personal 'the' problem. I often got 'the' or 'THe' wrongly instead of 'The'.  One Shot Shift mitigates this for me.
@@ -87,14 +86,14 @@ On **Xorg** you can use `compose` key, instead.
 And see this for **Unicode** input.
 * http://en.wikipedia.org/wiki/Unicode_input
 
+## `Fn` Key on macOS
 
-## Apple/Mac Keyboard `Fn`
-Not supported.
+Unlike most Fn keys, the one on Apple keyboards actually has its own keycode... sort of. It takes the place of the sixth keycode in a basic 6KRO HID report -- so an Apple keyboard is in fact only 5KRO.
 
-Apple/Mac keyboard sends keycode for Fn unlike most of other keyboards.
-I think you can send Apple Fn key using Apple venter specific Page 0xff01 and usage 0x0003. But you have to change HID Report Descriptor for this, of course.
+It is technically possible to get QMK to send this key. However, doing so requires modification of the report format to add the state of the Fn key.
+Even worse, it is not recognized unless the keyboard's VID and PID match that of a real Apple keyboard. The legal issues that official QMK support for this feature may create mean it is unlikely to happen.
 
-https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/AppleHIDUsageTables.h
+See [this issue](https://github.com/qmk/qmk_firmware/issues/2179) for detailed information.
 
 
 ## Media Control Keys in Mac OSX
@@ -212,20 +211,3 @@ here real_mods lost state for 'physical left shift'.
 
 weak_mods is ORed with real_mods when keyboard report is sent.
 https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57
-
-## Timer Functionality
-
-It's possible to start timers and read values for time-specific events - here's an example:
-
-```c
-static uint16_t key_timer;
-key_timer = timer_read();
-
-if (timer_elapsed(key_timer) < 100) {
-  // do something if less than 100ms have passed
-} else {
-  // do something if 100ms or more have passed
-}
-```
-
-It's best to declare the `static uint16_t key_timer;` at the top of the file, outside of any code blocks you're using it in.

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 143 - 106
docs/feature_advanced_keycodes.md


+ 8 - 8
docs/feature_audio.md

@@ -119,22 +119,22 @@ You can completely disable Music Mode as well. This is useful, if you're pressed
 
     #define NO_MUSIC_MODE
 
-## Faux Click
+## Audio Click
 
 This adds a click sound each time you hit a button, to simulate click sounds from the keyboard. And the sounds are slightly different for each keypress, so it doesn't sound like a single long note, if you type rapidly. 
 
 * `CK_TOGG` - Toggles the status (will play sound if enabled)
-* `CK_RST` - Resets the frequency to the default state 
-* `CK_UP` - Increases the frequency of the clicks
-* `CK_DOWN` - Decreases the frequency of the clicks
+* `CK_ON` - Turns on Audio Click (plays sound)
+* `CK_OFF` - Turns off Audio Click (doesn't play sound)
+* `CK_RST` - Resets the frequency to the default state (plays sound at default frequency)
+* `CK_UP` - Increases the frequency of the clicks (plays sound at new frequency)
+* `CK_DOWN` - Decreases the frequency of the clicks (plays sound at new frequency)
+
 
 The feature is disabled by default, to save space.  To enable it, add this to your `config.h`:
 
     #define AUDIO_CLICKY
 
-Additionally, even when enabled, the feature is not enabled by default, so you would need to turn it on first.  And since we don't use EEPROM to store the setting (yet), you can default this to on by adding this to your `config.h`:
-
-    #define AUDIO_CLICKY_ON
 
 You can configure the default, min and max frequencies, the stepping and built in randomness by defining these values: 
 
@@ -144,7 +144,7 @@ You can configure the default, min and max frequencies, the stepping and built i
 | `AUDIO_CLICKY_FREQ_MIN` | 65.0f | Sets the lowest frequency (under 60f are a bit buggy). |
 | `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | Sets the the highest frequency. Too high may result in coworkers attacking you. |
 | `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f| Sets the stepping of UP/DOWN key codes. |
-| `AUDIO_CLICKY_FREQ_RANDOMNESS`     |  0.05f |  Sets a factor of randomness for the clicks, Setting this to `0f` will make each click identical. | 
+| `AUDIO_CLICKY_FREQ_RANDOMNESS`     |  0.05f |  Sets a factor of randomness for the clicks, Setting this to `0f` will make each click identical, and `1.0f` will make this sound much like the 90's computer screen scrolling/typing effect. | 
 
 
 

+ 55 - 19
docs/feature_backlight.md

@@ -1,10 +1,20 @@
 # Backlighting
 
-<!-- FIXME: Describe how backlighting works in QMK -->
+Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming.
 
-## Backlight Keycodes
+The MCU can only supply so much current to its GPIO pins. Instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs.
 
-These keycodes control the backlight. Most keyboards use this for single color in-switch lighting.
+## Usage
+
+Most keyboards have backlighting enabled by default if they support it, but if it is not working for you, check that your `rules.mk` includes the following:
+
+```make
+BACKLIGHT_ENABLE = yes
+```
+
+You should then be able to use the keycodes below to change the backlight level.
+
+## Keycodes
 
 |Key      |Description                               |
 |---------|------------------------------------------|
@@ -16,24 +26,50 @@ These keycodes control the backlight. Most keyboards use this for single color i
 |`BL_DEC` |Decrease the backlight level              |
 |`BL_BRTG`|Toggle backlight breathing                |
 
-Note that for backlight breathing, you need to have `#define BACKLIGHT_BREATHING` in your config.h.
+## Caveats
+
+This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously use multiple different coloured LEDs on a keyboard.
+
+Hardware PWM is only supported on certain pins of the MCU, so if the backlighting is not connected to one of them, a software implementation will be used, and backlight breathing will not be available. Currently the supported pins are `B5`, `B6`, `B7`, and `C6`.
+
+## Configuration
+
+To change the behaviour of the backlighting, `#define` these in your `config.h`:
+
+|Define               |Default      |Description                                                                                                  |
+|---------------------|-------------|-------------------------------------------------------------------------------------------------------------|
+|`BACKLIGHT_PIN`      |`B7`         |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this|
+|`BACKLIGHT_LEVELS`   |`3`          |The number of brightness levels (maximum 15 excluding off)                                                   |
+|`BACKLIGHT_BREATHING`|*Not defined*|Enable backlight breathing, if hardware PWM is used                                                          |
+|`BREATHING_PERIOD`   |`6`          |The length of one backlight "breath" in seconds                                                              |
+
+## Hardware PWM Implementation
+
+When using the supported pins for backlighting, QMK will use a hardware timer configured to output a PWM signal. This timer will count up to `ICRx` (by default `0xFFFF`) before resetting to 0.
+The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the backlight pin will go low, and is pulled high again when the counter resets.
+In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on.
 
-## Configuration Options in `config.h`
+The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second.
+In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM.
 
-* `BACKLIGHT_PIN B7` defines the pin that controlls the LEDs. Unless you design your own keyboard, you don't need to set this.
-* `BACKLIGHT_LEVELS 3` defines the number of brightness levels (maximum 15 excluding off).
-* `BACKLIGHT_BREATHING` if defined, enables backlight breathing. Note that this is only available if `BACKLIGHT_PIN` is B5, B6 or B7.
-* `BREATHING_PERIOD 6` defines the length of one backlight "breath" in seconds.
+## Backlight Functions
 
-## Notes on Implementation
+|Function  |Description                                                |
+|----------|-----------------------------------------------------------|
+|`backlight_toggle()`    |Turn the backlight on or off                 |
+|`backlight_enable()`    |Turn the backlight on                        |
+|`backlight_disable()`   |Turn the backlight off                       |
+|`backlight_step()`      |Cycle through backlight levels               |
+|`backlight_increase()`  |Increase the backlight level                 |
+|`backlight_decrease()`  |Decrease the backlight level                 |
+|`backlight_level(x)`    |Sets the backlight level to specified level  |
+|`get_backlight_level()` |Return the current backlight level           |
+|`is_backlight_enabled()`|Return whether the backlight is currently on |
 
-To change the brightness when using pins B5, B6 or B7, the PWM (Pulse Width Modulation) functionality of the on-chip timer is used.
-The timer is a counter that counts up to a certain TOP value (`0xFFFF` set in ICR1) before resetting to 0.
-We also set an OCR1x register.
-When the counter reaches the value stored in that register, the PWM pin drops to low.
-The PWM pin is pulled high again when the counter resets to 0.
-Therefore, OCR1x basically sets the duty cycle of the LEDs and as such the brightness where `0` is the darkest and `0xFFFF` the brightest setting.
+### Backlight Breathing Functions
 
-To enable the breathing effect, we register an interrupt handler to be called whenever the counter resets (with `ISR(TIMER1_OVF_vect)`).
-In this handler, which gets called roughly 244 times per second, we compute the desired brightness using a precomputed brightness curve.
-To disable breathing, we can just disable the respective interrupt vector and reset the brightness to the desired level.
+|Function  |Description                                               |
+|----------|----------------------------------------------------------|
+|`breathing_toggle()`  |Turn the backlight breathing on or off        |
+|`breathing_enable()`  |Turns on backlight breathing                  |
+|`breathing_disable()` |Turns off backlight breathing                 |

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 31 - 1
docs/feature_bluetooth.md


+ 151 - 89
docs/feature_bootmagic.md

@@ -1,89 +1,151 @@
-# Bootmagic and Magic Keycodes
-
-There are 3 separate but related features that allow you to change the behavior of your keyboard without reflashing. While each of them have similar functionality you access that functionality in different ways depending on how your keyboard is configured.
-
-Bootmagic is a system for configuring your keyboard while it initializes. To trigger a Bootmagic command you hold down the bootmagic key (`KC_SPACE` on most keyboards) and one or more command keys.
-
-Bootmagic Keycodes allow you to access the Bootmagic functionality after your keyboard has initialized. To use Bootmagic Keycodes you assign keycodes starting with `MAGIC_`, much in the same way you define any other key.
-
-Command is a feature that allows you to control different aspects of your keyboard. Command used to be called Magic. Command is typically accessed by holding Left and Right Shift at the same time, although that can be customized. While it shares some functionality with Bootmagic it also allows you to access functionality that Bootmagic does not. For more information see the [Command](feature_command.md) documentation page.
-
-## Enabling Bootmagic
-
-Bootmagic is disabled by default. To use Bootmagic you need to enable it in your `rules.mk` file:
-
-    BOOTMAGIC_ENABLE = yes
-
-## Bootmagic Hotkeys and Keycodes
-
-This table describes the default Hotkeys for Bootmagic and the Keycodes for Magic. These may be overriden at the Keyboard or Keymap level. Some functionality is not available in both methods.
-
-To use the Hotkey hold down `BOOTMAGIC_KEY_SALT` (`KC_SPACE` by default) and the Hotkey while plugging in your keyboard. To use the Keycode assign that keycode to a layer. For example, if you hold down Space+B while plugging in most keyboards, you will enter bootloader mode.
-
-|Hotkey     |Keycode                           |Description                                             |
-|-----------|----------------------------------|--------------------------------------------------------|
-|`ESC`      |                                  |Skip bootmagic and saved eeprom configuration           |
-|`B`        |`RESET`                           |Enter bootloader instead of firmware                    |
-|`D`        |`DEBUG`                           |Enable debugging (writes messages to serial)            |
-|`X`        |                                  |Enable matrix debugging                                 |
-|`K`        |                                  |Enable keyboard debugging                               |
-|`M`        |                                  |Enable mouse debugging                                  |
-|`BACKSPACE`|                                  |Clear the saved settings from flash                     |
-|`CAPSLOCK` |`MAGIC_CAPSLOCK_TO_CONTROL`       |Treat `Capslock` as `Control`                           |
-|           |`MAGIC_UNCAPSLOCK_TO_CONTROL`     |Stop treating CapsLock as Control                       |
-|`LCTRL`    |`MAGIC_SWAP_CONTROL_CAPSLOCK`     |Swap `Control` and `Capslock`                           |
-|           |`MAGIC_UNSWAP_CONTROL_CAPSLOCK`   |Unswap Left Control and Caps Lock                       |
-|           |`MAGIC_SWAP_ALT_GUI`              |Swap Alt and GUI on both sides                          |
-|           |`MAGIC_UNSWAP_ALT_GUI`            |Unswap Left Alt and GUI                                 |
-|`LALT`     |`MAGIC_SWAP_LALT_LGUI`            |Swap Left `Alt` and `GUI`, e.g. for OSX Opt and Cmd     |
-|           |`MAGIC_UNSWAP_LALT_LGUI`          |Unswap Left Alt and GUI                                 |
-|`RALT`     |`MAGIC_SWAP_RALT_RGUI`            |Swap Right `Alt` and `GUI`                              |
-|           |`MAGIC_UNSWAP_RALT_RGUI`          |Unswap Right Alt and GUI                                |
-|`LGUI`     |`MAGIC_NO_GUI`                    |Disable GUI key - e.g. disable Windows key during gaming|
-|           |`MAGIC_UNNO_GUI`                  |Enable the GUI key                                      |
-|`GRAVE`    |`MAGIC_SWAP_GRAVE_ESC`            |Swap `\`~` and `ESC`                                    |
-|           |`MAGIC_UNSWAP_GRAVE_ESC`          |Unswap `\`~` and Escape                                 |
-|`BACKSLASH`|`MAGIC_SWAP_BACKSLASH_BACKSPACE`  |Swap Blackslash and Backspace                           |
-|           |`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|Unswap Backslash and Backspace                          |
-|`N`        |`MAGIC_HOST_NKRO`                 |Force N-Key Rollover (NKRO) on                          |
-|           |`MAGIC_UNHOST_NKRO`               |Force NKRO off                                          |
-|           |`MAGIC_TOGGLE_NKRO`               |Toggle NKRO on or off                                   |
-|`0`        |`DF(0)`                           |Make Layer 0 the default layer at bootup                |
-|`1`        |`DF(1)`                           |Make Layer 1 the default layer at bootup                |
-|`2`        |`DF(2)`                           |Make Layer 2 the default layer at bootup                |
-|`3`        |`DF(3)`                           |Make Layer 3 the default layer at bootup                |
-|`4`        |`DF(4)`                           |Make Layer 4 the default layer at bootup                |
-|`5`        |`DF(5)`                           |Make Layer 5 the default layer at bootup                |
-|`6`        |`DF(6)`                           |Make Layer 6 the default layer at bootup                |
-|`7`        |`DF(7)`                           |Make Layer 7 the default layer at bootup                |
-
-## Bootmagic Configuration
-
-When setting up your keyboard and/or keymap there are a number of `#define`s that control the behavior of Bootmagic. To use these put them in your `config.h`, either at the keyboard or keymap level.
-
-|Define |Default|Description |
-|-------|-------|------------|
-|`BOOTMAGIC_KEY_SALT`|`KC_SPACE`|The key to hold down to trigger Bootmagic during initialization.|
-|`BOOTMAGIC_KEY_SKIP`|`KC_ESC`|The Hotkey to ignore saved eeprom configuration.|
-|`BOOTMAGIC_KEY_EEPROM_CLEAR`|`KC_BSPACE`|The hotkey to clear the saved eeprom configuration.|
-|`BOOTMAGIC_KEY_BOOTLOADER`|`KC_B`|The hotkey to enter the bootloader.|
-|`BOOTMAGIC_KEY_DEBUG_ENABLE`|`KC_D`|The hotkey to enable debug mode.|
-|`BOOTMAGIC_KEY_DEBUG_MATRIX`|`KC_X`|The hotkey to enable matrix debugging mode.|
-|`BOOTMAGIC_KEY_DEBUG_KEYBOARD`|`KC_K`|The hotkey to enable keyboard debugging mode.|
-|`BOOTMAGIC_KEY_DEBUG_MOUSE`|`KC_M`|The hotkey to enable mouse debugging mode.|
-|`BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK`|`KC_LCTRL`||
-|`BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL`|`KC_CAPSLOCK`||
-|`BOOTMAGIC_KEY_SWAP_LALT_LGUI`|`KC_LALT`||
-|`BOOTMAGIC_KEY_SWAP_RALT_RGUI`|`KC_RALT`||
-|`BOOTMAGIC_KEY_NO_GUI`|`KC_LGUI`||
-|`BOOTMAGIC_KEY_SWAP_GRAVE_ESC`|`KC_GRAVE`||
-|`BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE`|`KC_BSLASH`||
-|`BOOTMAGIC_HOST_NKRO`|`KC_N`||
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_0`|`KC_0`|Hotkey to set Layer 0 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_1`|`KC_1`|Hotkey to set Layer 1 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_2`|`KC_2`|Hotkey to set Layer 2 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_3`|`KC_3`|Hotkey to set Layer 3 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_4`|`KC_4`|Hotkey to set Layer 4 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_5`|`KC_5`|Hotkey to set Layer 5 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_6`|`KC_6`|Hotkey to set Layer 6 as the default layer|
-|`BOOTMAGIC_KEY_DEFAULT_LAYER_7`|`KC_7`|Hotkey to set Layer 7 as the default layer|
+# Bootmagic
+
+There are three separate but related features that allow you to change the behavior of your keyboard without reflashing. While each of them have similar functionality, it is accessed in different ways depending on how your keyboard is configured.
+
+**Bootmagic** is a system for configuring your keyboard while it initializes. To trigger a Bootmagic command, hold down the Bootmagic key and one or more command keys.
+
+**Bootmagic Keycodes** are prefixed with `MAGIC_`, and allow you to access the Bootmagic functionality *after* your keyboard has initialized. To use the keycodes, assign them to your keymap as you would any other keycode.
+
+**Command**, formerly known as **Magic**, is another feature that allows you to control different aspects of your keyboard. While it shares some functionality with Bootmagic, it also allows you to do things that Bootmagic does not, such as printing version information to the console. For more information, see [Command](feature_command.md).
+
+On some keyboards Bootmagic is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk` with:
+
+```make
+BOOTMAGIC_ENABLE = full
+```
+
+?> You may see `yes` being used in place of `full`, and this is okay. However, `yes` is deprecated, and ideally `full` (or `lite`) should be used instead.
+
+Additionally, you can use [Bootmagic Lite](#bootmagic-lite) (a scaled down, very basic version of Bootmagic) by adding the following to your `rules.mk` file:
+
+```make
+BOOTMAGIC_ENABLE = lite
+```
+
+## Hotkeys
+
+Hold down the Bootmagic key (Space by default) and the desired hotkey while plugging in your keyboard. For example, holding Space+`B` should cause it to enter the bootloader.
+
+|Hotkey            |Description                                  |
+|------------------|---------------------------------------------|
+|Escape            |Ignore Bootmagic configuration in EEPROM     |
+|`B`               |Enter the bootloader                         |
+|`D`               |Toggle debugging over serial                 |
+|`X`               |Toggle key matrix debugging                  |
+|`K`               |Toggle keyboard debugging                    |
+|`M`               |Toggle mouse debugging                       |
+|Backspace         |Clear the EEPROM                             |
+|Caps Lock         |Toggle treating Caps Lock as Left Control    |
+|Left Control      |Toggle swapping Caps Lock and Left Control   |
+|Left Alt          |Toggle swapping Left Alt and Left GUI        |
+|Right Alt         |Toggle swapping Right Alt and Right GUI      |
+|Left GUI          |Toggle the GUI keys (useful when gaming)     |
+|<code>&#96;</code>|Toggle swapping <code>&#96;</code> and Escape|
+|`\`               |Toggle swapping `\` and Backspace            |
+|`N`               |Toggle N-Key Rollover (NKRO)                 |
+|`0`               |Make layer 0 the default layer               |
+|`1`               |Make layer 1 the default layer               |
+|`2`               |Make layer 2 the default layer               |
+|`3`               |Make layer 3 the default layer               |
+|`4`               |Make layer 4 the default layer               |
+|`5`               |Make layer 5 the default layer               |
+|`6`               |Make layer 6 the default layer               |
+|`7`               |Make layer 7 the default layer               |
+
+## Keycodes
+
+|Keycode                           |Aliases  |Description                               |
+|----------------------------------|---------|------------------------------------------|
+|`MAGIC_CAPSLOCK_TO_CONTROL`       |         |Treat Caps Lock as Left Control           |
+|`MAGIC_UNCAPSLOCK_TO_CONTROL`     |         |Stop treating Caps Lock as Left Control   |
+|`MAGIC_HOST_NKRO`                 |         |Force N-Key Rollover (NKRO) on            |
+|`MAGIC_UNHOST_NKRO`               |         |Force NKRO off                            |
+|`MAGIC_TOGGLE_NKRO`               |         |Turn NKRO on or off                       |
+|`MAGIC_NO_GUI`                    |         |Disable the GUI keys (useful when gaming) |
+|`MAGIC_UNNO_GUI`                  |         |Enable the GUI keys                       |
+|`MAGIC_SWAP_ALT_GUI`              |`AG_SWAP`|Swap Alt and GUI on both sides (for macOS)|
+|`MAGIC_UNSWAP_ALT_GUI`            |`AG_NORM`|Unswap Left Alt and Left GUI              |
+|`MAGIC_TOGGLE_ALT_GUI`            |`AG_TOGG`|Toggle Left Alt and GUI swap              |
+|`MAGIC_SWAP_BACKSLASH_BACKSPACE`  |         |Swap `\` and Backspace                    |
+|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|         |Unswap `\` and Backspace                  |
+|`MAGIC_SWAP_CONTROL_CAPSLOCK`     |         |Swap Left Control and Caps Lock           |
+|`MAGIC_UNSWAP_CONTROL_CAPSLOCK`   |         |Unswap Left Control and Caps Lock         |
+|`MAGIC_SWAP_GRAVE_ESC`            |         |Swap <code>&#96;</code> and Escape        |
+|`MAGIC_UNSWAP_GRAVE_ESC`          |         |Unswap <code>&#96;</code> and Escape      |
+|`MAGIC_SWAP_LALT_LGUI`            |         |Swap Left Alt and Left GUI                |
+|`MAGIC_UNSWAP_LALT_LGUI`          |         |Unswap Left Alt and Left GUI              |
+|`MAGIC_SWAP_RALT_RGUI`            |         |Swap Right Alt and Right GUI              |
+|`MAGIC_UNSWAP_RALT_RGUI`          |         |Unswap Right Alt and Right GUI            |
+
+## Configuration
+
+If you would like to change the hotkey assignments for Bootmagic, `#define` these in your `config.h` at either the keyboard or keymap level.
+
+|Define                                  |Default      |Description                                        |
+|----------------------------------------|-------------|---------------------------------------------------|
+|`BOOTMAGIC_KEY_SALT`                    |`KC_SPACE`   |The Bootmagic key                                  |
+|`BOOTMAGIC_KEY_SKIP`                    |`KC_ESC`     |Ignore Bootmagic configuration in EEPROM           |
+|`BOOTMAGIC_KEY_EEPROM_CLEAR`            |`KC_BSPACE`  |Clear the EEPROM configuration                     |
+|`BOOTMAGIC_KEY_BOOTLOADER`              |`KC_B`       |Enter the bootloader                               |
+|`BOOTMAGIC_KEY_DEBUG_ENABLE`            |`KC_D`       |Toggle debugging over serial                       |
+|`BOOTMAGIC_KEY_DEBUG_MATRIX`            |`KC_X`       |Toggle matrix debugging                            |
+|`BOOTMAGIC_KEY_DEBUG_KEYBOARD`          |`KC_K`       |Toggle keyboard debugging                          |
+|`BOOTMAGIC_KEY_DEBUG_MOUSE`             |`KC_M`       |Toggle mouse debugging                             |
+|`BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK`   |`KC_LCTRL`   |Swap Left Control and Caps Lock                    |
+|`BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL`     |`KC_CAPSLOCK`|Toggle treating Caps Lock as Left Control          |
+|`BOOTMAGIC_KEY_SWAP_LALT_LGUI`          |`KC_LALT`    |Toggle swapping Left Alt and Left GUI (for macOS)  |
+|`BOOTMAGIC_KEY_SWAP_RALT_RGUI`          |`KC_RALT`    |Toggle swapping Right Alt and Right GUI (for macOS)|
+|`BOOTMAGIC_KEY_NO_GUI`                  |`KC_LGUI`    |Toggle the GUI keys (useful when gaming)           |
+|`BOOTMAGIC_KEY_SWAP_GRAVE_ESC`          |`KC_GRAVE`   |Toggle swapping <code>&#96;</code> and Escape      |
+|`BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE`|`KC_BSLASH`  |Toggle swapping `\` and Backspace                  |
+|`BOOTMAGIC_HOST_NKRO`                   |`KC_N`       |Toggle N-Key Rollover (NKRO)                       |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_0`         |`KC_0`       |Make layer 0 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_1`         |`KC_1`       |Make layer 1 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_2`         |`KC_2`       |Make layer 2 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_3`         |`KC_3`       |Make layer 3 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_4`         |`KC_4`       |Make layer 4 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_5`         |`KC_5`       |Make layer 5 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_6`         |`KC_6`       |Make layer 6 the default layer                     |
+|`BOOTMAGIC_KEY_DEFAULT_LAYER_7`         |`KC_7`       |Make layer 7 the default layer                     |
+
+# Bootmagic Lite
+
+In addition to the full blown Bootmagic feature, is the Bootmagic Lite feature that only handles jumping into the bootloader.  This is great for boards that don't have a physical reset button but you need a way to jump into the bootloader, and don't want to deal with the headache that Bootmagic can cause.
+
+To enable this version of Bootmagic, you need to enable it in your `rules.mk` with:
+
+```make
+BOOTMAGIC_ENABLE = lite
+```
+
+Additionally, you may want to specify which key to use.  This is especially useful for keyboards that have unusual matrices.  To do so, you need to specify the row and column of the key that you want to use. Add these entries to your `config.h` file:
+
+```c
+#define BOOTMAGIC_LITE_ROW 0
+#define BOOTMAGIC_LITE_COLUMN 1
+```
+
+By default, these are set to 0 and 0, which is usually the "ESC" key on a majority of keyboards.
+
+And to trigger the bootloader, you hold this key down when plugging the keyboard in. Just the single key. 
+
+## Advanced Bootmagic Lite
+
+The `bootmagic_lite` function is defined weakly, so that you can replace this in your code, if you need.  A great example of this is the Zeal60 boards that have some additional handling needed.
+
+To replace the function, all you need to do is add something like this to your code:
+
+```c
+void bootmagic_lite(void) {
+    matrix_scan();
+    wait_ms(DEBOUNCING_DELAY * 2);
+    matrix_scan();
+
+    if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
+      // Jump to bootloader.
+      bootloader_jump();
+    }
+}
+```
+
+You can additional feature here. For instance, resetting the eeprom or requiring additional keys to be pressed to trigger bootmagic.  Keep in mind that `bootmagic_lite` is called before a majority of features are initialized in the firmware.

+ 89 - 0
docs/feature_combo.md

@@ -0,0 +1,89 @@
+# Combos
+
+The Combo feature is a chording type solution for adding custom actions.  It lets you hit multiple keys at once and produce a different effect.  For instance, hitting `A` and `S` within the tapping term would hit `ESC` instead, or have it perform even more complex tasks.
+
+To enable this feature, yu need to add `COMBO_ENABLE = yes` to your `rules.mk`.
+
+Additionally, in your `config.h`, you'll need to specify the number of combos that you'll be using, by adding `#define COMBO_COUNT 1` (replacing 1 with the number that you're using).
+<!-- At this time, this is necessary -->
+
+Also, by default, the tapping term for the Combos is set to the same value as `TAPPING_TERM` (200 by default on most boards). But you can specify a different value by defining it in your `config.h`.  For instance: `#define COMBO_TERM 300` would set the time out period for combos to 300ms.
+
+Then, your `keymap.c` file, you'll need to define a sequence of keys, terminated with `COMBO_END`, and a structure to list the combination of keys, and it's resulting action.
+
+```c
+const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END};
+combo_t key_combos[COMBO_COUNT] = {COMBO(test_combo, KC_ESC)};
+```
+
+This will send "Escape" if you hit the A and B keys.
+
+!> This method only supports [basic keycodes](keycodes_basic.md). See the examples for more control.
+!> You cannot reuse (share) keys in combos. Each key should only belong to a single combo.  
+
+## Examples
+
+If you want to add a list, then you'd use something like this:
+
+```c
+enum combos {
+  AB_ESC,
+  JK_TAB
+}
+const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END};
+const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+  [AB_ESC] = COMBO(ab_combo, KC_ESC),
+  [JK_TAB] = COMBO(jk_combo, KC_TAB)
+};
+```
+
+For a more complicated implementation, you can use the `process_combo_event` function to add custom handling.
+
+```c
+enum combo_events {
+  ZC_COPY,
+  XV_PASTE
+  };
+
+const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END};
+const uint16_t PROGMEM paste_combo[] = {KC_X, KC_V, COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+  [ZC_COPY] = COMBO_ACTION(copy_combo),
+  [XV_PASTE] = COMBO_ACTION(paste_combo),
+};
+
+void process_combo_event(uint8_t combo_index, bool pressed) {
+  switch(combo_index) {
+    case ZC_COPY:
+      if (pressed) {
+        register_code(KC_LCTL);
+        register_code(KC_C);
+        unregister_code(KC_C);
+        unregister_code(KC_LCTL);
+      }
+      break;
+
+    case XV_PASTE:
+      if (pressed) {
+        register_code(KC_LCTL);
+        register_code(KC_V);
+        unregister_code(KC_V);
+        unregister_code(KC_LCTL);
+      }
+      break;
+  }
+}
+```
+
+This will send Ctrl+C if you hit Z and C, and Ctrl+V if you hit X and V.  But you could change this to do stuff like change layers, play sounds, or change settings.
+
+## Additional Configuration
+
+If you're using long combos, or even longer combos, you may run into issues with this, as the structure may not be large enough to accommodate what you're doing.
+
+In this case, you can add either `#define EXTRA_LONG_COMBOS` or `#define EXTRA_EXTRA_LONG_COMBOS` in your `config.h` file.
+
+You may also be able to enable action keys by defining `COMBO_ALLOW_ACTION_KEYS`.

+ 41 - 43
docs/feature_command.md

@@ -1,52 +1,50 @@
-# Command (Formerly known as Magic)
+# Command
 
-Command is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic](feature_bootmagic.md). There is a lot of overlap between this functionality and the [Bootmagic Keycodes](feature_bootmagic.md). Whenever possible we encourage you to use that functionality instead of Command.
+Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic](feature_bootmagic.md). There is a lot of overlap between this functionality and the [Bootmagic Keycodes](feature_bootmagic.md#keycodes). Wherever possible we encourage you to use that feature instead of Command.
 
-## Enabling Command
+On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`:
 
-By default Command is disabled. You can enable it in your `rules.mk` file:
-
-    COMMAND_ENABLE = yes
+```make
+COMMAND_ENABLE = yes
+```
 
 ## Usage
 
-To use Command you hold down the key combination defined by `IS_COMMAND`. By default that combination is both shift keys. While holding the key combination press the key corresponding to the command you want.
-
-For example, to write the current QMK version to the QMK Toolbox console, you can press `Left Shift`+`Right Shift`+`V`.
+To use Command, hold down the key combination defined by the `IS_COMMAND()` macro. By default this is Left Shift+Right Shift. Then, press the key corresponding to the command you want. For example, to output the current QMK version to the QMK Toolbox console, press Left Shift+Right Shift+`V`.
 
 ## Configuration
 
-The following values can be defined in `config.h` to control the behavior of Command.
-
-|Define |Default | Description |
-|-------|--------|-------------|
-|`IS_COMMAND()`                      |`(keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))`|Key combination to activate Command|
-|`MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` |`true`                                                                |Do layer switching with Function row|
-|`MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` |`true`                                                                |Do layer switching with number keys.|
-|`MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM`|`false`                                                               |Do layer switching with custom keys (`MAGIC_KEY_LAYER0..9` below.)|
-|`MAGIC_KEY_HELP1`                   |`H`                                                                   |Show help.|
-|`MAGIC_KEY_HELP2`                   |`SLASH`                                                               |Show help.|
-|`MAGIC_KEY_DEBUG`                   |`D`                                                                   |Turn on debug mode.|
-|`MAGIC_KEY_DEBUG_MATRIX`            |`X`                                                                   |Turn on matrix debugging.|
-|`MAGIC_KEY_DEBUG_KBD`               |`K`                                                                   |Turn on keyboard debugging.|
-|`MAGIC_KEY_DEBUG_MOUSE`             |`M`                                                                   |Turn on mouse debugging.|
-|`MAGIC_KEY_VERSION`                 |`V`                                                                   |Write the QMK version to the console|
-|`MAGIC_KEY_STATUS`                  |`S`                                                                   |Show the current keyboard status|
-|`MAGIC_KEY_CONSOLE`                 |`C`                                                                   |Enable the Command Console|
-|`MAGIC_KEY_LAYER0_ALT1`             |`ESC`                                                                 |Alternate access to layer 0|
-|`MAGIC_KEY_LAYER0_ALT2`             |`GRAVE`                                                               |Alternate access to layer 0|
-|`MAGIC_KEY_LAYER0`                  |`0`                                                                   |Change default layer to 0|
-|`MAGIC_KEY_LAYER1`                  |`1`                                                                   |Change default layer to 1|
-|`MAGIC_KEY_LAYER2`                  |`2`                                                                   |Change default layer to 2|
-|`MAGIC_KEY_LAYER3`                  |`3`                                                                   |Change default layer to 3|
-|`MAGIC_KEY_LAYER4`                  |`4`                                                                   |Change default layer to 4|
-|`MAGIC_KEY_LAYER5`                  |`5`                                                                   |Change default layer to 5|
-|`MAGIC_KEY_LAYER6`                  |`6`                                                                   |Change default layer to 6|
-|`MAGIC_KEY_LAYER7`                  |`7`                                                                   |Change default layer to 7|
-|`MAGIC_KEY_LAYER8`                  |`8`                                                                   |Change default layer to 8|
-|`MAGIC_KEY_LAYER9`                  |`9`                                                                   |Change default layer to 9|
-|`MAGIC_KEY_BOOTLOADER`              |`PAUSE`                                                               |Exit keyboard and enter bootloader|
-|`MAGIC_KEY_LOCK`                    |`CAPS`                                                                |Lock the keyboard so nothing can be typed|
-|`MAGIC_KEY_EEPROM`                  |`E`                                                                   |Erase EEPROM settings|
-|`MAGIC_KEY_NKRO`                    |`N`                                                                   |Toggle NKRO on/off|
-|`MAGIC_KEY_SLEEP_LED`               |`Z`                                                                   |Toggle LED when computer is sleeping on/off|
+If you would like to change the key assignments for Command, `#define` these in your `config.h` at either the keyboard or keymap level. All keycode assignments here must omit the `KC_` prefix.
+
+|Define                              |Default                                                                               |Description                                     |
+|------------------------------------|--------------------------------------------------------------------------------------|------------------------------------------------|
+|`IS_COMMAND()`                      |<code>(keyboard_report->mods == (MOD_BIT(KC_LSHIFT) &#124; MOD_BIT(KC_RSHIFT)))</code>|The key combination to activate Command         |
+|`MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` |`true`                                                                                |Set default layer with the Function row         |
+|`MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` |`true`                                                                                |Set default layer with the number keys          |
+|`MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM`|`false`                                                                               |Set default layer with `MAGIC_KEY_LAYER0..9`    |
+|`MAGIC_KEY_DEBUG`                   |`D`                                                                                   |Toggle debugging over serial                    |
+|`MAGIC_KEY_DEBUG_MATRIX`            |`X`                                                                                   |Toggle key matrix debugging                     |
+|`MAGIC_KEY_DEBUG_KBD`               |`K`                                                                                   |Toggle keyboard debugging                       |
+|`MAGIC_KEY_DEBUG_MOUSE`             |`M`                                                                                   |Toggle mouse debugging                          |
+|`MAGIC_KEY_CONSOLE`                 |`C`                                                                                   |Enable the Command console                      |
+|`MAGIC_KEY_VERSION`                 |`V`                                                                                   |Print the running QMK version to the console    |
+|`MAGIC_KEY_STATUS`                  |`S`                                                                                   |Print the current keyboard status to the console|
+|`MAGIC_KEY_HELP1`                   |`H`                                                                                   |Print Command help to the console               |
+|`MAGIC_KEY_HELP2`                   |`SLASH`                                                                               |Print Command help to the console (alternate)   |
+|`MAGIC_KEY_LAYER0`                  |`0`                                                                                   |Make layer 0 the default layer                  |
+|`MAGIC_KEY_LAYER1`                  |`1`                                                                                   |Make layer 1 the default layer                  |
+|`MAGIC_KEY_LAYER2`                  |`2`                                                                                   |Make layer 2 the default layer                  |
+|`MAGIC_KEY_LAYER3`                  |`3`                                                                                   |Make layer 3 the default layer                  |
+|`MAGIC_KEY_LAYER4`                  |`4`                                                                                   |Make layer 4 the default layer                  |
+|`MAGIC_KEY_LAYER5`                  |`5`                                                                                   |Make layer 5 the default layer                  |
+|`MAGIC_KEY_LAYER6`                  |`6`                                                                                   |Make layer 6 the default layer                  |
+|`MAGIC_KEY_LAYER7`                  |`7`                                                                                   |Make layer 7 the default layer                  |
+|`MAGIC_KEY_LAYER8`                  |`8`                                                                                   |Make layer 8 the default layer                  |
+|`MAGIC_KEY_LAYER9`                  |`9`                                                                                   |Make layer 9 the default layer                  |
+|`MAGIC_KEY_LAYER0_ALT1`             |`ESC`                                                                                 |Make layer 0 the default layer (alternate)      |
+|`MAGIC_KEY_LAYER0_ALT2`             |`GRAVE`                                                                               |Make layer 0 the default layer (alternate)      |
+|`MAGIC_KEY_BOOTLOADER`              |`PAUSE`                                                                               |Enter the bootloader                            |
+|`MAGIC_KEY_LOCK`                    |`CAPS`                                                                                |Lock the keyboard so nothing can be typed       |
+|`MAGIC_KEY_EEPROM`                  |`E`                                                                                   |Clear the EEPROM                                |
+|`MAGIC_KEY_NKRO`                    |`N`                                                                                   |Toggle N-Key Rollover (NKRO)                    |
+|`MAGIC_KEY_SLEEP_LED`               |`Z`                                                                                   |Toggle LED when computer is sleeping            |

+ 3 - 3
docs/feature_dynamic_macros.md

@@ -4,10 +4,10 @@ QMK supports temporary macros created on the fly. We call these Dynamic Macros.
 
 You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM.
 
-To enable them, first add a new element to the `planck_keycodes` enum — `DYNAMIC_MACRO_RANGE`:
+To enable them, first add a new element to the end of your `keycodes` enum — `DYNAMIC_MACRO_RANGE`:
 
 ```c
-enum planck_keycodes {
+enum keycodes {
 	QWERTY = SAFE_RANGE,
 	COLEMAK,
 	DVORAK,
@@ -20,7 +20,7 @@ enum planck_keycodes {
 };
 ```
 
-It must be the last element because `dynamic_macros.h` will add some more keycodes after it.
+Your `keycodes` enum may have a slightly different name. You must add `DYNAMIC_MACRO_RANGE` as the last element because `dynamic_macros.h` will add some more keycodes after it.
 
 Below it, include the `dynamic_macro.h` header:
 

+ 48 - 0
docs/feature_encoders.md

@@ -0,0 +1,48 @@
+# Encoders
+
+Basic encoders are supported by adding this to your `rules.mk`:
+
+    ENCODER_ENABLE = yes
+
+and this to your `config.h`:
+
+    #define NUMBER_OF_ENCODERS 1
+    #define ENCODERS_PAD_A { B12 }
+    #define ENCODERS_PAD_B { B13 }
+
+Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.:
+
+    #define ENCODERS_PAD_A { encoder1a, encoder2a }
+    #define ENCODERS_PAD_B { encoder1a, encoder2b }
+
+If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions.
+
+Additionally, the resolution can be specified in the same file (the default & suggested is 4):
+
+    #define ENCODER_RESOLUTION 4
+
+## Callbacks
+
+The callback functions can be inserted into your `<keyboard>.c`:
+
+    void encoder_update_kb(uint8_t index, bool clockwise) {
+        encoder_update_user(index, clockwise);
+    }
+
+or `keymap.c`:
+
+    void encoder_update_user(uint8_t index, bool clockwise) {
+        if (index == 0) {
+            if (clockwise) {
+                register_code(KC_PGDN);
+                unregister_code(KC_PGDN);
+            } else {
+                register_code(KC_PGUP);
+                unregister_code(KC_PGUP);
+            }
+        }
+    }
+
+## Hardware
+
+The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground.

+ 15 - 8
docs/feature_grave_esc.md

@@ -1,17 +1,24 @@
 # Grave Escape
 
-Grave Escape is a feature that allows you to share the grave key (<code>&#96;</code> and `~`) on the same key as Escape. When `KC_GESC` is used it will act as `KC_ESC`, unless Shift or GUI is pressed, in which case it will act as `KC_GRAVE`.
+If you're using a 60% keyboard, or any other layout with no F-row, you will have noticed that there is no dedicated Escape key. Grave Escape is a feature that allows you to share the grave key (<code>&#96;</code> and `~`) with Escape.
 
+## Usage
+
+Replace the `KC_GRAVE` key in your keymap (usually to the left of the `1` key) with `KC_GESC`. When pressed it will behave like `KC_ESC`, but with Shift or GUI held it will send `KC_GRAVE`.
+
+## Keycodes
 
 |Key      |Aliases    |Description                                                       |
 |---------|-----------|------------------------------------------------------------------|
 |`KC_GESC`|`GRAVE_ESC`|Escape when pressed, <code>&#96;</code> when Shift or GUI are held|
 
-There are several possible key combinations this will break, among them Ctrl+Shift+Esc on Windows and Cmd+Opt+Esc on macOS. You can use these options in your `config.h` to work around this:
+## Configuration
+
+There are several possible key combinations this will break, among them Control+Shift+Escape on Windows and Command+Option+Escape on macOS. To work around this, you can `#define` these options in your `config.h`:
 
-| Option | Description |
-|--------|-------------|
-| `GRAVE_ESC_ALT_OVERRIDE` | Always send Escape if Alt is pressed. |
-| `GRAVE_ESC_CTRL_OVERRIDE` | Always send Escape if Ctrl is pressed. |
-| `GRAVE_ESC_GUI_OVERRIDE` | Always send Escape if GUI is pressed. |
-| `GRAVE_ESC_SHIFT_OVERRIDE` | Always send Escape if SHIFT is pressed. |
+|Define                    |Description                              |
+|--------------------------|-----------------------------------------|
+|`GRAVE_ESC_ALT_OVERRIDE`  |Always send Escape if Alt is pressed     |
+|`GRAVE_ESC_CTRL_OVERRIDE` |Always send Escape if Control is pressed |
+|`GRAVE_ESC_GUI_OVERRIDE`  |Always send Escape if GUI is pressed     |
+|`GRAVE_ESC_SHIFT_OVERRIDE`|Always send Escape if Shift is pressed   |

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 18 - 7
docs/feature_key_lock.md


+ 6 - 0
docs/feature_layouts.md

@@ -53,6 +53,8 @@ but the `LAYOUT_<layout>` variable must be defined in `<folder>.h` as well.
 
 ## Tips for Making Layouts Keyboard-Agnostic
 
+### Includes
+
 Instead of using `#include "planck.h"`, you can use this line to include whatever `<keyboard>.h` (`<folder>.h` should not be included here) file that is being compiled:
 
     #include QMK_KEYBOARD_H
@@ -72,3 +74,7 @@ For example:
 ```
 
 Note that the names are lowercase and match the folder/file names for the keyboard/revision exactly.
+
+### Keymaps
+
+In order to support both split and non-split keyboards with the same layout, you need to use the keyboard agnostic `LAYOUT_<layout name>` macro in your keymap. For instance, in order for a Let's Split and Planck to share the same layout file, you need to use `LAYOUT_ortho_4x12` instead of `LAYOUT_planck_grid` or just `{}` for a C array.

+ 9 - 1
docs/feature_leader_key.md

@@ -5,7 +5,7 @@ If you've ever used Vim, you know what a Leader key is. If not, you're about to
 That's what `KC_LEAD` does. Here's an example:
 
 1. Pick a key on your keyboard you want to use as the Leader key. Assign it the keycode `KC_LEAD`. This key would be dedicated just for this -- it's a single action key, can't be used for anything else.
-2. Include the line `#define LEADER_TIMEOUT 300` somewhere in your keymap.c file, probably near the top. The 300 there is 300ms -- that's how long you have for the sequence of keys following the leader. You can tweak this value for comfort, of course.
+2. Include the line `#define LEADER_TIMEOUT 300` in your config.h. The 300 there is 300ms -- that's how long you have for the sequence of keys following the leader. You can tweak this value for comfort, of course.
 3. Within your `matrix_scan_user` function, do something like this:
 
 ```
@@ -39,3 +39,11 @@ void matrix_scan_user(void) {
 As you can see, you have a few function. You can use `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS`, `SEQ_THREE_KEYS` up to `SEQ_FIVE_KEYS` for longer sequences.
 
 Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
+
+## Adding Leader Key Support in the `rules.mk`
+
+To add support for Leader Key you simply need to add a single line to your keymap's `rules.mk`:
+
+```
+LEADER_ENABLE = yes
+```

+ 4 - 0
docs/feature_macros.md

@@ -228,6 +228,10 @@ This sends the `<kc>` keydown event to the computer. Some examples would be `KC_
 
 Parallel to `register_code` function, this sends the `<kc>` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
 
+### `tap_code(<kc>);`
+
+This will send `register_code(<kc>)` and then `unregister_code(<kc>)`. This is useful if you want to send both the press and release events ("tap" the key, rather than hold it).
+
 ### `clear_keyboard();`
 
 This will clear all mods and keys currently pressed.

+ 18 - 0
docs/feature_ps2_mouse.md

@@ -6,6 +6,24 @@ To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest fr
 
 There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended).
 
+### The Cirtuitry between Trackpoint and Controller
+
+To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+. 
+
+```
+
+          DATA ----------+--------- PIN
+                         |
+                        4.7K
+                         |
+MODULE    5+  --------+--+--------- PWR   CONTROLLER
+                      |
+                     4.7K
+                      |    
+          CLK   ------+------------ PIN
+```
+
+
 ### Busywait Version
 
 Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.

+ 78 - 5
docs/feature_rgb_matrix.md

@@ -1,8 +1,12 @@
 # RGB Matrix Lighting
 
+## Driver configuration
+
+### IS31FL3731
+
 There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
 
-    RGB_MATRIX_ENABLE = yes
+    RGB_MATRIX_ENABLE = IS31FL3731
 
 Configure the hardware via your `config.h`:
 
@@ -36,7 +40,51 @@ Define these arrays listing all the LEDs in your `<keyboard>.c`:
 	    ....
 	}
 
-Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf). The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
+Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now).
+
+###  IS31FL3733
+
+There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
+
+    RGB_MATRIX_ENABLE = IS31FL3733
+
+Configure the hardware via your `config.h`:
+
+	// This is a 7-bit address, that gets left-shifted and bit 0
+	// set to 0 for write, 1 for read (as per I2C protocol)
+	// The address will vary depending on your wiring:
+	// 00 <-> GND
+	// 01 <-> SCL
+	// 10 <-> SDA
+	// 11 <-> VCC
+	// ADDR1 represents A1:A0 of the 7-bit address.
+	// ADDR2 represents A3:A2 of the 7-bit address.
+	// The result is: 0b101(ADDR2)(ADDR1)
+	#define DRIVER_ADDR_1 0b1010000
+	#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons.
+
+	#define DRIVER_COUNT 1
+	#define DRIVER_1_LED_TOTAL 64
+	#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL
+
+Currently only a single drivers is supported, but it would be trivial to support all 4 combinations. For now define `DRIVER_ADDR_2` as `DRIVER_ADDR_1`
+
+Define these arrays listing all the LEDs in your `<keyboard>.c`:
+
+	const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
+	/* Refer to IS31 manual for these locations
+	 *   driver
+	 *   |  R location
+	 *   |  |       G location
+	 *   |  |       |       B location
+	 *   |  |       |       | */
+	    {0, B_1,    A_1,    C_1},
+	    ....
+	}
+
+Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0` right now).
+
+From this point forward the configuration is the same for all the drivers. 
 
 	const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
 	/* {row | col << 4}
@@ -80,7 +128,7 @@ All RGB keycodes are currently shared with the RGBLIGHT system:
 These are the effects that are currently available:
 
 	enum rgb_matrix_effects {
-		RGB_MATRIX_SOLID_COLOR = 1,
+	    RGB_MATRIX_SOLID_COLOR = 1,
 	    RGB_MATRIX_ALPHAS_MODS,
 	    RGB_MATRIX_DUAL_BEACON,
 	    RGB_MATRIX_GRADIENT_UP_DOWN,
@@ -92,8 +140,9 @@ These are the effects that are currently available:
 	    RGB_MATRIX_RAINBOW_PINWHEELS,
 	    RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
 	    RGB_MATRIX_JELLYBEAN_RAINDROPS,
+	    RGB_MATRIX_DIGITAL_RAIN,
 	#ifdef RGB_MATRIX_KEYPRESSES
-		RGB_MATRIX_SOLID_REACTIVE,
+	    RGB_MATRIX_SOLID_REACTIVE,
 	    RGB_MATRIX_SPLASH,
 	    RGB_MATRIX_MULTISPLASH,
 	    RGB_MATRIX_SOLID_SPLASH,
@@ -101,13 +150,37 @@ These are the effects that are currently available:
 	#endif
 	    RGB_MATRIX_EFFECT_MAX
 	};
+    
+You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `config.h`:
+
+
+|Define                                             |Description                                 |
+|---------------------------------------------------|--------------------------------------------|
+|`#define DISABLE_RGB_MATRIX_ALPHAS_MODS`           |Disables `RGB_MATRIX_ALPHAS_MODS`           |
+|`#define DISABLE_RGB_MATRIX_DUAL_BEACON`           |Disables `RGB_MATRIX_DUAL_BEACON`           |
+|`#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN`      |Disables `RGB_MATRIX_GRADIENT_UP_DOWN`      |
+|`#define DISABLE_RGB_MATRIX_RAINDROPS`             |Disables `RGB_MATRIX_RAINDROPS`             |
+|`#define DISABLE_RGB_MATRIX_CYCLE_ALL`             |Disables `RGB_MATRIX_CYCLE_ALL`             |
+|`#define DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT`      |Disables `RGB_MATRIX_CYCLE_LEFT_RIGHT`      |
+|`#define DISABLE_RGB_MATRIX_CYCLE_UP_DOWN`         |Disables `RGB_MATRIX_CYCLE_UP_DOWN`         |
+|`#define DISABLE_RGB_MATRIX_RAINBOW_BEACON`        |Disables `RGB_MATRIX_RAINBOW_BEACON`        |
+|`#define DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS`     |Disables `RGB_MATRIX_RAINBOW_PINWHEELS`     |
+|`#define DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON`|Disables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON`|
+|`#define DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS`   |Disables `RGB_MATRIX_JELLYBEAN_RAINDROPS`   |
+|`#define DISABLE_RGB_MATRIX_DIGITAL_RAIN`          |Disables `RGB_MATRIX_DIGITAL_RAIN`          |
+|`#define DISABLE_RGB_MATRIX_SOLID_REACTIVE`        |Disables `RGB_MATRIX_SOLID_REACTIVE`        |
+|`#define DISABLE_RGB_MATRIX_SPLASH`                |Disables `RGB_MATRIX_SPLASH`                |
+|`#define DISABLE_RGB_MATRIX_MULTISPLASH`           |Disables `RGB_MATRIX_MULTISPLASH`           |
+|`#define DISABLE_RGB_MATRIX_SOLID_SPLASH`          |Disables `RGB_MATRIX_SOLID_SPLASH`          |
+|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH`     |Disables `RGB_MATRIX_SOLID_MULTISPLASH`     |
+
 
 ## Custom layer effects
 
 Custom layer effects can be done by defining this in your `<keyboard>.c`:
 
     void rgb_matrix_indicators_kb(void) {
-    	// rgb_matrix_set_color(index, red, green, blue);
+        rgb_matrix_set_color(index, red, green, blue);
     }
 
 A similar function works in the keymap as `rgb_matrix_indicators_user`.

+ 120 - 121
docs/feature_rgblight.md

@@ -1,131 +1,46 @@
 # RGB Lighting
 
-If you've installed addressable RGB lights on your keyboard you can control them with QMK. Currently we support the following addressable LEDs on Atmel AVR processors:
+QMK has the ability to control RGB LEDs attached to your keyboard. This is commonly called *underglow*, due to the LEDs often being mounted on the bottom of the keyboard, producing a nice diffused effect when combined with a translucent case.
 
-* WS2811 and variants (WS2812, WS2812B, WS2812C, etc)
-* SK6812RGBW
-
-Some keyboards come with RGB LEDs pre-installed. Others have to have LEDs installed after the fact. See below for information on modifying your keyboard.
-
-## Selecting Colors
-
-QMK uses Hue, Saturation, and Value to set color rather than using RGB. You can use the color wheel below to see how this works. Changing the Hue will cycle around the circle. Saturation will affect the intensity of the color, which you can see as you move from the inner part to the outer part of the wheel. Value sets the overall brightness.
-
-<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250">
-
-If you would like to learn more about HSV you can start with the [Wikipedia article](https://en.wikipedia.org/wiki/HSL_and_HSV).
+![Planck with RGB Underglow](https://raw.githubusercontent.com/qmk/qmk_firmware/3774a7fcdab5544fc787f4c200be05fcd417e31f/keyboards/planck/keymaps/yang/planck-with-rgb-underglow.jpg)
 
-## Configuration
+Some keyboards come with RGB LEDs preinstalled. Others must have them installed after the fact. See the [Hardware Modification](#hardware-modification) section for information on adding RGB lighting to your keyboard.
 
-Before RGB Lighting can be used you have to enable it in `rules.mk`:
+Currently QMK supports the following addressable LEDs on AVR microcontrollers (however, the white LED in RGBW variants is not supported):
 
-    RGBLIGHT_ENABLE = yes
+ * WS2811, WS2812, WS2812B, WS2812C, etc.
+ * SK6812, SK6812MINI, SK6805
 
-You can configure the behavior of the RGB lighting by defining values inside `config.h`.
+These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs.
 
-### Required Configuration
+## Usage
 
-At minimum you have to define the pin your LED strip is connected to and the number of LEDs connected.
+On keyboards with onboard RGB LEDs, it is usually enabled by default. If it is not working for you, check that your `rules.mk` includes the following:
 
-```c
-#define RGB_DI_PIN D7     // The pin the LED strip is connected to
-#define RGBLED_NUM 14     // Number of LEDs in your strip
+```make
+RGBLIGHT_ENABLE = yes
 ```
 
-### Optional Configuration
-
-You can change the behavior of the RGB Lighting by setting these configuration values. Use `#define <Option> <Value>` in a `config.h` at the keyboard, revision, or keymap level.
+At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these.
 
-| Option | Default Value | Description |
-|--------|---------------|-------------|
-| `RGBLIGHT_HUE_STEP` | 10 | How many hues you want to have available. |
-| `RGBLIGHT_SAT_STEP` | 17 | How many steps of saturation you'd like. |
-| `RGBLIGHT_VAL_STEP` | 17 | The number of levels of brightness you want. |
-| `RGBLIGHT_LIMIT_VAL` | 255 | Limit the val of HSV to limit the maximum brightness simply. |
-| `RGBLIGHT_SLEEP`     |    |  `#define` this will shut off the lights when the host goes to sleep | 
+|Define      |Description                                  |
+|------------|---------------------------------------------|
+|`RGB_DI_PIN`|The pin connected to the data pin of the LEDs|
+|`RGBLED_NUM`|The number of LEDs connected                 |
 
+Then you should be able to use the keycodes below to change the RGB lighting to your liking.
 
-### Animations
+### Color Selection
 
-If you have `#define RGBLIGHT_ANIMATIONS` in your `config.h` you will have a number of animation modes you can cycle through using the `RGB_MOD` key. You can also `#define` other options to tweak certain animations.
+QMK uses [Hue, Saturation, and Value](https://en.wikipedia.org/wiki/HSL_and_HSV) to select colors rather than RGB. The color wheel below demonstrates how this works.
 
-| Option | Default Value | Description |
-|--------|---------------|-------------|
-| `RGBLIGHT_ANIMATIONS` | | `#define` this to enable animation modes. |
-| `RGBLIGHT_EFFECT_BREATHE_CENTER` | 1.85 | Used to calculate the curve for the breathing animation. Valid values 1.0-2.7. |
-| `RGBLIGHT_EFFECT_BREATHE_MAX` | 255 | The maximum brightness for the breathing mode. Valid values 1-255. |
-| `RGBLIGHT_EFFECT_SNAKE_LENGTH` | 4 | The number of LEDs to light up for the "snake" animation. |
-| `RGBLIGHT_EFFECT_KNIGHT_LENGTH` | 3 | The number of LEDs to light up for the "knight" animation. |
-| `RGBLIGHT_EFFECT_KNIGHT_OFFSET` | 0 | Start the knight animation this many LEDs from the start of the strip. |
-| `RGBLIGHT_EFFECT_KNIGHT_LED_NUM` | RGBLED_NUM | The number of LEDs to have the "knight" animation travel. |
-| `RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL` | 1000 | How long to wait between light changes for the "christmas" animation. Specified in ms. |
-| `RGBLIGHT_EFFECT_CHRISTMAS_STEP` | 2 | How many LED's to group the red/green colors by for the christmas mode. |
+<img src="gitbook/images/color-wheel.svg" alt="HSV Color Wheel" width="250"/>
 
-You can also tweak the behavior of the animations by defining these consts in your `keymap.c`. These mostly affect the speed different modes animate at.
-
-```c
-// How long (in ms) to wait between animation steps for the breathing mode
-const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
-
-// How long (in ms) to wait between animation steps for the rainbow mode
-const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
-
-// How long (in ms) to wait between animation steps for the swirl mode
-const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
-
-// How long (in ms) to wait between animation steps for the snake mode
-const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
-
-// How long (in ms) to wait between animation steps for the knight modes
-const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
-
-// These control which colors are selected for the gradient mode
-const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
-```
+Changing the **Hue** cycles around the circle.  
+Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.  
+Changing the **Value** sets the overall brightness.
 
-### LED Control
-
-Look in `rgblights.h` for all available functions, but if you want to control all or some LEDs your goto functions are:
-
-```c
-// turn all lights off (stored in EEPROM)
-rgblight_disable();
-// turn lights on, based on their previous state (stored in EEPROM)
-rgblight_enable(); 
-
-// turn all lights off (not stored in EEPROM)
-rgblight_disable_noeeprom();
-// turn lights on, based on their previous state (not stored in EEPROM)
-rgblight_enable_noeeprom();
-
-// where r/g/b is a number from 0..255.  Turns all the LEDs to this color (ignores mode, not stored in EEPROM). 
-rgblight_setrgb(r, g, b); 
-// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (stored in EEPROM)
-rgblight_sethsv(h, s, v);  
-// HSV color control - h is a value from 0..360 and s/v is a value from 0..255 (not stored in EEPROM)
-rgblight_sethsv_noeeprom(h, s, v);  
-
-// Sets the mode, if rgb animations are enabled (stored in eeprom)
-rgblight_mode(x);
-// Sets the mode, if rgb animations are enabled (not stored in eeprom)
-rgblight_mode_noeeprom(x);
-// MODE 1, solid color
-// MODE 2-5, breathing
-// MODE 6-8, rainbow mood
-// MODE 9-14, rainbow swirl
-// MODE 15-20, snake
-// MODE 21-23, knight
-// MODE 24, xmas
-// MODE 25-34, static rainbow
-
-rgblight_setrgb_at(r,g,b, LED);  // control a single LED.  0 <= LED < RGBLED_NUM
-rgblight_sethsv_at(h,s,v, LED);  // control a single LED.  0 <= LED < RGBLED_NUM
-```
-You can find a list of predefined colors at [`quantum/rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Free to add to this list!
-
-## RGB Lighting Keycodes
-
-These control the RGB Lighting functionality.
+## Keycodes
 
 |Key                |Aliases   |Description                                                         |
 |-------------------|----------|--------------------------------------------------------------------|
@@ -146,25 +61,109 @@ These control the RGB Lighting functionality.
 |`RGB_MODE_KNIGHT`  |`RGB_M_K` |"Knight Rider" animation mode                                       |
 |`RGB_MODE_XMAS`    |`RGB_M_X` |Christmas animation mode                                            |
 |`RGB_MODE_GRADIENT`|`RGB_M_G` |Static gradient animation mode                                      |
-|`RGB_MODE_RGBTEST `|`RGB_M_T` |Red,Green,Blue test animation mode                                  |
+|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode                                |
 
-note: for backwards compatibility, `RGB_SMOD` is an alias for `RGB_MOD`.
+## Configuration
 
-## Hardware Modification
+Your RGB lighting can be configured by placing these `#define`s in your `config.h`:
+
+|Define               |Default      |Description                                                                  |
+|---------------------|-------------|-----------------------------------------------------------------------------|
+|`RGBLIGHT_HUE_STEP`  |`10`         |The number of steps to cycle through the hue by                              |
+|`RGBLIGHT_SAT_STEP`  |`17`         |The number of steps to increment the saturation by                           |
+|`RGBLIGHT_VAL_STEP`  |`17`         |The number of steps to increment the brightness by                           |
+|`RGBLIGHT_LIMIT_VAL` |`255`        |The maximum brightness level                                                 |
+|`RGBLIGHT_SLEEP`     |*Not defined*|If defined, the RGB lighting will be switched off when the host goes to sleep|
+
+## Animations
+
+
+Not only can this lighting be whatever color you want,
+if `RGBLIGHT_EFFECT_xxxx` or `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal:
+
+|Mode number symbol           |Additional number  |Description                            |
+|-----------------------------|-------------------|---------------------------------------|
+|`RGBLIGHT_MODE_STATIC_LIGHT` | *None*            |Solid color (this mode is always enabled) |
+|`RGBLIGHT_MODE_BREATHING`    | 0,1,2,3           |Solid color breathing                  |
+|`RGBLIGHT_MODE_RAINBOW_MOOD` | 0,1,2             |Cycling rainbow                        |
+|`RGBLIGHT_MODE_RAINBOW_SWIRL`| 0,1,2,3,4,5       |Swirling rainbow                       |
+|`RGBLIGHT_MODE_SNAKE`        | 0,1,2,3,4,5       |Snake                                  |
+|`RGBLIGHT_MODE_KNIGHT`       | 0,1,2             |Knight                                 |
+|`RGBLIGHT_MODE_CHRISTMAS`    | *None*            |Christmas                              |
+|`RGBLIGHT_MODE_STATIC_GRADIENT`| 0,1,..,9        |Static gradient                        |
+|`RGBLIGHT_MODE_RGB_TEST`     | *None*            |RGB Test                               |
+|`RGBLIGHT_MODE_ALTERNATING`  | *None*            |Alternating                            |
+
+Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration.
+
+Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight.h` there is a contrast table between the old mode number and the current symbol.
+
+The following options can be used to tweak the various animations:
+
+|Define                              |Default      |Description                                                                          |
+|------------------------------------|-------------|-------------------------------------------------------------------------------------|
+|`RGBLIGHT_EFFECT_BREATHING`         |*Not defined*|If defined, enable breathing animation mode.                                         |
+|`RGBLIGHT_EFFECT_RAINBOW_MOOD`      |*Not defined*|If defined, enable rainbow mood animation mode.                                      |
+|`RGBLIGHT_EFFECT_RAINBOW_SWIRL`     |*Not defined*|If defined, enable rainbow swirl animation mode.                                     |
+|`RGBLIGHT_EFFECT_SNAKE`             |*Not defined*|If defined, enable snake animation mode.                                             |
+|`RGBLIGHT_EFFECT_KNIGHT`            |*Not defined*|If defined, enable knight animation mode.                                            |
+|`RGBLIGHT_EFFECT_CHRISTMAS`         |*Not defined*|If defined, enable christmas animation mode.                                         |
+|`RGBLIGHT_EFFECT_STATIC_GRADIENT`   |*Not defined*|If defined, enable static gradient mode.                                             |
+|`RGBLIGHT_EFFECT_RGB_TEST`          |*Not defined*|If defined, enable RGB test animation mode.                                          |
+|`RGBLIGHT_EFFECT_ALTERNATING`       |*Not defined*|If defined, enable alternating animation mode.                                       |
+|`RGBLIGHT_ANIMATIONS`               |*Not defined*|If defined, enables all additional animation modes                                   |
+|`RGBLIGHT_EFFECT_BREATHE_CENTER`    |`1.85`       |Used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 |
+|`RGBLIGHT_EFFECT_BREATHE_MAX`       |`255`        |The maximum brightness for the breathing mode. Valid values are 1 to 255             |
+|`RGBLIGHT_EFFECT_SNAKE_LENGTH`      |`4`          |The number of LEDs to light up for the "Snake" animation                             |
+|`RGBLIGHT_EFFECT_KNIGHT_LENGTH`     |`3`          |The number of LEDs to light up for the "Knight" animation                            |
+|`RGBLIGHT_EFFECT_KNIGHT_OFFSET`     |`0`          |The number of LEDs to start the "Knight" animation from the start of the strip by    |
+|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM`    |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel                             |
+|`RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL`|`1000`       |How long to wait between light changes for the "Christmas" animation, in milliseconds|
+|`RGBLIGHT_EFFECT_CHRISTMAS_STEP`    |`2`          |The number of LEDs to group the red/green colors by for the "Christmas" animation    |
+|`RGBLIGHT_RAINBOW_SWIRL_RANGE`      |`360`        |Range adjustment for the rainbow swirl effect to get different swirls                |
+
+You can also modify the speeds that the different modes animate at:
 
-![Planck with RGB Underglow](https://raw.githubusercontent.com/qmk/qmk_firmware/3774a7fcdab5544fc787f4c200be05fcd417e31f/keyboards/planck/keymaps/yang/planck-with-rgb-underglow.jpg)
+```c
+// How long (in milliseconds) to wait between animation steps for each of the "Solid color breathing" animations
+const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
 
-Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY).
+// How long (in milliseconds) to wait between animation steps for each of the "Cycling rainbow" animations
+const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
 
-For this mod, you need an unused pin wiring to DI of WS2812 strip. After wiring the VCC, GND, and DI, you can enable the underglow in your Makefile.
+// How long (in milliseconds) to wait between animation steps for each of the "Swirling rainbow" animations
+const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
 
-    RGBLIGHT_ENABLE = yes
+// How long (in milliseconds) to wait between animation steps for each of the "Snake" animations
+const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
 
-In order to use the underglow animation functions, you need to have `#define RGBLIGHT_ANIMATIONS` in your `config.h`.
+// How long (in milliseconds) to wait between animation steps for each of the "Knight" animations
+const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
 
-Please add the following options into your config.h, and set them up according your hardware configuration. These settings are for the `F4` pin by default:
+// These control which hues are selected for each of the "Static gradient" modes
+const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
+```
 
-    #define RGB_DI_PIN F4     // The pin your RGB strip is wired to
-    #define RGBLED_NUM 14     // Number of LEDs
+## Functions
+
+If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include:
+
+|Function                           |Description                                                                                                                                                            |
+|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|`rgblight_enable()`                |Turn LEDs on, based on their previous state                                                                                                                            |
+|`rgblight_enable_noeeprom()`       |Turn LEDs on, based on their previous state (not written to EEPROM)                                                                                                    |
+|`rgblight_disable()`               |Turn LEDs off                                                                                                                                                          |
+|`rgblight_disable_noeeprom()`      |Turn LEDs off (not written to EEPROM)                                                                                                                                  |
+|`rgblight_mode(x)`                 |Set the mode, if RGB animations are enabled                                                                                                                            |
+|`rgblight_mode_noeeprom(x)`        |Set the mode, if RGB animations are enabled (not written to EEPROM)                                                                                                    |
+|`rgblight_setrgb(r, g, b)`         |Set all LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM)                                                                    |
+|`rgblight_setrgb_at(r, g, b, led)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM)                       |
+|`rgblight_sethsv(h, s, v)`         |Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255                                                                   |
+|`rgblight_sethsv_noeeprom(h, s, v)`|Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255 (not written to EEPROM)                                           |
+|`rgblight_sethsv_at(h, s, v, led)` |Set a single LED to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255, and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM)|
+
+Additionally, [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h) defines several predefined shortcuts for various colors. Feel free to add to this list!
+
+## Hardware Modification
 
-You'll need to edit `RGB_DI_PIN` to the pin you have your `DI` on your RGB strip wired to.
+If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins.

+ 0 - 24
docs/feature_space_cadet.md

@@ -1,24 +0,0 @@
-## Space Cadet Shift: The Future, Built In
-
-Steve Losh [described](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) the Space Cadet Shift quite well. Essentially, you hit the left Shift on its own, and you get an opening parenthesis; hit the right Shift on its own, and you get the closing one. When hit with other keys, the Shift key keeps working as it always does. Yes, it's as cool as it sounds.
-
-To use it, use `KC_LSPO` (Left Shift, Parenthesis Open) for your left Shift on your keymap, and `KC_RSPC` (Right Shift, Parenthesis Close) for your right Shift.
-
-It's defaulted to work on US keyboards, but if your layout uses different keys for parenthesis, you can define those in your `config.h` like this:
-
-    #define LSPO_KEY KC_9
-    #define RSPC_KEY KC_0
-
-You can also choose between different rollover behaviors of the shift keys by defining:
-
-    #define DISABLE_SPACE_CADET_ROLLOVER
-
-in your `config.h`. Disabling rollover allows you to use the opposite shift key to cancel the space cadet state in the event of an erroneous press instead of emitting a pair of parentheses when the keys are released.
-
-The only other thing you're going to want to do is create a `Makefile` in your keymap directory and set the following:
-
-```
-COMMAND_ENABLE   = no  # Commands for debug and configuration
-```
-
-This is just to keep the keyboard from going into command mode when you hold both Shift keys at the same time.

+ 33 - 0
docs/feature_space_cadet_shift.md

@@ -0,0 +1,33 @@
+# Space Cadet Shift: The Future, Built In
+
+Steve Losh described the [Space Cadet Shift](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) quite well. Essentially, when you tap Left Shift on its own, you get an opening parenthesis; tap Right Shift on its own and you get the closing one. When held, the Shift keys function as normal. Yes, it's as cool as it sounds.
+
+## Usage
+
+Replace the Left Shift key in your keymap with `KC_LSPO` (Left Shift, Parenthesis Open), and Right Shift with `KC_RSPC` (Right Shift, Parenthesis Close).
+
+## Keycodes
+
+|Keycode  |Description                           |
+|---------|--------------------------------------|
+|`KC_LSPO`|Left Shift when held, `(` when tapped |
+|`KC_RSPC`|Right Shift when held, `)` when tapped|
+
+## Caveats
+
+Space Cadet's functionality can conflict with the default Command functionality when both Shift keys are held at the same time. Make sure that Command is disabled in your `rules.mk` with:
+
+```make
+COMMAND_ENABLE = no
+```
+
+## Configuration
+
+By default Space Cadet assumes a US ANSI layout, but if your layout uses different keys for parentheses, you can redefine them in your `config.h`.
+You can also disable the rollover, allowing you to use the opposite Shift key to cancel the Space Cadet state in the event of an erroneous press, instead of emitting a pair of parentheses when the keys are released.
+
+|Define                        |Default      |Description                                                 |
+|------------------------------|-------------|------------------------------------------------------------|
+|`LSPO_KEY`                    |`KC_9`       |The keycode to send when Left Shift is tapped               |
+|`RSPC_KEY`                    |`KC_0`       |The keycode to send when Right Shift is tapped              |
+|`DISABLE_SPACE_CADET_ROLLOVER`|*Not defined*|If defined, use the opposite Shift key to cancel Space Cadet|

+ 31 - 0
docs/feature_space_cadet_shift_enter.md

@@ -0,0 +1,31 @@
+# Space Cadet Shift Enter
+
+Based on the [Space Cadet Shift](feature_space_cadet_shift.md) feature. Tap the Shift key on its own, and it behaves like Enter. When held, the Shift functions as normal.
+
+## Usage
+
+Replace any Shift key in your keymap with `KC_SFTENT` (Shift, Enter), and you're done.
+
+## Keycodes
+
+|Keycode    |Description                             |
+|-----------|----------------------------------------|
+|`KC_SFTENT`|Right Shift when held, Enter when tapped|
+
+## Caveats
+
+As with Space Cadet Shift, this feature may conflict with Command, so it should be disabled in your `rules.mk` with:
+
+```make
+COMMAND_ENABLE = no
+```
+
+This feature also uses the same timers as Space Cadet Shift, so using them in tandem may produce strange results.
+
+## Configuration
+
+By default Space Cadet assumes a US ANSI layout, but if you'd like to use a different key for Enter, you can redefine it in your `config.h`:
+
+|Define      |Default |Description                                     |
+|------------|--------|------------------------------------------------|
+|`SFTENT_KEY`|`KC_ENT`|The keycode to send when the Shift key is tapped|

+ 0 - 26
docs/feature_space_shift_cadet.md

@@ -1,26 +0,0 @@
-## Space Cadet Shift Enter: The future, built in
-
-Based on the Space Cadet Shift by Steve Losh [described](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/) 
-Essentially, you hit the Shift on its own, and it acts as the enter key. When hit with other keys, the Shift key keeps working as it always does. Yes, it's as cool as it sounds. This solution works better than using a macro since the timers defined in quantum allow us to tell when another key is pressed, rather than just having a janky timer than results in accidental endlines. 
-
-To use it, use `KC_SFTENT` (Shift, Enter) for any Shift on your keymap.
-
-It's defaulted to work on US keyboards, but if you'd like to use a different key for Enter, you can define those in your `config.h` like this:
-
-    #define SFTENT_KEY KC_ENT
-
-
-The only other thing you're going to want to do is create a `rules.mk` in your keymap directory and set the following:
-
-```
-COMMAND_ENABLE   = no  # Commands for debug and configuration
-```
-
-This is just to keep the keyboard from going into command mode when you hold both Shift keys at the same time.
-
-
-
-
-
-PLEASE NOTE: this feature uses the same timers as the Space Cadet Shift feature, so using them in tandem may produce unwanted results. 
-

+ 4 - 4
docs/feature_swap_hands.md

@@ -22,9 +22,9 @@ Note that the array indices are reversed same as the matrix and the values are o
 |Key        |Description                                                              |
 |-----------|-------------------------------------------------------------------------|
 |`SH_T(key)`|Sends `key` with a tap; momentary swap when held.                        |
-|`SW_ON`    |Turns on swapping and leaves it on.                                      |
-|`SW_OFF`   |Turn off swapping and leaves it off. Good for returning to a known state.|
-|`SW_MON`   |Swaps hands when pressed, returns to normal when released (momentary).   |
-|`SW_MOFF`  |Momentarily turns off swap.                                              |
+|`SH_ON`    |Turns on swapping and leaves it on.                                      |
+|`SH_OFF`   |Turn off swapping and leaves it off. Good for returning to a known state.|
+|`SH_MON`   |Swaps hands when pressed, returns to normal when released (momentary).   |
+|`SH_MOFF`  |Momentarily turns off swap.                                              |
 |`SH_TG`    |Toggles swap on and off with every key press.                            |
 |`SH_TT`    |Toggles with a tap; momentary when held.                                 |

+ 10 - 10
docs/feature_tap_dance.md

@@ -26,6 +26,8 @@ This array specifies what actions shall be taken when a tap-dance key is in acti
 
 The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
 
+!> Keep in mind that only [basic keycodes](keycodes_basic.md) are supported here. Custom keycodes are not supported.
+
 And that's the bulk of it!
 
 And now, on to the explanation of how it works!
@@ -196,22 +198,20 @@ SRC += your_name.c
 Pretty simple. It is a nice way to keep some rules common on all your keymaps.
 
 
-### In `/qmk_firmware/users/<your_name>/<you_name>.h`
+### In `/qmk_firmware/users/<your_name>/<your_name>.h`
 
 You will need a few things in this file:
 
 ```c
-#ifndef YOUR_NAME
-#define YOUR_NAME
+#pragma once
 
 #include "quantum.h"
 #include "process_keycode/process_tap_dance.h"
 
-
 typedef struct {
   bool is_press_action;
   int state;
-} xtap;
+} tap;
 
 enum {
   SINGLE_TAP = 1,
@@ -225,9 +225,9 @@ enum {
 
 //Tap dance enums
 enum {
-    CTL_X = 0,
-    SOME_OTHER_DANCE
-}
+  X_CTL = 0,
+  SOME_OTHER_DANCE
+};
 
 int cur_dance (qk_tap_dance_state_t *state);
 
@@ -241,7 +241,7 @@ void x_reset (qk_tap_dance_state_t *state, void *user_data);
 And then in your user's `.c` file you implement the functions above:
 
 ```c
-#include "gordon.h"
+#include "<your_name>.h"
 #include "quantum.h"
 #include "action.h"
 #include "process_keycode/process_tap_dance.h"
@@ -335,4 +335,4 @@ qk_tap_dance_action_t tap_dance_actions[] = {
 };
 ```
 
-And then simply use TD(X_CTL) anywhere in your keymap.
+And then simply use `TD(X_CTL)` anywhere in your keymap after including `<your_name>.h`.

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 94 - 18
docs/feature_unicode.md


+ 138 - 36
docs/feature_userspace.md

@@ -5,15 +5,12 @@ If you use more than one keyboard with a similar keymap, you might see the benef
 * `/users/<name>/` (added to the path automatically)
   * `readme.md` (optional, recommended)
   * `rules.mk` (included automatically)
+  * `config.h` (included automatically)
   * `<name>.h` (optional)
   * `<name>.c` (optional)
-  * `config.h` (optional)
+  * `cool_rgb_stuff.c` (optional)
+  * `cool_rgb_stuff.h` (optional)
 
-`<name>.c` will need to be added to the SRC in `rules.mk` like this:
-
-    SRC += <name>.c
-
-Additional files may be added in the same way - it's recommended you have one named `<name>`.c/.h though.
 
 All this only happens when you build a keymap named `<name>`, like this:
 
@@ -23,68 +20,179 @@ For example,
 
     make planck:jack
 
-Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`.
+Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`.  
+
+!> This `name` can be [overridden](#override-default-userspace), if needed.  
+
+## `Rules.mk`
+
+The `rules.mk` is one of the two files that gets processed automatically.  This is how you add additional source files (such as  `<name>.c`) will be added when compiling.
+
+It's highly recommended that you use `<name>.c` as the default source file to be added. And to add it, you need to add it the SRC in `rules.mk` like this:
+
+    SRC += <name>.c
+
+Additional files may be added in the same way - it's recommended you have one named `<name>`.c/.h to start off with, though. 
+
+The `/users/<name>/rules.mk` file will be included in the build _after_ the `rules.mk` from your keymap. This allows you to have features in your userspace `rules.mk` that depend on individual QMK features that may or may not be available on a specific keyboard. 
+
+For example, if you have RGB control features shared between all your keyboards that support RGB lighting, you can add support for that if the RGBLIGHT feature is enabled:
+```make
+ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
+  # Include my fancy rgb functions source here
+  SRC += cool_rgb_stuff.c
+endif
+```
+
+Alternatively, you can `define RGB_ENABLE` in your keymap's `rules.mk` and then check for the variable in your userspace's `rules.mk` like this:
+```make
+ifdef RGB_ENABLE
+  # Include my fancy rgb functions source here
+  SRC += cool_rgb_stuff.c
+endif
+```
+
+### Override default userspace
+
+By default the userspace used will be the same as the keymap name. In some situations this isn't desirable. For instance, if you use the [layout](feature_layouts.md) feature you can't use the same name for different keymaps (e.g. ANSI and ISO). You can name your layouts `mylayout-ansi` and `mylayout-iso` and add the following line to your layout's `rules.mk`:
+
+```
+USER_NAME := mylayout
+```
+
+This is also useful if you have multiple different keyboards with different features physically present on the board (such as one with RGB Lights, and one with Audio, or different number of LEDs, or connected to a different PIN on the controller).
+
+## Configuration Options (`config.h`)
 
 Additionally, `config.h` here will be processed like the same file in your keymap folder.  This is handled separately from the `<name>.h` file.
 
 The reason for this, is that `<name>.h` won't be added in time to add settings (such as `#define TAPPING_TERM 100`), and including the `<name.h>` file in any `config.h` files will result in compile issues.
 
-So you should use the `config.h` for QMK settings, and the `<name>.h` file for user or keymap specific settings.
+!>You should use the `config.h` for [configuration options](config_options.md), and the `<name>.h` file for user or keymap specific settings (such as the enum for layer or keycodes)
 
-## Readme
+
+## Readme (`readme.md`)
 
 Please include authorship (your name, github username, email), and optionally [a license that's GPL compatible](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses).
 
-## `Config.h`
+You can use this as a template: 
+```
+Copyright <year> <name> <email> @<github_username>
+
+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/>.
+```
+
+You'd want to replace the year, name, email and github username with your info. 
+
+Additionally, this is a good place to document your code, if you wish to share it with others. 
+
+# Examples
+
+For a brief example, checkout [`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna).  
+For a more complicated example, checkout [`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna)'s userspace.
+
+
+## Customized Functions
+
+QMK has a bunch of [functions](custom_quantum_functions.md) that have [`_quantum`, `_kb`, and `_user` versions](custom_quantum_functions.md#a-word-on-core-vs-keyboards-vs-keymap) that you can use.  You will pretty much always want to use the user version of these functions.  But the problem is that if you use them in your userspace, then you don't have a version that you can use in your keymap. 
+
+However, you can actually add support for keymap version, so that you can use it in both your userspace and your keymap! 
 
-If you do add a `config,h` file, you want to make sure that it only gets processed once.  So you may want to start off with something like this:
 
+For instance, lets looks at the `layer_state_set_user` function.  Lets enable the [Tri Layer State](ref_functions.md#olkb-tri-layers) functionalitly to all of our boards, and then still have your `keymap.c` still able to use this functionality. 
+
+In your `<name.c>` file, you'd want to add this: 
 ```c
-#ifndef USERSPACE_CONFIG_H
-#define USERSPACE_CONFIG_H
+__attribute__ ((weak))
+uint32_t layer_state_set_keymap (uint32_t state) {
+  return state;
+}
+
+uint32_t layer_state_set_user (uint32_t state) {
+  state = update_tri_layer_state(state, 2, 3, 5);
+  return layer_state_set_keymap (state);
+}
+```
+The `__attribute__ ((weak))` part tells the compiler that this is a placeholder function that can then be replaced by a version in your `keymap.c`.  That way, you don't need to add it to your `keymap.c`, but if you do, you won't get any conflicts because the function is the same name. 
+
+The `_keymap` part here doesn't matter, it just needs to be something other than `_quantum`, `_kb`, or `_user`, since those are already in use. So you could use `layer_state_set_mine`, `layer_state_set_fn`, or anything else.
+
+You can see a list of this and other common functions in [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) in [`users/drashna`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna).
 
-// Put normal config.h settings here:
+## Custom Features
 
-#endif // !USERSPACE_CONFIG_H
+Since the Userspace feature can support a staggering number of boards, you may have boards that you want to enable certain functionality for, but not for others. And you can actually create "features" that you can enable or disable in your own userspace.  
+
+For instance, if you wanted to have a bunch of macros available, but only on certain boards (to save space), you could "hide" them being a `#ifdef MACROS_ENABLED`, and then enable it per board.  To do this, add this to your rules.mk
+```make
+ifeq ($(strip $(MACROS_ENABLED)), yes)
+    OPT_DEFS += -DMACROS_ENABLED
+endif
 ```
+The `OPT_DEFS` setting causes `MACROS_ENABLED` to be defined for your keyboards (note the `-D` in front of the name), and you could use `#ifdef MACROS_ENABLED` to check the status in your c/h files, and handle that code based on that. 
 
-You can use any option hre that you could use in your keymap's `config.h` file. You can find a list of vales [here](config_options.md).
+Then you add `MACROS_ENABLED = yes` to the `rules.mk` for you keymap to enable this feature and the code in your userspace.
 
-## Example
+And in your `process_record_user` function, you'd do something like this: 
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+#ifdef MACROS_ENABLED
+  case MACRO1:
+    if (!record->event.pressed) {
+      SEND_STRING("This is macro 1!");
+    }
+    break;
+  case MACRO2:
+    if (!record->event.pressed) {
+      SEND_STRING("This is macro 2!");
+    }
+    break;
+#endif
+  }
+  return true;
+}
+```
 
-For a brief example, checkout `/users/_example/` , or for a more detailed examples check out [`template.h`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.h) and [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) in `/users/drashna/` .
 
-### Consolidated Macros
+## Consolidated Macros
 
-If you wanted to consolidate macros and other functions into your userspace for all of your keymaps, you can do that.  The issue is that you then cannot call any function defined in your userspace, or it gets complicated.  To better handle this, you can call the functions here and create new functions to use in individual keymaps.
+If you wanted to consolidate macros and other functions into your userspace for all of your keymaps, you can do that.  This builds upon the [Customized Functions](#customized-functions) example above. This lets you maintain a bunch of macros that are shared between the different keyboards, and allow for keyboard specific macros, too. 
 
 First, you'd want to go through all of your `keymap.c` files and replace `process_record_user` with `process_record_keymap` instead.   This way, you can still use keyboard specific codes on those boards, and use your custom "global" keycodes as well.   You'll also want to replace `SAFE_RANGE` with `NEW_SAFE_RANGE` so that you wont have any overlapping keycodes
 
 Then add `#include <name.h>` to all of your keymap.c files.  This allows you to use these new keycodes without having to redefine them in each keymap.
 
 Once you've done that, you'll want to set the keycode definitions that you need to the `<name>.h`  file. For instance:
-```
-#ifndef USERSPACE
-#define USERSPACE
+```c
+#pragma once
 
 #include "quantum.h"
+#include "action.h"
+#include "version.h"
 
 // Define all of
 enum custom_keycodes {
   KC_MAKE = SAFE_RANGE,
   NEW_SAFE_RANGE  //use "NEW_SAFE_RANGE" for keymap specific codes
 };
-
-#endif
 ```
 
 Now you want to create the `<name>.c` file, and add this content to it:
 
-```
+```c
 #include "<name>.h"
-#include "quantum.h"
-#include "action.h"
-#include "version.h"
 
 __attribute__ ((weak))
 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
@@ -112,14 +220,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 }
 ```
 
-This will add a new `KC_MAKE`  keycode that can be used in any of your keymaps.  And this keycode will output `make <keyboard>:<keymap">`, making frequent compiling easier.  And this will work with any keyboard and any keymap as it will output the current boards info, so that you don't have to type this out every time.
+This will add a new `KC_MAKE` keycode that can be used in any of your keymaps.  And this keycode will output `make <keyboard>:<keymap>`, making frequent compiling easier.  And this will work with any keyboard and any keymap as it will output the current boards info, so that you don't have to type this out every time.
 
 Additionally, this should flash the newly compiled firmware automatically, using the correct utility, based on the bootloader settings (or default to just generating the HEX file). However, it should be noted that this may not work on all systems. AVRDUDE doesn't work on WSL, namely (and will dump the HEX in the ".build" folder instead).
 
-## Override default userspace
 
-By default the userspace used will be the same as the keymap name. In some situations this isn't desirable. For instance, if you use the [layout](feature_layouts.md) feature you can't use the same name for different keymaps (e.g. ANSI and ISO). You can name your layouts `mylayout-ansi` and `mylayout-iso` and add the following line to your layout's `rules.mk`:
-
-```
-USER_NAME := mylayout
-```

+ 6 - 2
docs/features.md

@@ -3,23 +3,27 @@
 QMK has a staggering number of features for building your keyboard. It can take some time to understand all of them and determine which one will achieve your goal.
 
 
-* [Advanced Keycodes](feature_advanced_keycodes.md) - Change layers, type shifted keys, and more. Go beyond typing simple characters.
+* [Advanced Keycodes](feature_advanced_keycodes.md) - Change layers, dual-action keys, and more. Go beyond typing simple characters.
 * [Audio](feature_audio.md) - Connect a speaker to your keyboard for audio feedback, midi support, and music mode.
 * [Auto Shift](feature_auto_shift.md) - Tap for the normal key, hold slightly longer for its shifted state.
 * [Backlight](feature_backlight.md) - LED lighting support for your keyboard.
 * [Bootmagic](feature_bootmagic.md) - Adjust the behavior of your keyboard using hotkeys.
+* [Combos](feature_combo.md) - Custom actions for multiple key holds.
+* [Command](feature_command.md) - Runtime version of bootmagic (Formerly known as "Magic").
 * [Dynamic Macros](feature_dynamic_macros.md) - Record and playback macros from the keyboard itself.
+* [Grave Escape](feature_grave_esc.md) - Lets you use a single key for Esc and Grave. 
 * [HD44780 LCD Display](feature_hd44780.md) - Support for LCD character displays using the HD44780 standard.
 * [Key Lock](feature_key_lock.md) - Lock a key in the "down" state.
 * [Layouts](feature_layouts.md) - Use one keymap with any keyboard that supports your layout.
 * [Leader Key](feature_leader_key.md) - Tap the leader key followed by a sequence to trigger custom behavior.
 * [Macros](feature_macros.md) - Send multiple key presses when pressing only one physical key.
 * [Mouse keys](feature_mouse_keys.md) - Control your mouse pointer from your keyboard.
+* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys) - Sticky Keys, lets hit a key rather than holding it.
 * [Pointing Device](feature_pointing_device.md) - Framework for connecting your custom pointing device to your keyboard.
 * [PS2 Mouse](feature_ps2_mouse.md) - Driver for connecting a PS/2 mouse directly to your keyboard.
 * [RGB Light](feature_rgblight.md) - RGB lighting for your keyboard.
 * [RGB Matrix](feature_rgb_matrix.md) - RGB Matrix lights for per key lighting.
-* [Space Cadet](feature_space_cadet.md) - Use your left/right shift keys to type parenthesis and brackets.
+* [Space Cadet](feature_space_cadet_shift.md) - Use your left/right shift keys to type parenthesis and brackets.
 * [Stenography](feature_stenography.md) - Put your keyboard into Plover mode for stenography use.
 * [Swap Hands](feature_swap_hands.md) - Mirror your keyboard for one handed usage.
 * [Tap Dance](feature_tap_dance.md) - Make a single key do as many things as you want.

+ 34 - 5
docs/flashing.md

@@ -2,7 +2,7 @@
 
 There are quite a few different types of bootloaders that keyboards use, and just about all of the use a different flashing method. Luckily, projects like the [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) aim to be compatible with all the different types without having to think about it much, but this article will describe the different types of bootloaders, and available methods for flashing them.
 
-If you have a bootloader selected with the `BOOTLOADER` variable in your `rules.mk`, QMK will automatically calculate if your .hex file is the right size to be flashed to the device, and output the total size it bytes (along with the max). To run this process manually, compile with the target `check-size`, eg `make planck/rev4:default:check-size`.
+If you have a bootloader selected with the `BOOTLOADER` variable in your `rules.mk`, QMK will automatically calculate if your .hex file is the right size to be flashed to the device, and output the total size in bytes (along with the max). To run this process manually, compile with the target `check-size`, eg `make planck/rev4:default:check-size`.
 
 ## DFU
 
@@ -71,13 +71,19 @@ Flashing sequence:
 
 1. Press the `RESET` keycode, or short RST to GND quickly (you only have 7 seconds to flash once it enters)
 2. Wait for the OS to detect the device
-4. Flash a .hex file
-5. Wait for the device to reset automatically
+3. Flash a .hex file
+4. Wait for the device to reset automatically
 
 or
 
     make <keyboard>:<keymap>:avrdude
 
+or if you want to flash multiple boards, use the following command
+
+    make <keyboard>:<keymap>:avrdude-loop
+
+When you're done flashing boards, you'll need to hit Ctrl + C or whatever the correct keystroke is for your operating system to break the loop.
+
 ## Halfkay
 
 Halfkay is a super-slim protocol developed by PJRC that uses HID, and come on all Teensys (namely the 2.0).
@@ -100,5 +106,28 @@ Flashing sequence:
 
 1. Press the `RESET` keycode, or short RST to GND quickly (you only have 7 seconds to flash once it enters)
 2. Wait for the OS to detect the device
-4. Flash a .hex file
-5. Reset the device into application mode (may be done automatically)
+3. Flash a .hex file
+4. Reset the device into application mode (may be done automatically)
+
+## STM32
+
+All STM32 chips come preloaded with a factory bootloader that cannot be modified nor deleted. Some STM32 chips have bootloaders that do not come with USB programming (e.g. STM32F103) but the process is still the same.
+
+At the moment, no `BOOTLOADER` variable is needed on `rules.mk` for STM32.
+
+Compatible flashers:
+
+* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI)
+* [dfu-util](https://github.com/Stefan-Schmidt/dfu-util) / `:dfu-util` (recommended command line)
+
+Flashing sequence:
+
+1. Enter the bootloader using any of the following methods:
+    * Tap the `RESET` keycode (may not work on STM32F042 devices)
+    * If a reset circuit is present, tap the RESET button
+    * Otherwise, you need to bridge BOOT0 to VCC (via BOOT0 button or bridge), short RESET to GND (via RESET button or bridge), and then let go of the BOOT0 bridge
+2. Wait for the OS to detect the device
+3. Flash a .bin file
+    * You will receive a warning about the DFU signature; Just ignore it
+4. Reset the device into application mode (may be done automatically)
+    * If you are building from command line (e.g. `make planck/rev6:default:dfu-util`), make sure that `:leave` is passed to the `DFU_ARGS` variable inside your `rules.mk` (e.g. `DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave`) so that your device resets after flashing

+ 6 - 4
docs/getting_started_build_tools.md

@@ -8,7 +8,7 @@ Note: If it is your first time here, Check out the "Complete Newbs guide" instea
 
 ## Linux
 
-To ensure you are always up to date, you can just run `sudo util/install_dependencies.sh`. That should always install all the dependencies needed. **This will run `apt-get upgrade`.**
+To ensure you are always up to date, you can just run `sudo util/qmk_install.sh`. That should always install all the dependencies needed. **This will run `apt-get upgrade`.**
 
 You can also install things manually, but this documentation might not be always up to date with all requirements.
 
@@ -57,11 +57,13 @@ If you're using [homebrew,](http://brew.sh/) you can use the following commands:
     brew tap PX4/homebrew-px4
     brew update
     brew install avr-gcc@7
+    brew link --force avr-gcc@7
     brew install dfu-programmer
+    brew install dfu-util
     brew install gcc-arm-none-eabi
     brew install avrdude
 
-This is the recommended method. If you don't have homebrew, [install it!](http://brew.sh/) It's very much worth it for anyone who works in the command line. Note that the `make` and `make install` portion during the homebrew installation of avr-libc can take over 20 minutes and exhibit high CPU usage.
+This is the recommended method. If you don't have homebrew, [install it!](http://brew.sh/) It's very much worth it for anyone who works in the command line. Note that the `make` and `make install` portion during the homebrew installation of `avr-gcc@7` can take over 20 minutes and exhibit high CPU usage.
 
 ## Windows with msys2 (recommended)
 
@@ -69,9 +71,9 @@ The best environment to use, for Windows Vista through any later version (tested
 
 * Install msys2 by downloading it and following the instructions here: http://www.msys2.org
 * Open the ``MSYS2 MingGW 64-bit`` shortcut
-* Navigate to your qmk checkout. For example, if it's in the root of your c drive:
+* Navigate to your QMK repository. For example, if it's in the root of your c drive:
  * `$ cd /c/qmk_firmware`
-* Run `util/msys2_install.sh` and follow the prompts
+* Run `util/qmk_install.sh` and follow the prompts
 
 ## Windows 10 (deprecated)
 These are the old instructions for Windows 10. We recommend you use [MSYS2 as outlined above](#windows-with-msys2-recommended).

+ 5 - 7
docs/getting_started_github.md

@@ -8,7 +8,7 @@ Start on the [QMK Github page](https://github.com/qmk/qmk_firmware), and you'll
 
 ![Fork on Github](http://i.imgur.com/8Toomz4.jpg)
 
-If you're apart of an organization, you'll need to choose which account to fork it to. In most circumstances, you'll want to fork it to your personal account. Once your fork is completed (sometimes this takes a little while), click the "Clone or Download" button:
+If you're a part of an organization, you'll need to choose which account to fork it to. In most circumstances, you'll want to fork it to your personal account. Once your fork is completed (sometimes this takes a little while), click the "Clone or Download" button:
 
 ![Download from Github](http://i.imgur.com/N1NYcSz.jpg)
 
@@ -19,8 +19,7 @@ And be sure to select "HTTPS", and select the link and copy it:
 From here, enter `git clone ` into the command line, and then paste your link:
 
 ```
-**[terminal]
-**[prompt you@computer]**[path ~]**[delimiter  $ ]**[command git clone https://github.com/whoeveryouare/qmk_firmware.git]
+user@computer:~$ git clone https://github.com/whoeveryouare/qmk_firmware.git
 Cloning into 'qmk_firmware'...
 remote: Counting objects: 46625, done.
 remote: Compressing objects: 100% (2/2), done.
@@ -33,13 +32,12 @@ Checking out files: 100% (2799/2799), done.
 You now have your QMK fork on your local machine, and you can add your keymap, compile it and flash it to your board. Once you're happy with your changes, you can add, commit, and push them to your fork like this:
 
 ```
-**[terminal]
-**[prompt you@computer]**[path ~/qmk_firmware]**[delimiter  $ ]**[command git add .]
-**[prompt you@computer]**[path ~/qmk_firmware]**[delimiter  $ ]**[command git commit -m "adding my keymap"]
+user@computer:~$ git add .
+user@computer:~$ git commit -m "adding my keymap"
 [master cccb1608] adding my keymap
  1 file changed, 1 insertion(+)
  create mode 100644 keyboards/planck/keymaps/mine/keymap.c
-**[prompt you@computer]**[path ~/qmk_firmware]**[delimiter  $ ]**[command git push]
+user@computer:~$ git push
 Counting objects: 1, done.
 Delta compression using up to 4 threads.
 Compressing objects: 100% (1/1), done.

+ 4 - 0
docs/getting_started_make_guide.md

@@ -133,6 +133,10 @@ This consumes about 5390 bytes.
 
 This enables [key lock](feature_key_lock.md). This consumes an additional 260 bytes.
 
+`SPLIT_KEYBOARD`
+
+This enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
+
 ## Customizing Makefile Options on a Per-Keymap Basis
 
 If your keymap directory has a file called `rules.mk` any options you set in that file will take precedence over other `rules.mk` options for your particular keyboard.

+ 21 - 23
docs/hardware_avr.md

@@ -8,7 +8,7 @@ If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_
 
 QMK has a number of features to simplify working with AVR keyboards. For most keyboards you don't have to write a single line of code. To get started run the `util/new_project.sh` script:
 
-```
+```bash
 $ util/new_project.sh my_awesome_keyboard
 ######################################################
 # /keyboards/my_awesome_keyboard project created. To start
@@ -30,7 +30,7 @@ This is where all the custom logic for your keyboard goes. Many keyboards do not
 
 This is the file you define your [Layout Macro(s)](feature_layouts.md) in. At minimum you should have a `#define LAYOUT` for your keyboard that looks something like this:
 
-```
+```c
 #define LAYOUT(          \
       k00, k01, k02,     \
       k10,   k11         \
@@ -57,7 +57,7 @@ At the top of the `config.h` you'll find USB related settings. These control how
 
 Do change the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` lines to accurately reflect your keyboard.
 
-```
+```c
 #define VENDOR_ID       0xFEED
 #define PRODUCT_ID      0x6060
 #define DEVICE_VER      0x0001
@@ -66,20 +66,20 @@ Do change the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` lines to accurately r
 #define DESCRIPTION     A custom keyboard
 ```
 
-?> Note: On Windows and macOS the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` fields will be displayed in the list of USB devices. On Linux these values will not be visible in `lsusb`, since Linux takes that information from the list published by the USB-IF.
+?> Note: On Windows and macOS the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` fields will be displayed in the list of USB devices. ?> On Linux these values will not be visible in lsusb by default, since Linux takes the information from the list maintained by [USB ID Repository](http://www.linux-usb.org/usb-ids.html) by default. lsusb will show the information reported by the device when executed with -v option. It is also present in kernel logs after plugging in the device.
 
 ### Keyboard Matrix Configuration
 
 The next section of the `config.h` file deals with your keyboard's matrix. The first thing you should set is the matrix's size. This is usually, but not always, the same number of rows and columns as the physical key arrangement.
 
-```
+```c
 #define MATRIX_ROWS 2
 #define MATRIX_COLS 3
 ```
 
 Once you've defined the size of your matrix you need to define which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins:
 
-```
+```c
 #define MATRIX_ROW_PINS { D0, D5 }
 #define MATRIX_COL_PINS { F1, F0, B0 }
 #define UNUSED_PINS
@@ -89,7 +89,7 @@ The number of `MATRIX_ROW_PINS` entries must be the same as the number you assig
 
 Finally, you can specify the direction your diodes point. This can be `COL2ROW`, `ROW2COL`, or `CUSTOM_MATRIX`.
 
-```
+```c
 #define DIODE_DIRECTION COL2ROW
 ```
 
@@ -97,16 +97,14 @@ Finally, you can specify the direction your diodes point. This can be `COL2ROW`,
 
 By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are using one of those you can simply enable it here. For more details see the [Backlight Documentation](feature_backlight.md).
 
-```
+```c
 #define BACKLIGHT_PIN B7
 #define BACKLIGHT_LEVELS 3
 #define BACKLIGHT_BREATHING
 #define BREATHING_PERIOD 6
 ```
 
-{% hint style='info' %}
-You can use backlighting on any pin you like, but you will have to do more work to support that. See the [Backlight Documentation](feature_backlight.md) for more details.
-{% endhint %}
+?> You can use backlighting on any pin you like, but you will have to do more work to support that. See the [Backlight Documentation](feature_backlight.md) for more details.
 
 ### Other Configuration Options
 
@@ -120,7 +118,7 @@ You use the `rules.mk` file to tell QMK what files to build and what features to
 
 These options tell the build system what CPU to build for. Be very careful if you change any of these settings, you can render your keyboard inoperable.
 
-```
+```make
 MCU = atmega32u4
 F_CPU = 16000000
 ARCH = AVR8
@@ -128,26 +126,26 @@ F_USB = $(F_CPU)
 OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
 ```
 
-### Bootloader Size
+### Bootloaders
 
-The bootloader is a special section of your MCU that allows you to upgrade the code stored on the MCU. Think of it like a Rescue Partition for your keyboard. If you are using a teensy 2.0, or a device like the Ergodox EZ that uses the teensy bootloader you should set this to `512`. Most other bootloaders should be set to `4096`, but `1024` and `2048` are other possible values you may encounter.
+The bootloader is a special section of your MCU that allows you to upgrade the code stored on the MCU. Think of it like a Rescue Partition for your keyboard. 
 
-#### Teensy 2.0 Bootloader Example
+#### Teensy Bootloader Example
 
-```
-OPT_DEFS += -DBOOTLOADER_SIZE=512
+```make
+BOOTLOADER = halfkay
 ```
 
-#### Teensy 2.0++ Bootloader Example
+#### Atmel DFU Loader Example
 
-```
-OPT_DEFS += -DBOOTLOADER_SIZE=1024
+```make
+BOOTLOADER = atmel-dfu
 ```
 
-#### Atmel DFU Loader Example
+#### Pro Micro Bootloader Example
 
-```
-OPT_DEFS += -DBOOTLOADER_SIZE=4096
+```make
+BOOTLOADER = caterina
 ```
 
 ### Build Options

+ 8 - 0
docs/hardware_drivers.md

@@ -25,3 +25,11 @@ You can make use of uGFX within QMK to drive character and graphic LCD's, LED ar
 ## WS2812 (AVR Only)
 
 Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page.
+
+## IS31FL3731
+
+Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.
+
+## IS31FL3733
+
+Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.

+ 7 - 7
docs/how_keyboards_work.md

@@ -27,17 +27,17 @@ This usually happens with a periodic scan of key presses. This speed often is li
 
 ## 2. What the Firmware Sends
 
-The [HID specification](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf) tells what a keyboard can actually send through USB to have a chance to be properly recognised. This includes a pre-defined list of scancodes which are simple numbers from `0x00` to `0xE7`. The firmware assigns a scancode to each key of the keyboard.
+The [HID specification](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) tells what a keyboard can actually send through USB to have a chance to be properly recognised. This includes a pre-defined list of scancodes which are simple numbers from `0x00` to `0xE7`. The firmware assigns a scancode to each key of the keyboard.
 
-The firmware does not send actually letters or characters, but only scancodes.
-Thus, by modifying the firmware, you only can modify what scancode is sent over
+The firmware does not send actual letters or characters, but only scancodes.
+Thus, by modifying the firmware, you can only modify what scancode is sent over
 USB for a given key.
 
 ## 3. What the Operating System Does
 
 Once the keycode reaches the operating system, a piece of software has to have
 it match an actual character thanks to a keyboard layout. For example, if your
-layout is set to QWERTY, a sample of the matching table is as follow:
+layout is set to QWERTY, a sample of the matching table is as follows:
 
 | keycode | character |
 |---------|-----------|
@@ -55,11 +55,11 @@ As the layout is generally fixed (unless you create your own), the firmware can
 
 ## List of Characters You Can Send
 
-Putting aside shortcuts, having a limited set of keycodes mapped to a limited layout means that **the list of characters you can assign to a given key only is the ones present in the layout**.
+Putting aside shortcuts, having a limited set of keycodes mapped to a limited layout means that **the list of characters you can assign to a given key are only the ones present in the layout**.
 
-For example, this means that if you have a QWERTY US layout, and you want to assign 1 key to produce `€` (euro currency symbol), you are unable to do so, because the QWERTY US layout does not have such mapping. You could fix that by using a QWERTY UK layout, or a QWERTY US International.
+For example, this means that if you have a QWERTY US layout, and you want to assign one key to produce `€` (euro currency symbol), you are unable to do so, because the QWERTY US layout does not have such mapping. You could fix that by using a QWERTY UK layout, or a QWERTY US International.
 
-You may wonder why a keyboard layout containing all of Unicode is not devised then? The limited number of keycode available through USB simply disallow such a thing.
+You may wonder why a keyboard layout containing all of Unicode is not devised then? The limited number of keycodes available through USB simply disallows such a thing.
 
 ## How to (Maybe) Enter Unicode Characters
 

+ 82 - 0
docs/i2c_driver.md

@@ -0,0 +1,82 @@
+# I2C Master Driver
+
+The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
+
+## Available functions
+
+|Function                                                                                                          |Description                                                                                                                                                                  |
+|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|`void i2c_init(void);`                                                                                            |Initializes the I2C driver. This function should be called once before any transaction is initiated.                                                                         |
+|`uint8_t i2c_start(uint8_t address);`                                                                             |Starts an I2C transaction. Address is the 7-bit slave address without the direction bit.                                                                                     |
+|`uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);`                        |Transmit data over I2C. Address is the 7-bit slave address without the direction. Returns status of transaction.                                                             |
+|`uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);`                         |Receive data over I2C. Address is the 7-bit slave address without the direction. Saves number of bytes specified by `length` in `data` array. Returns status of transaction. |
+|`uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);`       |Same as the `i2c_transmit` function but `regaddr` sets where in the slave the data will be written.                                                                          |
+|`uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);`        |Same as the `i2c_receive` function but `regaddr` sets from where in the slave the data will be read.                                                                         |
+|`uint8_t i2c_stop(uint16_t timeout);`                                                                             |Stops the I2C driver.                                                                                                                                                        |
+
+### Function Return
+
+All the above functions, except `void i2c_init(void);` return the following truth table:
+
+|Return Value   |Description                                        |
+|---------------|---------------------------------------------------|
+|0              |Operation executed successfully.                   |
+|-1             |Operation failed.                                  |
+|-2             |Operation timed out.                               |
+
+
+## AVR
+
+### Configuration
+
+The following defines can be used to configure the I2C master driver.
+
+|Variable          |Description                                        |Default|
+|------------------|---------------------------------------------------|-------|
+|`#F_SCL`          |Clock frequency in Hz                              |400KHz |
+|`#Prescaler`      |Divides master clock to aid in I2C clock selection |1      |
+
+AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required.
+
+## ARM
+
+For ARM the Chibios I2C HAL driver is under the hood.
+This section assumes an STM32 MCU.
+
+### Configuration
+
+The configuration for ARM MCUs can be quite complex as often there are multiple I2C drivers which can be assigned to a variety of ports.
+
+Firstly the `mcuconf.h` file must be setup to enable the necessary hardware drivers.
+
+|Variable                      |Description                                                                        |Default|
+|------------------------------|------------------------------------------------------------------------------------|-------|
+|`#STM32_I2C_USE_XXX`          |Enable/Disable the hardware driver XXX (each driver should be explicitly listed)    |FALSE  |
+|`#STM32_I2C_BUSY_TIMEOUT`     |Time in ms until the I2C command is aborted if no response is received              |50     |
+|`#STM32_I2C_XXX_IRQ_PRIORITY` |Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING)              |10     |
+|`#STM32_I2C_USE_DMA`          |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit  |TRUE   |
+|`#STM32_I2C_XXX_DMA_PRIORITY` |Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING)            |1      |
+
+Secondly, in the `halconf.h` file, `#define HAL_USE_I2C` must be set to `TRUE`. This allows ChibiOS to load its I2C driver.
+
+Lastly, we need to assign the correct GPIO pins depending on the I2C hardware driver we want to use.
+
+By default the I2C1 hardware driver is assumed to be used. If another hardware driver is used,  `#define I2C_DRIVER I2CDX` should be added to the `config.h` file with X being the number of hardware driver used. For example is I2C3 is enabled, the `config.h` file should contain `#define I2C_DRIVER I2CD3`. This aligns the QMK I2C driver with the Chibios I2C driver.
+
+STM32 MCUs allows a variety of pins to be configured as I2C pins depending on the hardware driver used. By default B6 and B7 are set to I2C.
+
+This can be changed by declaring the `i2c_init` function which intentionally has a weak attribute. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function:
+
+```C
+void i2c_init(void)
+{
+  setPinInput(B6); // Try releasing special pins for a short time
+  setPinInput(B7);
+  chThdSleepMilliseconds(10); // Wait for the release to happen
+
+  palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function
+  palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function
+}
+```
+
+

+ 2 - 1
docs/index.html

@@ -25,7 +25,8 @@
         placeholder: 'Search Documentation...',
         noData: 'We could not find any documents matching your search.',
         depth: 6
-      }
+      },
+      fallbackLanguages: ['zh']
     }
   </script>
   <script src="//unpkg.com/docsify/lib/docsify.min.js"></script>

+ 23 - 0
docs/internals_gpio_control.md

@@ -0,0 +1,23 @@
+# GPIO Control
+
+QMK has a GPIO control abstraction layer which is micro-controller agnostic. This is done to allow easy access to pin control across different platforms.
+
+## Functions
+
+The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
+
+|Function              |Description                                                       |
+|----------------------|------------------------------------------------------------------|
+|`setPinInput(pin)`    |Set pin as input with high impedance (High-Z)                     |
+|`setPinInputHigh(pin)`|Set pin as input with build in pull-up                            |
+|`setPinInputLow(pin)` |Set pin as input with build in pull-down (Supported only on STM32)|
+|`setPinOutput(pin)`   |Set pin as output                                                 |
+|`writePinHigh(pin)`   |Set pin level as high, assuming it is an output                   |
+|`writePinLow(pin)`    |Set pin level as low, assuming it is an output                    |
+|`writePin(pin, level)`|Set pin level, assuming it is an output                           |
+|`readPin(pin)`        |Returns the level of the pin                                      |
+
+## Advance settings
+
+Each micro-controller can have multiple advance settings regarding its GPIO. This abstraction layer does not limit the use of architecture specific functions. Advance users should consult the datasheet of there desired device and include any needed libraries. For AVR the standard avr/io.h library is used and for STM32 the Chibios [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 50 - 29
docs/isp_flashing_guide.md


+ 2 - 0
docs/keycode.txt

@@ -209,6 +209,8 @@ KC_WWW_FORWARD      KC_WFWD
 KC_WWW_STOP         KC_WSTP
 KC_WWW_REFRESH      KC_WREF
 KC_WWW_FAVORITES    KC_WFAV
+KC_BRIGHTNESS_UP    KC_BRIU
+KC_BRIGHTNESS_DOWN  KC_BRID
 /* Mousekey */
 KC_MS_UP            KC_MS_U         Mouse Cursor Up
 KC_MS_DOWN          KC_MS_D         Mouse Cursor Down

+ 163 - 146
docs/keycodes.md

@@ -8,40 +8,8 @@ This is a reference only. Each group of keys links to the page documenting their
 
 |Key                    |Aliases             |Description                                    |
 |-----------------------|--------------------|-----------------------------------------------|
-|`KC_1`                 |                    |`1` and `!`                                    |
-|`KC_2`                 |                    |`2` and `@`                                    |
-|`KC_3`                 |                    |`3` and `#`                                    |
-|`KC_4`                 |                    |`4` and `$`                                    |
-|`KC_5`                 |                    |`5` and `%`                                    |
-|`KC_6`                 |                    |`6` and `^`                                    |
-|`KC_7`                 |                    |`7` and `&`                                    |
-|`KC_8`                 |                    |`8` and `*`                                    |
-|`KC_9`                 |                    |`9` and `(`                                    |
-|`KC_0`                 |                    |`0` and `)`                                    |
-|`KC_F1`                |                    |                                               |
-|`KC_F2`                |                    |                                               |
-|`KC_F3`                |                    |                                               |
-|`KC_F4`                |                    |                                               |
-|`KC_F5`                |                    |                                               |
-|`KC_F6`                |                    |                                               |
-|`KC_F7`                |                    |                                               |
-|`KC_F8`                |                    |                                               |
-|`KC_F9`                |                    |                                               |
-|`KC_F10`               |                    |                                               |
-|`KC_F11`               |                    |                                               |
-|`KC_F12`               |                    |                                               |
-|`KC_F13`               |                    |                                               |
-|`KC_F14`               |                    |                                               |
-|`KC_F15`               |                    |                                               |
-|`KC_F16`               |                    |                                               |
-|`KC_F17`               |                    |                                               |
-|`KC_F18`               |                    |                                               |
-|`KC_F19`               |                    |                                               |
-|`KC_F20`               |                    |                                               |
-|`KC_F21`               |                    |                                               |
-|`KC_F22`               |                    |                                               |
-|`KC_F23`               |                    |                                               |
-|`KC_F24`               |                    |                                               |
+|`KC_NO`                |`XXXXXXX`           |Ignore this key (NOOP)                         |
+|`KC_TRANSPARENT`       |`KC_TRNS`, `_______`|Use the next lowest non-transparent key        |
 |`KC_A`                 |                    |`a` and `A`                                    |
 |`KC_B`                 |                    |`b` and `B`                                    |
 |`KC_C`                 |                    |`c` and `C`                                    |
@@ -68,6 +36,16 @@ This is a reference only. Each group of keys links to the page documenting their
 |`KC_X`                 |                    |`x` and `X`                                    |
 |`KC_Y`                 |                    |`y` and `Y`                                    |
 |`KC_Z`                 |                    |`z` and `Z`                                    |
+|`KC_1`                 |                    |`1` and `!`                                    |
+|`KC_2`                 |                    |`2` and `@`                                    |
+|`KC_3`                 |                    |`3` and `#`                                    |
+|`KC_4`                 |                    |`4` and `$`                                    |
+|`KC_5`                 |                    |`5` and `%`                                    |
+|`KC_6`                 |                    |`6` and `^`                                    |
+|`KC_7`                 |                    |`7` and `&`                                    |
+|`KC_8`                 |                    |`8` and `*`                                    |
+|`KC_9`                 |                    |`9` and `(`                                    |
+|`KC_0`                 |                    |`0` and `)`                                    |
 |`KC_ENTER`             |`KC_ENT`            |Return (Enter)                                 |
 |`KC_ESCAPE`            |`KC_ESC`            |Escape                                         |
 |`KC_BSPACE`            |`KC_BSPC`           |Delete (Backspace)                             |
@@ -79,33 +57,28 @@ This is a reference only. Each group of keys links to the page documenting their
 |`KC_RBRACKET`          |`KC_RBRC`           |`]` and `}`                                    |
 |`KC_BSLASH`            |`KC_BSLS`           |`\` and <code>&#124;</code>                    |
 |`KC_NONUS_HASH`        |`KC_NUHS`           |Non-US `#` and `~`                             |
-|`KC_NONUS_BSLASH`      |`KC_NUBS`           |Non-US `\` and <code>&#124;</code>             |
-|`KC_INT1`              |`KC_RO`             |JIS `\` and <code>&#124;</code>                |
-|`KC_INT2`              |`KC_KANA`           |JIS Katakana/Hiragana                          |
-|`KC_INT3`              |`KC_JYEN`           |JIS `¥`                                        |
 |`KC_SCOLON`            |`KC_SCLN`           |`;` and `:`                                    |
 |`KC_QUOTE`             |`KC_QUOT`           |`'` and `"`                                    |
-|`KC_GRAVE`             |`KC_GRV`            |<code>&#96;</code> and `~`                     |
+|`KC_GRAVE`             |`KC_GRV`, `KC_ZKHK` |<code>&#96;</code> and `~`, JIS Zenkaku/Hankaku|
 |`KC_COMMA`             |`KC_COMM`           |`,` and `<`                                    |
 |`KC_DOT`               |                    |`.` and `>`                                    |
 |`KC_SLASH`             |`KC_SLSH`           |`/` and `?`                                    |
-|`KC_CAPSLOCK`          |`KC_CAPS`           |Caps Lock                                      |
-|`KC_LCTRL`             |`KC_LCTL`           |Left Control                                   |
-|`KC_LSHIFT`            |`KC_LSFT`           |Left Shift                                     |
-|`KC_LALT`              |                    |Left Alt                                       |
-|`KC_LGUI`              |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key)            |
-|`KC_RCTRL`             |`KC_RCTL`           |Right Control                                  |
-|`KC_RSHIFT`            |`KC_RSFT`           |Right Shift                                    |
-|`KC_RALT`              |                    |Right Alt                                      |
-|`KC_RGUI`              |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)           |
-|`KC_LOCKING_CAPS`      |`KC_LCAP`           |Locking Caps Lock                              |
-|`KC_LOCKING_NUM`       |`KC_LNUM`           |Locking Num Lock                               |
-|`KC_LOCKING_SCROLL`    |`KC_LSCR`           |Locking Scroll Lock                            |
-|`KC_INT4`              |`KC_HENK`           |JIS Henkan                                     |
-|`KC_INT5`              |`KC_MHEN`           |JIS Muhenkan                                   |
+|`KC_CAPSLOCK`          |`KC_CLCK`, `KC_CAPS`|Caps Lock                                      |
+|`KC_F1`                |                    |F1                                             |
+|`KC_F2`                |                    |F2                                             |
+|`KC_F3`                |                    |F3                                             |
+|`KC_F4`                |                    |F4                                             |
+|`KC_F5`                |                    |F5                                             |
+|`KC_F6`                |                    |F6                                             |
+|`KC_F7`                |                    |F7                                             |
+|`KC_F8`                |                    |F8                                             |
+|`KC_F9`                |                    |F9                                             |
+|`KC_F10`               |                    |F10                                            |
+|`KC_F11`               |                    |F11                                            |
+|`KC_F12`               |                    |F12                                            |
 |`KC_PSCREEN`           |`KC_PSCR`           |Print Screen                                   |
 |`KC_SCROLLLOCK`        |`KC_SLCK`           |Scroll Lock                                    |
-|`KC_PAUSE`             |`KC_PAUS`           |Pause                                          |
+|`KC_PAUSE`             |`KC_PAUS`, `KC_BRK` |Pause                                          |
 |`KC_INSERT`            |`KC_INS`            |Insert                                         |
 |`KC_HOME`              |                    |Home                                           |
 |`KC_PGUP`              |                    |Page Up                                        |
@@ -116,22 +89,80 @@ This is a reference only. Each group of keys links to the page documenting their
 |`KC_LEFT`              |                    |Left Arrow                                     |
 |`KC_DOWN`              |                    |Down Arrow                                     |
 |`KC_UP`                |                    |Up Arrow                                       |
+|`KC_NUMLOCK`           |`KC_NLCK`           |Keypad Num Lock and Clear                      |
+|`KC_KP_SLASH`          |`KC_PSLS`           |Keypad `/`                                     |
+|`KC_KP_ASTERISK`       |`KC_PAST`           |Keypad `*`                                     |
+|`KC_KP_MINUS`          |`KC_PMNS`           |Keypad `-`                                     |
+|`KC_KP_PLUS`           |`KC_PPLS`           |Keypad `+`                                     |
+|`KC_KP_ENTER`          |`KC_PENT`           |Keypad Enter                                   |
+|`KC_KP_1`              |`KC_P1`             |Keypad `1` and End                             |
+|`KC_KP_2`              |`KC_P2`             |Keypad `2` and Down Arrow                      |
+|`KC_KP_3`              |`KC_P3`             |Keypad `3` and Page Down                       |
+|`KC_KP_4`              |`KC_P4`             |Keypad `4` and Left Arrow                      |
+|`KC_KP_5`              |`KC_P5`             |Keypad `5`                                     |
+|`KC_KP_6`              |`KC_P6`             |Keypad `6` and Right Arrow                     |
+|`KC_KP_7`              |`KC_P7`             |Keypad `7` and Home                            |
+|`KC_KP_8`              |`KC_P8`             |Keypad `8` and Up Arrow                        |
+|`KC_KP_9`              |`KC_P9`             |Keypad `9` and Page Up                         |
+|`KC_KP_0`              |`KC_P0`             |Keypad `0` and Insert                          |
+|`KC_KP_DOT`            |`KC_PDOT`           |Keypad `.` and Delete                          |
+|`KC_NONUS_BSLASH`      |`KC_NUBS`           |Non-US `\` and <code>&#124;</code>             |
 |`KC_APPLICATION`       |`KC_APP`            |Application (Windows Menu Key)                 |
-|`KC_POWER`             |                    |Deprecated by MS in favor of `KC_SYSTEM_POWER`.|
-|`KC_EXECUTE`           |                    |Execute                                        |
+|`KC_POWER`             |                    |System Power (macOS)                           |
+|`KC_KP_EQUAL`          |`KC_PEQL`           |Keypad `=`                                     |
+|`KC_F13`               |                    |F13                                            |
+|`KC_F14`               |                    |F14                                            |
+|`KC_F15`               |                    |F15                                            |
+|`KC_F16`               |                    |F16                                            |
+|`KC_F17`               |                    |F17                                            |
+|`KC_F18`               |                    |F18                                            |
+|`KC_F19`               |                    |F19                                            |
+|`KC_F20`               |                    |F20                                            |
+|`KC_F21`               |                    |F21                                            |
+|`KC_F22`               |                    |F22                                            |
+|`KC_F23`               |                    |F23                                            |
+|`KC_F24`               |                    |F24                                            |
+|`KC_EXECUTE`           |`KC_EXEC`           |Execute                                        |
 |`KC_HELP`              |                    |Help                                           |
 |`KC_MENU`              |                    |Menu                                           |
-|`KC_SELECT`            |                    |Select                                         |
-|`KC_AGAIN`             |                    |Again                                          |
+|`KC_SELECT`            |`KC_SLCT`           |Select                                         |
+|`KC_STOP`              |                    |Stop                                           |
+|`KC_AGAIN`             |`KC_AGIN`           |Again                                          |
 |`KC_UNDO`              |                    |Undo                                           |
 |`KC_CUT`               |                    |Cut                                            |
 |`KC_COPY`              |                    |Copy                                           |
-|`KC_PASTE`             |                    |Paste                                          |
+|`KC_PASTE`             |`KC_PSTE`           |Paste                                          |
 |`KC_FIND`              |                    |Find                                           |
-|`KC_ALT_ERASE`         |                    |Alternate Erase                                |
+|`KC__MUTE`             |                    |Mute (macOS)                                   |
+|`KC__VOLUP`            |                    |Volume Up (macOS)                              |
+|`KC__VOLDOWN`          |                    |Volume Down (macOS)                            |
+|`KC_LOCKING_CAPS`      |`KC_LCAP`           |Locking Caps Lock                              |
+|`KC_LOCKING_NUM`       |`KC_LNUM`           |Locking Num Lock                               |
+|`KC_LOCKING_SCROLL`    |`KC_LSCR`           |Locking Scroll Lock                            |
+|`KC_KP_COMMA`          |`KC_PCMM`           |Keypad `,`                                     |
+|`KC_KP_EQUAL_AS400`    |                    |Keypad `=` on AS/400 keyboards                 |
+|`KC_INT1`              |`KC_RO`             |JIS `\` and `_`                                |
+|`KC_INT2`              |`KC_KANA`           |JIS Katakana/Hiragana                          |
+|`KC_INT3`              |`KC_JYEN`           |JIS `¥` and <code>&#124;</code>                |
+|`KC_INT4`              |`KC_HENK`           |JIS Henkan                                     |
+|`KC_INT5`              |`KC_MHEN`           |JIS Muhenkan                                   |
+|`KC_INT6`              |                    |JIS Numpad `,`                                 |
+|`KC_INT7`              |                    |International 7                                |
+|`KC_INT8`              |                    |International 8                                |
+|`KC_INT9`              |                    |International 9                                |
+|`KC_LANG1`             |`KC_HAEN`           |Hangul/English                                 |
+|`KC_LANG2`             |`KC_HANJ`           |Hanja                                          |
+|`KC_LANG3`             |                    |JIS Katakana                                   |
+|`KC_LANG4`             |                    |JIS Hiragana                                   |
+|`KC_LANG5`             |                    |JIS Zenkaku/Hankaku                            |
+|`KC_LANG6`             |                    |Language 6                                     |
+|`KC_LANG7`             |                    |Language 7                                     |
+|`KC_LANG8`             |                    |Language 8                                     |
+|`KC_LANG9`             |                    |Language 9                                     |
+|`KC_ALT_ERASE`         |`KC_ERAS`           |Alternate Erase                                |
 |`KC_SYSREQ`            |                    |SysReq/Attention                               |
 |`KC_CANCEL`            |                    |Cancel                                         |
-|`KC_CLEAR`             |                    |Clear                                          |
+|`KC_CLEAR`             |`KC_CLR`            |Clear                                          |
 |`KC_PRIOR`             |                    |Prior                                          |
 |`KC_RETURN`            |                    |Return                                         |
 |`KC_SEPARATOR`         |                    |Separator                                      |
@@ -140,71 +171,56 @@ This is a reference only. Each group of keys links to the page documenting their
 |`KC_CLEAR_AGAIN`       |                    |Clear/Again                                    |
 |`KC_CRSEL`             |                    |CrSel/Props                                    |
 |`KC_EXSEL`             |                    |ExSel                                          |
-|`KC_SYSTEM_POWER`      |`KC_PWR`            |System Power Down. Recommended over `KC_POWER`.|
+|`KC_LCTRL`             |`KC_LCTL`           |Left Control                                   |
+|`KC_LSHIFT`            |`KC_LSFT`           |Left Shift                                     |
+|`KC_LALT`              |                    |Left Alt                                       |
+|`KC_LGUI`              |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key)            |
+|`KC_RCTRL`             |`KC_RCTL`           |Right Control                                  |
+|`KC_RSHIFT`            |`KC_RSFT`           |Right Shift                                    |
+|`KC_RALT`              |                    |Right Alt                                      |
+|`KC_RGUI`              |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)           |
+|`KC_SYSTEM_POWER`      |`KC_PWR`            |System Power Down                              |
 |`KC_SYSTEM_SLEEP`      |`KC_SLEP`           |System Sleep                                   |
 |`KC_SYSTEM_WAKE`       |`KC_WAKE`           |System Wake                                    |
-|`KC_MAIL`              |`KC_MAIL`           |                                               |
-|`KC_CALCULATOR`        |`KC_CALC`           |                                               |
-|`KC_MY_COMPUTER`       |`KC_MYCM`           |                                               |
-|`KC_WWW_SEARCH`        |`KC_WSCH`           |                                               |
-|`KC_WWW_HOME`          |`KC_WHOM`           |                                               |
-|`KC_WWW_BACK`          |`KC_WBAK`           |                                               |
-|`KC_WWW_FORWARD`       |`KC_WFWD`           |                                               |
-|`KC_WWW_STOP`          |`KC_WSTP`           |                                               |
-|`KC_WWW_REFRESH`       |`KC_WREF`           |                                               |
-|`KC_WWW_FAVORITES`     |`KC_WFAV`           |                                               |
-|`KC_STOP`              |                    |Stop                                           |
-|`KC__MUTE`             |                    |Mute (macOS)                                   |
-|`KC__VOLUP`            |                    |Volume Up (macOS)                              |
-|`KC__VOLDOWN`          |                    |Volume Down (macOS)                            |
-|`KC_AUDIO_MUTE`        |`KC_MUTE`           |Mute (Windows/macOS/Linux)                     |
-|`KC_AUDIO_VOL_UP`      |`KC_VOLU`           |Volume Up (Windows/macOS/Linux)                |
-|`KC_AUDIO_VOL_DOWN`    |`KC_VOLD`           |Volume Down (Windows/macOS/Linux)              |
+|`KC_AUDIO_MUTE`        |`KC_MUTE`           |Mute                                           |
+|`KC_AUDIO_VOL_UP`      |`KC_VOLU`           |Volume Up                                      |
+|`KC_AUDIO_VOL_DOWN`    |`KC_VOLD`           |Volume Down                                    |
 |`KC_MEDIA_NEXT_TRACK`  |`KC_MNXT`           |Next Track (Windows)                           |
 |`KC_MEDIA_PREV_TRACK`  |`KC_MPRV`           |Previous Track (Windows)                       |
-|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`           |Next Track (macOS)                             |
-|`KC_MEDIA_REWIND`      |`KC_MRWD`           |Previous Track (macOS)                         |
-|`KC_MEDIA_STOP`        |`KC_MSTP`           |Stop Track                                     |
+|`KC_MEDIA_STOP`        |`KC_MSTP`           |Stop Track (Windows)                           |
 |`KC_MEDIA_PLAY_PAUSE`  |`KC_MPLY`           |Play/Pause Track                               |
-|`KC_MEDIA_SELECT`      |`KC_MSEL`           |                                               |
+|`KC_MEDIA_SELECT`      |`KC_MSEL`           |Launch Media Player (Windows)                  |
 |`KC_MEDIA_EJECT`       |`KC_EJCT`           |Eject (macOS)                                  |
-|`KC_NUMLOCK`           |`KC_NLCK`           |Keypad Num Lock and Clear                      |
-|`KC_KP_SLASH`          |`KC_PSLS`           |Keypad `/`                                     |
-|`KC_KP_ASTERISK`       |`KC_PAST`           |Keypad `*`                                     |
-|`KC_KP_MINUS`          |`KC_PMNS`           |Keypad `-`                                     |
-|`KC_KP_PLUS`           |`KC_PPLS`           |Keypad `+`                                     |
-|`KC_KP_ENTER`          |`KC_PENT`           |Keypad Enter                                   |
-|`KC_KP_1`              |`KC_P1`             |Keypad `1` and End                             |
-|`KC_KP_2`              |`KC_P2`             |Keypad `2` and Down Arrow                      |
-|`KC_KP_3`              |`KC_P3`             |Keypad `3` and Page Down                       |
-|`KC_KP_4`              |`KC_P4`             |Keypad `4` and Left Arrow                      |
-|`KC_KP_5`              |`KC_P5`             |Keypad `5`                                     |
-|`KC_KP_6`              |`KC_P6`             |Keypad `6` and Right Arrow                     |
-|`KC_KP_7`              |`KC_P7`             |Keypad `7` and Home                            |
-|`KC_KP_8`              |`KC_P8`             |Keypad `8` and Up Arrow                        |
-|`KC_KP_9`              |`KC_P9`             |Keypad `9` and Page Up                         |
-|`KC_KP_0`              |`KC_P0`             |Keypad `0` and Insert                          |
-|`KC_KP_DOT`            |`KC_PDOT`           |Keypad `.` and Delete                          |
-|`KC_KP_EQUAL`          |`KC_PEQL`           |Keypad `=`                                     |
-|`KC_KP_COMMA`          |`KC_PCMM`           |Keypad `,`                                     |
-|`KC_KP_EQUAL_AS400`    |                    |Keypad `=` on AS/400 keyboards                 |
-|`KC_NO`                |                    |Ignore this key (NOOP)                         |
-|`KC_TRANSPARENT`       |`KC_TRNS`           |Use the next lowest non-transparent key        |
+|`KC_MAIL`              |                    |Launch Mail (Windows)                          |
+|`KC_CALCULATOR`        |`KC_CALC`           |Launch Calculator (Windows)                    |
+|`KC_MY_COMPUTER`       |`KC_MYCM`           |Launch My Computer (Windows)                   |
+|`KC_WWW_SEARCH`        |`KC_WSCH`           |Browser Search (Windows)                       |
+|`KC_WWW_HOME`          |`KC_WHOM`           |Browser Home (Windows)                         |
+|`KC_WWW_BACK`          |`KC_WBAK`           |Browser Back (Windows)                         |
+|`KC_WWW_FORWARD`       |`KC_WFWD`           |Browser Forward (Windows)                      |
+|`KC_WWW_STOP`          |`KC_WSTP`           |Browser Stop (Windows)                         |
+|`KC_WWW_REFRESH`       |`KC_WREF`           |Browser Refresh (Windows)                      |
+|`KC_WWW_FAVORITES`     |`KC_WFAV`           |Browser Favorites (Windows)                    |
+|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`           |Next Track (macOS)                             |
+|`KC_MEDIA_REWIND`      |`KC_MRWD`           |Previous Track (macOS)                         |
+|`KC_BRIGHTNESS_UP`     |`KC_BRIU`           |Brightness Up                                  |
+|`KC_BRIGHTNESS_DOWN`   |`KC_BRID`           |Brightness Down                                |
 
 ## [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes)
 
-|Key          |Aliases    |Description                                                          |
-|-------------|-----------|---------------------------------------------------------------------|
-|`RESET`      |           |Put the keyboard into DFU mode for flashing                          |
-|`DEBUG`      |           |Toggle debug mode                                                    |
-|`KC_GESC`    |`GRAVE_ESC`|Escape when tapped, <code>&#96;</code> when pressed with Shift or GUI|
-|`KC_LSPO`    |           |Left Shift when held, `(` when tapped                                |
-|`KC_RSPC`    |           |Right Shift when held, `)` when tapped                               |
-|`KC_LEAD`    |           |The [Leader key](feature_leader_key.md)                              |
-|`KC_LOCK`    |           |The [Lock key](feature_key_lock.md)                                  |
-|`FUNC(n)`    |`F(n)`     |Call `fn_action(n)` (deprecated)                                     |
-|`M(n)`       |           |Call macro `n`                                                       |
-|`MACROTAP(n)`|           |Macro-tap `n` idk FIXME                                              |
+|Key            |Aliases    |Description                                                          |
+|---------------|-----------|---------------------------------------------------------------------|
+|`RESET`        |           |Put the keyboard into DFU mode for flashing                          |
+|`DEBUG`        |           |Toggle debug mode                                                    |
+|`EEPROM_RESET` |`EEP_RST`  |Resets EEPROM state by reinitializing it                             |
+|`KC_GESC`      |`GRAVE_ESC`|Escape when tapped, <code>&#96;</code> when pressed with Shift or GUI|
+|`KC_LSPO`      |           |Left Shift when held, `(` when tapped                                |
+|`KC_RSPC`      |           |Right Shift when held, `)` when tapped                               |
+|`KC_LEAD`      |           |The [Leader key](feature_leader_key.md)                              |
+|`KC_LOCK`      |           |The [Lock key](feature_key_lock.md)                                  |
+|`FUNC(n)`      |`F(n)`     |Call `fn_action(n)` (deprecated)                                     |
+|`M(n)`         |           |Call macro `n`                                                       |
+|`MACROTAP(n)`  |           |Macro-tap `n` idk FIXME                                              |
 
 ## [Audio Keys](feature_audio.md)
 
@@ -258,6 +274,7 @@ This is a reference only. Each group of keys links to the page documenting their
 |`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|         |Unswap `\` and Backspace            |
 |`MAGIC_UNHOST_NKRO`               |         |Force NKRO off                      |
 |`MAGIC_UNSWAP_ALT_GUI`            |`AG_NORM`|Unswap Alt and GUI on both sides    |
+|`MAGIC_TOGGLE_ALT_GUI`            |`AG_TOGG`|Toggle Alt and GUI swap on both sides|
 |`MAGIC_TOGGLE_NKRO`               |         |Turn NKRO on or off                 |
 
 ## [Bluetooth](feature_bluetooth.md)
@@ -269,7 +286,7 @@ This is a reference only. Each group of keys links to the page documenting their
 |`OUT_BT`  |Bluetooth only                                |
 
 
-## [Layer Switching](feature_advanced_keycodes.md# Switching and Toggling Layers)
+## [Layer Switching](feature_advanced_keycodes.md#switching-and-toggling-layers)
 
 |Key         |Description                                                               |
 |-----------------|---------------------------------------------------------------------|
@@ -305,7 +322,7 @@ This is a reference only. Each group of keys links to the page documenting their
 ## [Modifiers](feature_advanced_keycodes.md#modifier-keys)
 
 |Key       |Aliases               |Description                                         |
-|----------|----------            |----------------------------------------------------|
+|----------|----------------------|----------------------------------------------------|
 |`KC_HYPR` |                      |Hold Left Control, Shift, Alt and GUI               |
 |`KC_MEH`  |                      |Hold Left Control, Shift and Alt                    |
 |`LCTL(kc)`|                      |Hold Left Control and press `kc`                    |
@@ -319,7 +336,6 @@ This is a reference only. Each group of keys links to the page documenting their
 |`HYPR(kc)`|                      |Hold Left Control, Shift, Alt and GUI and press `kc`|
 |`MEH(kc)` |                      |Hold Left Control, Shift and Alt and press `kc`     |
 |`LCAG(kc)`|                      |Hold Left Control, Alt and GUI and press `kc`       |
-|`ALTG(kc)`|                      |Hold Right Control and Alt and press `kc`           |
 |`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)`|Hold Left Shift and GUI and press `kc`              |
 |`LCA(kc)` |                      |Hold Left Control and Alt and press `kc`            |
 
@@ -340,7 +356,7 @@ This is a reference only. Each group of keys links to the page documenting their
 |`LCAG_T(kc)`|                                       |Left Control, Alt and GUI when held, `kc` when tapped  |
 |`RCAG_T(kc)`|                                       |Right Control, Alt and GUI when held, `kc` when tapped |
 |`ALL_T(kc)` |                                       |Left Control, Shift, Alt and GUI when held, `kc` when tapped - more info [here](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)|
-|`SCMD_T(kc)`|`SWIN_T(kc)`                           |Left Shift and GUI when held, `kc` when tapped         |
+|`SGUI_T(kc)`|`SCMD_T(kc)`, `SWIN_T(kc)`             |Left Shift and GUI when held, `kc` when tapped         |
 |`LCA_T(kc)` |                                       |Left Control and Alt when held, `kc` when tapped       |
 
 ## [RGB Lighting](feature_rgblight.md)
@@ -389,31 +405,31 @@ This is a reference only. Each group of keys links to the page documenting their
 |`PRINT_ON` |Start printing everything the user types|
 |`PRINT_OFF`|Stop printing everything the user types |
 
-## [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
-
-|Key                     |Aliases           |Description        |
-|------------------------|------------------|-------------------|
-|`KC_TILDE`              |`KC_TILD`         |`~`                |
-|`KC_EXCLAIM`            |`KC_EXLM`         |`!`                |
-|`KC_AT`                 |                  |`@`                |
-|`KC_HASH`               |                  |`#`                |
-|`KC_DOLLAR`             |`KC_DLR`          |`$`                |
-|`KC_PERCENT`            |`KC_PERC`         |`%`                |
-|`KC_CIRCUMFLEX`         |`KC_CIRC`         |`^`                |
-|`KC_AMPERSAND`          |`KC_AMPR`         |`&`                |
-|`KC_ASTERISK`           |`KC_ASTR`         |`*`                |
-|`KC_LEFT_PAREN`         |`KC_LPRN`         |`(`                |
-|`KC_RIGHT_PAREN`        |`KC_RPRN`         |`)`                |
-|`KC_UNDERSCORE`         |`KC_UNDS`         |`_`                |
-|`KC_PLUS`               |                  |`+`                |
-|`KC_LEFT_CURLY_BRACE`   |`KC_LCBR`         |`{`                |
-|`KC_RIGHT_CURLY_BRACE`  |`KC_RCBR`         |`}`                |
-|`KC_PIPE`               |                  |<code>&#124;</code>|
-|`KC_COLON`              |`KC_COLN`         |`:`                |
-|`KC_DOUBLE_QUOTE`       |`KC_DQT`/`KC_DQUO`|`"`                |
-|`KC_LEFT_ANGLE_BRACKET` |`KC_LT`/`KC_LABK` |`<`                |
-|`KC_RIGHT_ANGLE_BRACKET`|`KC_GT`/`KC_RABK` |`>`                |
-|`KC_QUESTION`           |`KC_QUES`         |`?`                |
+## [US ANSI Shifted Symbols](keycodes_us_ansi_shifted.md)
+
+|Key                     |Aliases            |Description        |
+|------------------------|-------------------|-------------------|
+|`KC_TILDE`              |`KC_TILD`          |`~`                |
+|`KC_EXCLAIM`            |`KC_EXLM`          |`!`                |
+|`KC_AT`                 |                   |`@`                |
+|`KC_HASH`               |                   |`#`                |
+|`KC_DOLLAR`             |`KC_DLR`           |`$`                |
+|`KC_PERCENT`            |`KC_PERC`          |`%`                |
+|`KC_CIRCUMFLEX`         |`KC_CIRC`          |`^`                |
+|`KC_AMPERSAND`          |`KC_AMPR`          |`&`                |
+|`KC_ASTERISK`           |`KC_ASTR`          |`*`                |
+|`KC_LEFT_PAREN`         |`KC_LPRN`          |`(`                |
+|`KC_RIGHT_PAREN`        |`KC_RPRN`          |`)`                |
+|`KC_UNDERSCORE`         |`KC_UNDS`          |`_`                |
+|`KC_PLUS`               |                   |`+`                |
+|`KC_LEFT_CURLY_BRACE`   |`KC_LCBR`          |`{`                |
+|`KC_RIGHT_CURLY_BRACE`  |`KC_RCBR`          |`}`                |
+|`KC_PIPE`               |                   |<code>&#124;</code>|
+|`KC_COLON`              |`KC_COLN`          |`:`                |
+|`KC_DOUBLE_QUOTE`       |`KC_DQUO`, `KC_DQT`|`"`                |
+|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<`                |
+|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>`                |
+|`KC_QUESTION`           |`KC_QUES`          |`?`                |
 
 ## [Switching and Toggling Layers](feature_advanced_keycodes.md#switching-and-toggling-layers)
 
@@ -446,6 +462,7 @@ This is a reference only. Each group of keys links to the page documenting their
 |`SH_MOFF`  |Momentarily turns off swap.                                              |
 |`SH_TG`    |Toggles swap on and off with every key press.                            |
 |`SH_TT`    |Toggles with a tap; momentary when held.                                 |
+
 ## [Unicode Support](feature_unicode.md)
 
 |Key         |Aliases|                                                 |

+ 163 - 138
docs/keycodes_basic.md

@@ -1,6 +1,6 @@
 # Basic Keycodes
 
-The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07)](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf) with the exception of `KC_NO`, `KC_TRNS` and keycodes in the `0xA5-DF` range. See below for more details.
+The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07)](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) with the exception of `KC_NO`, `KC_TRNS` and keycodes in the `0xA5-DF` range. See below for more details.
 
 ## Letters and Numbers
 
@@ -47,117 +47,145 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07
 
 |Key     |Description|
 |--------|-----------|
-|`KC_F1` |           |
-|`KC_F2` |           |
-|`KC_F3` |           |
-|`KC_F4` |           |
-|`KC_F5` |           |
-|`KC_F6` |           |
-|`KC_F7` |           |
-|`KC_F8` |           |
-|`KC_F9` |           |
-|`KC_F10`|           |
-|`KC_F11`|           |
-|`KC_F12`|           |
-|`KC_F13`|           |
-|`KC_F14`|           |
-|`KC_F15`|           |
-|`KC_F16`|           |
-|`KC_F17`|           |
-|`KC_F18`|           |
-|`KC_F19`|           |
-|`KC_F20`|           |
-|`KC_F21`|           |
-|`KC_F22`|           |
-|`KC_F23`|           |
-|`KC_F24`|           |
+|`KC_F1` |F1         |
+|`KC_F2` |F2         |
+|`KC_F3` |F3         |
+|`KC_F4` |F4         |
+|`KC_F5` |F5         |
+|`KC_F6` |F6         |
+|`KC_F7` |F7         |
+|`KC_F8` |F8         |
+|`KC_F9` |F9         |
+|`KC_F10`|F10        |
+|`KC_F11`|F11        |
+|`KC_F12`|F12        |
+|`KC_F13`|F13        |
+|`KC_F14`|F14        |
+|`KC_F15`|F15        |
+|`KC_F16`|F16        |
+|`KC_F17`|F17        |
+|`KC_F18`|F18        |
+|`KC_F19`|F19        |
+|`KC_F20`|F20        |
+|`KC_F21`|F21        |
+|`KC_F22`|F22        |
+|`KC_F23`|F23        |
+|`KC_F24`|F24        |
 
 ## Punctuation
 
-|Key              |Aliases  |Description                       |
-|-----------------|---------|----------------------------------|
-|`KC_ENTER`       |`KC_ENT` |Return (Enter)                    |
-|`KC_ESCAPE`      |`KC_ESC` |Escape                            |
-|`KC_BSPACE`      |`KC_BSPC`|Delete (Backspace)                |
-|`KC_TAB`         |         |Tab                               |
-|`KC_SPACE`       |`KC_SPC` |Spacebar                          |
-|`KC_MINUS`       |`KC_MINS`|`-` and `_`                       |
-|`KC_EQUAL`       |`KC_EQL` |`=` and `+`                       |
-|`KC_LBRACKET`    |`KC_LBRC`|`[` and `{`                       |
-|`KC_RBRACKET`    |`KC_RBRC`|`]` and `}`                       |
-|`KC_BSLASH`      |`KC_BSLS`|`\` and <code>&#124;</code>       |
-|`KC_NONUS_HASH`  |`KC_NUHS`|Non-US `#` and `~`                |
-|`KC_NONUS_BSLASH`|`KC_NUBS`|Non-US `\` and <code>&#124;</code>|
-|`KC_INT1`        |`KC_RO`  |JIS `\` and <code>&#124;</code>   |
-|`KC_INT2`        |`KC_KANA`|JIS Katakana/Hiragana             |
-|`KC_INT3`        |`KC_JYEN`|JIS `¥`                           |
-|`KC_SCOLON`      |`KC_SCLN`|`;` and `:`                       |
-|`KC_QUOTE`       |`KC_QUOT`|`'` and `"`                       |
-|`KC_GRAVE`       |`KC_GRV` |<code>&#96;</code> and `~`        |
-|`KC_COMMA`       |`KC_COMM`|`,` and `<`                       |
-|`KC_DOT`         |         |`.` and `>`                       |
-|`KC_SLASH`       |`KC_SLSH`|`/` and `?`                       |
-|`KC_CAPSLOCK`    |`KC_CAPS`|Caps Lock                         |
+|Key              |Aliases            |Description                                    |
+|-----------------|-------------------|-----------------------------------------------|
+|`KC_ENTER`       |`KC_ENT`           |Return (Enter)                                 |
+|`KC_ESCAPE`      |`KC_ESC`           |Escape                                         |
+|`KC_BSPACE`      |`KC_BSPC`          |Delete (Backspace)                             |
+|`KC_TAB`         |                   |Tab                                            |
+|`KC_SPACE`       |`KC_SPC`           |Spacebar                                       |
+|`KC_MINUS`       |`KC_MINS`          |`-` and `_`                                    |
+|`KC_EQUAL`       |`KC_EQL`           |`=` and `+`                                    |
+|`KC_LBRACKET`    |`KC_LBRC`          |`[` and `{`                                    |
+|`KC_RBRACKET`    |`KC_RBRC`          |`]` and `}`                                    |
+|`KC_BSLASH`      |`KC_BSLS`          |`\` and <code>&#124;</code>                    |
+|`KC_NONUS_HASH`  |`KC_NUHS`          |Non-US `#` and `~`                             |
+|`KC_SCOLON`      |`KC_SCLN`          |`;` and `:`                                    |
+|`KC_QUOTE`       |`KC_QUOT`          |`'` and `"`                                    |
+|`KC_GRAVE`       |`KC_GRV`, `KC_ZKHK`|<code>&#96;</code> and `~`, JIS Zenkaku/Hankaku|
+|`KC_COMMA`       |`KC_COMM`          |`,` and `<`                                    |
+|`KC_DOT`         |                   |`.` and `>`                                    |
+|`KC_SLASH`       |`KC_SLSH`          |`/` and `?`                                    |
+|`KC_NONUS_BSLASH`|`KC_NUBS`          |Non-US `\` and <code>&#124;</code>             |
+
+## Lock Keys
+
+|Key                |Aliases             |Description              |
+|-------------------|--------------------|-------------------------|
+|`KC_CAPSLOCK`      |`KC_CLCK`, `KC_CAPS`|Caps Lock                |
+|`KC_SCROLLLOCK`    |`KC_SLCK`           |Scroll Lock              |
+|`KC_NUMLOCK`       |`KC_NLCK`           |Keypad Num Lock and Clear|
+|`KC_LOCKING_CAPS`  |`KC_LCAP`           |Locking Caps Lock        |
+|`KC_LOCKING_NUM`   |`KC_LNUM`           |Locking Num Lock         |
+|`KC_LOCKING_SCROLL`|`KC_LSCR`           |Locking Scroll Lock      |
 
 ## Modifiers
 
-|Key                |Aliases             |Description                         |
-|-------------------|--------------------|------------------------------------|
-|`KC_LCTRL`         |`KC_LCTL`           |Left Control                        |
-|`KC_LSHIFT`        |`KC_LSFT`           |Left Shift                          |
-|`KC_LALT`          |                    |Left Alt                            |
-|`KC_LGUI`          |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) |
-|`KC_RCTRL`         |`KC_RCTL`           |Right Control                       |
-|`KC_RSHIFT`        |`KC_RSFT`           |Right Shift                         |
-|`KC_RALT`          |                    |Right Alt                           |
-|`KC_RGUI`          |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)|
-|`KC_LOCKING_CAPS`  |`KC_LCAP`           |Locking Caps Lock                   |
-|`KC_LOCKING_NUM`   |`KC_LNUM`           |Locking Num Lock                    |
-|`KC_LOCKING_SCROLL`|`KC_LSCR`           |Locking Scroll Lock                 |
-|`KC_INT4`          |`KC_HENK`           |JIS Henkan                          |
-|`KC_INT5`          |`KC_MHEN`           |JIS Muhenkan                        |
+|Key        |Aliases             |Description                         |
+|-----------|--------------------|------------------------------------|
+|`KC_LCTRL` |`KC_LCTL`           |Left Control                        |
+|`KC_LSHIFT`|`KC_LSFT`           |Left Shift                          |
+|`KC_LALT`  |                    |Left Alt                            |
+|`KC_LGUI`  |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) |
+|`KC_RCTRL` |`KC_RCTL`           |Right Control                       |
+|`KC_RSHIFT`|`KC_RSFT`           |Right Shift                         |
+|`KC_RALT`  |                    |Right Alt                           |
+|`KC_RGUI`  |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)|
+
+## International
+
+|Key       |Aliases  |Description                    |
+|----------|---------|-------------------------------|
+|`KC_INT1` |`KC_RO`  |JIS `\` and `_`                |
+|`KC_INT2` |`KC_KANA`|JIS Katakana/Hiragana          |
+|`KC_INT3` |`KC_JYEN`|JIS `¥` and <code>&#124;</code>|
+|`KC_INT4` |`KC_HENK`|JIS Henkan                     |
+|`KC_INT5` |`KC_MHEN`|JIS Muhenkan                   |
+|`KC_INT6` |         |JIS Numpad `,`                 |
+|`KC_INT7` |         |International 7                |
+|`KC_INT8` |         |International 8                |
+|`KC_INT9` |         |International 9                |
+|`KC_LANG1`|`KC_HAEN`|Hangul/English                 |
+|`KC_LANG2`|`KC_HANJ`|Hanja                          |
+|`KC_LANG3`|         |JIS Katakana                   |
+|`KC_LANG4`|         |JIS Hiragana                   |
+|`KC_LANG5`|         |JIS Zenkaku/Hankaku            |
+|`KC_LANG6`|         |Language 6                     |
+|`KC_LANG7`|         |Language 7                     |
+|`KC_LANG8`|         |Language 8                     |
+|`KC_LANG9`|         |Language 9                     |
 
 ## Commands
 
-|Key               |Aliases  |Description                   |
-|------------------|---------|------------------------------|
-|`KC_PSCREEN`      |`KC_PSCR`|Print Screen                  |
-|`KC_SCROLLLOCK`   |`KC_SLCK`|Scroll Lock                   |
-|`KC_PAUSE`        |`KC_PAUS`|Pause                         |
-|`KC_INSERT`       |`KC_INS` |Insert                        |
-|`KC_HOME`         |         |Home                          |
-|`KC_PGUP`         |         |Page Up                       |
-|`KC_DELETE`       |`KC_DEL` |Forward Delete                |
-|`KC_END`          |         |End                           |
-|`KC_PGDOWN`       |`KC_PGDN`|Page Down                     |
-|`KC_RIGHT`        |`KC_RGHT`|Right Arrow                   |
-|`KC_LEFT`         |         |Left Arrow                    |
-|`KC_DOWN`         |         |Down Arrow                    |
-|`KC_UP`           |         |Up Arrow                      |
-|`KC_APPLICATION`  |`KC_APP` |Application (Windows Menu Key)|
-|`KC_POWER`        |         |Power                         |
-|`KC_EXECUTE`      |         |Execute                       |
-|`KC_HELP`         |         |Help                          |
-|`KC_MENU`         |         |Menu                          |
-|`KC_SELECT`       |         |Select                        |
-|`KC_AGAIN`        |         |Again                         |
-|`KC_UNDO`         |         |Undo                          |
-|`KC_CUT`          |         |Cut                           |
-|`KC_COPY`         |         |Copy                          |
-|`KC_PASTE`        |         |Paste                         |
-|`KC_FIND`         |         |Find                          |
-|`KC_ALT_ERASE`    |         |Alternate Erase               |
-|`KC_SYSREQ`       |         |SysReq/Attention              |
-|`KC_CANCEL`       |         |Cancel                        |
-|`KC_CLEAR`        |         |Clear                         |
-|`KC_PRIOR`        |         |Prior                         |
-|`KC_RETURN`       |         |Return                        |
-|`KC_SEPARATOR`    |         |Separator                     |
-|`KC_OUT`          |         |Out                           |
-|`KC_OPER`         |         |Oper                          |
-|`KC_CLEAR_AGAIN`  |         |Clear/Again                   |
-|`KC_CRSEL`        |         |CrSel/Props                   |
-|`KC_EXSEL`        |         |ExSel                         |
+|Key               |Aliases            |Description                   |
+|------------------|-------------------|------------------------------|
+|`KC_PSCREEN`      |`KC_PSCR`          |Print Screen                  |
+|`KC_PAUSE`        |`KC_PAUS`, `KC_BRK`|Pause                         |
+|`KC_INSERT`       |`KC_INS`           |Insert                        |
+|`KC_HOME`         |                   |Home                          |
+|`KC_PGUP`         |                   |Page Up                       |
+|`KC_DELETE`       |`KC_DEL`           |Forward Delete                |
+|`KC_END`          |                   |End                           |
+|`KC_PGDOWN`       |`KC_PGDN`          |Page Down                     |
+|`KC_RIGHT`        |`KC_RGHT`          |Right Arrow                   |
+|`KC_LEFT`         |                   |Left Arrow                    |
+|`KC_DOWN`         |                   |Down Arrow                    |
+|`KC_UP`           |                   |Up Arrow                      |
+|`KC_APPLICATION`  |`KC_APP`           |Application (Windows Menu Key)|
+|`KC_POWER`        |                   |System Power (macOS/Linux)    |
+|`KC_EXECUTE`      |`KC_EXEC`          |Execute                       |
+|`KC_HELP`         |                   |Help                          |
+|`KC_MENU`         |                   |Menu                          |
+|`KC_SELECT`       |`KC_SLCT`          |Select                        |
+|`KC_STOP`         |                   |Stop                          |
+|`KC_AGAIN`        |`KC_AGIN`          |Again                         |
+|`KC_UNDO`         |                   |Undo                          |
+|`KC_CUT`          |                   |Cut                           |
+|`KC_COPY`         |                   |Copy                          |
+|`KC_PASTE`        |`KC_PSTE`          |Paste                         |
+|`KC_FIND`         |                   |Find                          |
+|`KC__MUTE`        |                   |Mute (macOS)                  |
+|`KC__VOLUP`       |                   |Volume Up (macOS)             |
+|`KC__VOLDOWN`     |                   |Volume Down (macOS)           |
+|`KC_ALT_ERASE`    |`KC_ERAS`          |Alternate Erase               |
+|`KC_SYSREQ`       |                   |SysReq/Attention              |
+|`KC_CANCEL`       |                   |Cancel                        |
+|`KC_CLEAR`        |`KC_CLR`           |Clear                         |
+|`KC_PRIOR`        |                   |Prior                         |
+|`KC_RETURN`       |                   |Return                        |
+|`KC_SEPARATOR`    |                   |Separator                     |
+|`KC_OUT`          |                   |Out                           |
+|`KC_OPER`         |                   |Oper                          |
+|`KC_CLEAR_AGAIN`  |                   |Clear/Again                   |
+|`KC_CRSEL`        |                   |CrSel/Props                   |
+|`KC_EXSEL`        |                   |ExSel                         |
 
 ## Media Keys
 
@@ -165,42 +193,39 @@ These keycodes are not part of the Keyboard/Keypad usage page. The `SYSTEM_` key
 
 Windows and macOS use different keycodes for "next track" and "previous track". Make sure you choose the keycode that corresponds to your OS.
 
-|Key                    |Aliases  |Description                      |
-|-----------------------|---------|---------------------------------|
-|`KC_SYSTEM_POWER`      |`KC_PWR` |System Power Down                |
-|`KC_SYSTEM_SLEEP`      |`KC_SLEP`|System Sleep                     |
-|`KC_SYSTEM_WAKE`       |`KC_WAKE`|System Wake                      |
-|`KC_MAIL`              |`KC_MAIL`|                                 |
-|`KC_CALCULATOR`        |`KC_CALC`|                                 |
-|`KC_MY_COMPUTER`       |`KC_MYCM`|                                 |
-|`KC_WWW_SEARCH`        |`KC_WSCH`|                                 |
-|`KC_WWW_HOME`          |`KC_WHOM`|                                 |
-|`KC_WWW_BACK`          |`KC_WBAK`|                                 |
-|`KC_WWW_FORWARD`       |`KC_WFWD`|                                 |
-|`KC_WWW_STOP`          |`KC_WSTP`|                                 |
-|`KC_WWW_REFRESH`       |`KC_WREF`|                                 |
-|`KC_STOP`              |         |Stop                             |
-|`KC_WWW_FAVORITES`     |`KC_WFAV`|                                 |
-|`KC__MUTE`             |         |Mute (macOS)                     |
-|`KC__VOLUP`            |         |Volume Up (macOS)                |
-|`KC__VOLDOWN`          |         |Volume Down (macOS)              |
-|`KC_AUDIO_MUTE`        |`KC_MUTE`|Mute (Windows/macOS/Linux)       |
-|`KC_AUDIO_VOL_UP`      |`KC_VOLU`|Volume Up (Windows/macOS/Linux)  |
-|`KC_AUDIO_VOL_DOWN`    |`KC_VOLD`|Volume Down (Windows/macOS/Linux)|
-|`KC_MEDIA_NEXT_TRACK`  |`KC_MNXT`|Next Track (Windows)             |
-|`KC_MEDIA_PREV_TRACK`  |`KC_MPRV`|Previous Track (Windows)         |
-|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`|Next Track (macOS)               |
-|`KC_MEDIA_REWIND`      |`KC_MRWD`|Previous Track (macOS)           |
-|`KC_MEDIA_STOP`        |`KC_MSTP`|Stop Track                       |
-|`KC_MEDIA_PLAY_PAUSE`  |`KC_MPLY`|Play/Pause Track                 |
-|`KC_MEDIA_SELECT`      |`KC_MSEL`|                                 |
-|`KC_MEDIA_EJECT`       |`KC_EJCT`|Eject (macOS)                    |
+|Key                    |Aliases  |Description                  |
+|-----------------------|---------|-----------------------------|
+|`KC_SYSTEM_POWER`      |`KC_PWR` |System Power Down            |
+|`KC_SYSTEM_SLEEP`      |`KC_SLEP`|System Sleep                 |
+|`KC_SYSTEM_WAKE`       |`KC_WAKE`|System Wake                  |
+|`KC_AUDIO_MUTE`        |`KC_MUTE`|Mute                         |
+|`KC_AUDIO_VOL_UP`      |`KC_VOLU`|Volume Up                    |
+|`KC_AUDIO_VOL_DOWN`    |`KC_VOLD`|Volume Down                  |
+|`KC_MEDIA_NEXT_TRACK`  |`KC_MNXT`|Next Track (Windows)         |
+|`KC_MEDIA_PREV_TRACK`  |`KC_MPRV`|Previous Track (Windows)     |
+|`KC_MEDIA_STOP`        |`KC_MSTP`|Stop Track (Windows)         |
+|`KC_MEDIA_PLAY_PAUSE`  |`KC_MPLY`|Play/Pause Track             |
+|`KC_MEDIA_SELECT`      |`KC_MSEL`|Launch Media Player (Windows)|
+|`KC_MEDIA_EJECT`       |`KC_EJCT`|Eject (macOS)                |
+|`KC_MAIL`              |         |Launch Mail (Windows)        |
+|`KC_CALCULATOR`        |`KC_CALC`|Launch Calculator (Windows)  |
+|`KC_MY_COMPUTER`       |`KC_MYCM`|Launch My Computer (Windows) |
+|`KC_WWW_SEARCH`        |`KC_WSCH`|Browser Search (Windows)     |
+|`KC_WWW_HOME`          |`KC_WHOM`|Browser Home (Windows)       |
+|`KC_WWW_BACK`          |`KC_WBAK`|Browser Back (Windows)       |
+|`KC_WWW_FORWARD`       |`KC_WFWD`|Browser Forward (Windows)    |
+|`KC_WWW_STOP`          |`KC_WSTP`|Browser Stop (Windows)       |
+|`KC_WWW_REFRESH`       |`KC_WREF`|Browser Refresh (Windows)    |
+|`KC_WWW_FAVORITES`     |`KC_WFAV`|Browser Favorites (Windows)  |
+|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`|Next Track (macOS)           |
+|`KC_MEDIA_REWIND`      |`KC_MRWD`|Previous Track (macOS)       |
+|`KC_BRIGHTNESS_UP`     |`KC_BRIU`|Brightness Up                |
+|`KC_BRIGHTNESS_DOWN`   |`KC_BRID`|Brightness Down              |
 
 ## Number Pad
 
 |Key                |Aliases  |Description                   |
 |-------------------|---------|------------------------------|
-|`KC_NUMLOCK`       |`KC_NLCK`|Keypad Num Lock and Clear     |
 |`KC_KP_SLASH`      |`KC_PSLS`|Keypad `/`                    |
 |`KC_KP_ASTERISK`   |`KC_PAST`|Keypad `*`                    |
 |`KC_KP_MINUS`      |`KC_PMNS`|Keypad `-`                    |
@@ -225,7 +250,7 @@ Windows and macOS use different keycodes for "next track" and "previous track".
 
 In addition to these, keycodes in the range of `0xA5-DF` are reserved for internal use by TMK.
 
-|Key             |Aliases  |Description                            |
-|----------------|---------|---------------------------------------|
-|`KC_NO`         |         |Ignore this key (NOOP)                 |
-|`KC_TRANSPARENT`|`KC_TRNS`|Use the next lowest non-transparent key|
+|Key             |Aliases             |Description                            |
+|----------------|--------------------|---------------------------------------|
+|`KC_NO`         |`XXXXXXX`           |Ignore this key (NOOP)                 |
+|`KC_TRANSPARENT`|`KC_TRNS`, `_______`|Use the next lowest non-transparent key|

+ 32 - 26
docs/keycodes_us_ansi_shifted.md

@@ -1,31 +1,37 @@
 # US ANSI Shifted Symbols
 
-These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboards. They do not have dedicated keycodes but are instead typed by holding down shift and then sending a keycode.
+These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboard. They do not have keycodes of their own but are simply shortcuts for `LSFT(kc)`, and as such send a Left Shift with the unshifted keycode, not the symbol itself.
 
-It's important to remember that all of these keycodes send a left shift - this may cause unintended actions if unaccounted for. The short code is preferred in most situations.
+## Caveats
 
-## US ANSI Shifted Keycodes
+Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored.
 
-|Key                     |Aliases           |Description        |
-|------------------------|------------------|-------------------|
-|`KC_TILDE`              |`KC_TILD`         |`~`                |
-|`KC_EXCLAIM`            |`KC_EXLM`         |`!`                |
-|`KC_AT`                 |                  |`@`                |
-|`KC_HASH`               |                  |`#`                |
-|`KC_DOLLAR`             |`KC_DLR`          |`$`                |
-|`KC_PERCENT`            |`KC_PERC`         |`%`                |
-|`KC_CIRCUMFLEX`         |`KC_CIRC`         |`^`                |
-|`KC_AMPERSAND`          |`KC_AMPR`         |`&`                |
-|`KC_ASTERISK`           |`KC_ASTR`         |`*`                |
-|`KC_LEFT_PAREN`         |`KC_LPRN`         |`(`                |
-|`KC_RIGHT_PAREN`        |`KC_RPRN`         |`)`                |
-|`KC_UNDERSCORE`         |`KC_UNDS`         |`_`                |
-|`KC_PLUS`               |                  |`+`                |
-|`KC_LEFT_CURLY_BRACE`   |`KC_LCBR`         |`{`                |
-|`KC_RIGHT_CURLY_BRACE`  |`KC_RCBR`         |`}`                |
-|`KC_PIPE`               |                  |<code>&#124;</code>|
-|`KC_COLON`              |`KC_COLN`         |`:`                |
-|`KC_DOUBLE_QUOTE`       |`KC_DQT`/`KC_DQUO`|`"`                |
-|`KC_LEFT_ANGLE_BRACKET` |`KC_LT`/`KC_LABK` |`<`                |
-|`KC_RIGHT_ANGLE_BRACKET`|`KC_GT`/`KC_RABK` |`>`                |
-|`KC_QUESTION`           |`KC_QUES`         |`?`                |
+Additionally, you may run into issues when using Remote Desktop Connection on Windows. Because these codes send shift very fast, Remote Desktop may miss the codes.
+
+To fix this, open Remote Desktop Connection, click on "Show Options", open the the "Local Resources" tab. In the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly.
+
+## Keycodes
+
+|Key                     |Aliases            |Description        |
+|------------------------|-------------------|-------------------|
+|`KC_TILDE`              |`KC_TILD`          |`~`                |
+|`KC_EXCLAIM`            |`KC_EXLM`          |`!`                |
+|`KC_AT`                 |                   |`@`                |
+|`KC_HASH`               |                   |`#`                |
+|`KC_DOLLAR`             |`KC_DLR`           |`$`                |
+|`KC_PERCENT`            |`KC_PERC`          |`%`                |
+|`KC_CIRCUMFLEX`         |`KC_CIRC`          |`^`                |
+|`KC_AMPERSAND`          |`KC_AMPR`          |`&`                |
+|`KC_ASTERISK`           |`KC_ASTR`          |`*`                |
+|`KC_LEFT_PAREN`         |`KC_LPRN`          |`(`                |
+|`KC_RIGHT_PAREN`        |`KC_RPRN`          |`)`                |
+|`KC_UNDERSCORE`         |`KC_UNDS`          |`_`                |
+|`KC_PLUS`               |                   |`+`                |
+|`KC_LEFT_CURLY_BRACE`   |`KC_LCBR`          |`{`                |
+|`KC_RIGHT_CURLY_BRACE`  |`KC_RCBR`          |`}`                |
+|`KC_PIPE`               |                   |<code>&#124;</code>|
+|`KC_COLON`              |`KC_COLN`          |`:`                |
+|`KC_DOUBLE_QUOTE`       |`KC_DQUO`, `KC_DQT`|`"`                |
+|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<`                |
+|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>`                |
+|`KC_QUESTION`           |`KC_QUES`          |`?`                |

+ 9 - 3
docs/keymap.md

@@ -89,11 +89,15 @@ There are 3 main sections of a `keymap.c` file you'll want to concern yourself w
 
 At the top of the file you'll find this:
 
-    #include "clueboard.h"
+    #include QMK_KEYBOARD_H
 
     // Helpful defines
     #define GRAVE_MODS  (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
-    #define _______ KC_TRNS
+
+    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
+     *  You can use _______ in place for KC_TRNS (transparent)   *
+     *  Or you can use XXXXXXX for KC_NO (NOOP)                  *
+     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
     // Each layer gets a name for readability.
     // The underscores don't mean anything - you can
@@ -105,7 +109,9 @@ At the top of the file you'll find this:
     #define _FL 1
     #define _CL 2
 
-These are some handy definitions we can use when building our keymap and our custom function. The `GRAVE_MODS` definition will be used later in our custom function. The `_______` define makes it easier to see what keys a layer is overriding, while the `_BL`, `_FL`, and `_CL` defines make it easier to refer to each of our layers.
+These are some handy definitions we can use when building our keymap and our custom function. The `GRAVE_MODS` definition will be used later in our custom function, and the following `_BL`, `_FL`, and `_CL` defines make it easier to refer to each of our layers.
+
+Note: You may also find some older keymap files may also have a define(s) for `_______` and/or `XXXXXXX`. These can be used in place for `KC_TRNS` and `KC_NO` respectively, making it easier to see what keys a layer is overriding. These definitions are now unecessary, as they are included by default.
 
 ### Layers and Keymaps
 

+ 2 - 2
docs/newbs.md

@@ -6,13 +6,13 @@ Not sure if your keyboard can run QMK? If it's a mechanical keyboard you built y
 
 ## Overview
 
-There are 4 main sections to this guide:
+There are 5 main sections to this guide:
 
 * [Getting Started](newbs_getting_started.md)
 * [Building Your First Firmware](newbs_building_firmware.md)
 * [Flashing Firmware](newbs_flashing.md)
 * [Testing and Debugging](newbs_testing_debugging.md)
+* [Best Practices](newbs_best_practices.md)
 * [Learn More with these Resources](newbs_learn_more_resources.md)
 
 This guide is focused on helping someone who has never compiled software before. It makes choices and recommendations based on that viewpoint. There are alternative methods for many of these procedures, and we support most of those alternatives. If you have any doubt about how to accomplish a task you can [ask us for guidance](getting_started_getting_help.md).
-

+ 163 - 0
docs/newbs_best_practices.md

@@ -0,0 +1,163 @@
+# Best Practices
+
+## Or, "How I Learned to Stop Worrying and Love Git."
+
+This document aims to instruct novices in the best ways to have a smooth experience in contributing to QMK. We will walk through the process of contributing to QMK, detailing some ways to make this task easier, and then later we'll break some things in order to teach you how to fix them.
+
+This document assumes a few things:
+
+1. You have a GitHub account, and have [forked the qmk_firmware repository](getting_started_github.md) to your account.
+2. You've [set up your build environment](newbs_getting_started.md?id=environment-setup).
+
+
+## Your fork's master: Update Often, Commit Never
+
+It is highly recommended for QMK development, regardless of what is being done or where, to keep your `master` branch updated, but ***never*** commit to it. Instead, do all your changes in a development branch and issue pull requests from your branches when you're developing.
+
+To reduce the chances of merge conflicts &mdash; instances where two or more users have edited the same part of a file concurrently &mdash; keep your `master` branch relatively up-to-date, and start any new developments by creating a new branch.
+
+### Updating your master branch
+
+To keep your `master` branch updated, it is recommended to add the QMK Firmware repository ("repo") as a remote repository in git. To do this, open your Git command line interface and enter:
+
+```
+git remote add upstream https://github.com/qmk/qmk_firmware.git
+```
+
+To verify that the repository has been added, run `git remote -v`, which should return the following:
+
+```
+$ git remote -v
+origin  https://github.com/<your_username>/qmk_firmware.git (fetch)
+origin  https://github.com/<your_username>/qmk_firmware.git (push)
+upstream        https://github.com/qmk/qmk_firmware.git (fetch)
+upstream        https://github.com/qmk/qmk_firmware.git (push)
+```
+
+Now that this is done, you can check for updates to the repo by running `git fetch upstream`. This retrieves the branches and tags &mdash; collectively referred to as "refs" &mdash; from the QMK repo, which now has the nickname `upstream`. We can now compare the data on our fork `origin` to that held by QMK.
+
+To update your fork's master, run the following, hitting the Enter key after each line:
+
+```
+git checkout master
+git fetch upstream
+git pull upstream master
+git push origin master
+```
+
+This switches you to your `master` branch, retrieves the refs from the QMK repo, downloads the current QMK `master` branch to your computer, and then uploads it to your fork.
+
+### Making Changes
+
+To make changes, create a new branch by entering:
+
+```
+git checkout -b dev_branch
+git push --set-upstream origin dev_branch
+```
+
+This creates a new branch named `dev_branch`, checks it out, and then saves the new branch to your fork. The `--set-upstream` argument tells git to use your fork and the `dev_branch` branch every time you use `git push` or `git pull` from this branch. It only needs to be used on the first push; after that, you can safely use `git push` or `git pull`, without the rest of the arguments.
+
+!> With `git push`, you can use `-u` in place of `--set-upstream` &mdash; `-u` is an alias for `--set-upstream`.
+
+You can name your branch nearly anything you want, though it is recommended to name it something related to the changes you are going to make.
+
+By default `git checkout -b` will base your new branch on the branch that is checked out. You can base your new branch on an existing branch that is not checked out by adding the name of the existing branch to the command:
+
+```
+git checkout -b dev_branch master
+```
+
+Now that you have a development branch, open your text editor and make whatever changes you need to make. It is recommended to make many small commits to your branch; that way, any change that causes issues can be more easily traced and undone if needed. To make your changes, edit and save any files that need to be updated, add them to Git's *staging area*, and then commit them to your branch:
+
+```
+git add path/to/updated_file
+git commit -m "My commit message."
+```
+
+`git add` adds files that have been changed to Git's *staging area*, which is Git's "loading zone." This contains the changes that are going to be *committed* by `git commit`, which saves the changes to the repo. Use descriptive commit messages so you can know what was changed at a glance.
+
+!> If you've changed a lot of files, but all the files are part of the same change, you can use `git add .` to add all the changed files that are in your current directory, rather than having to add each file individually.
+
+### Publishing Your Changes
+
+The last step is to push your changes to your fork. To do this, enter `git push`. Git now publishes the current state of `dev_branch` to your fork.
+
+
+## Resolving Merge Conflicts
+
+Sometimes when your work in a branch takes a long time to complete, changes that have been made by others conflict with changes you have made to your branch when you open a pull request. This is called a *merge conflict*, and is what happens when multiple people edit the same parts of the same files.
+
+### Rebasing Your Changes
+
+A *rebase* is Git's way of taking changes that were applied at one point, reversing them, and then applying the same changes to another point. In the case of a merge conflict, you can rebase your branch to grab the changes that were made between when you created your branch and the present time.
+
+To start, run the following:
+
+```
+git fetch upstream
+git rev-list --left-right --count HEAD...upstream/master
+```
+
+The `git rev-list` command entered here returns the number of commits that differ between the current branch and QMK's master branch. We run `git fetch` first to make sure we have the refs that represent the current state of the upstream repo. The output of the `git rev-list` command entered returns two numbers:
+
+```
+$ git rev-list --left-right --count HEAD...upstream/master
+7       35
+```
+
+The first number represents the number of commits on the current branch since it was created, and the second number is the number of commits made to `upstream/master` since the current branch was created, and thus, the changes that are not recorded in the current branch.
+
+Now that the current states of both the current branch and the upstream repo are known, we can start a rebase operation:
+
+```
+git rebase upstream/master
+```
+
+This tells Git to undo the commits on the current branch, and then reapply them against QMK's master branch.
+
+```
+$ git rebase upstream/master
+First, rewinding head to replay your work on top of it...
+Applying: Commit #1
+Using index info to reconstruct a base tree...
+M       conflicting_file_1.txt
+Falling back to patching base and 3-way merge...
+Auto-merging conflicting_file_1.txt
+CONFLICT (content): Merge conflict in conflicting_file_1.txt
+error: Failed to merge in the changes.
+hint: Use 'git am --show-current-patch' to see the failed patch
+Patch failed at 0001 Commit #1
+
+Resolve all conflicts manually, mark them as resolved with
+"git add/rm <conflicted_files>", then run "git rebase --continue".
+You can instead skip this commit: run "git rebase --skip".
+To abort and get back to the state before "git rebase", run "git rebase --abort".
+```
+
+This tells us that we have a merge conflict, and gives the name of the file with the conflict. Open the conflicting file in your text editor, and somewhere in the file, you'll find something like this:
+
+```
+<<<<<<< HEAD
+<p>For help with any issues, email us at support@webhost.us.</p>
+=======
+<p>Need help? Email support@webhost.us.</p>
+>>>>>>> Commit #1
+```
+
+The line `<<<<<<< HEAD` marks the beginning of a merge conflict, and the `>>>>>>> Commit #1` line marks the end, with the conflicting sections separated by `=======`. The part on the `HEAD` side is from the QMK master version of the file, and the part marked with the commit message is from the current branch and commit.
+
+Because Git tracks *changes to files* rather than the contents of the files directly, if Git can't find the text that was in the file previous to the commit that was made, it won't know how to edit the file. Re-editing the file will solve the conflict. Make your changes, and then save the file.
+
+```
+<p>Need help? Email support@webhost.us.</p>
+```
+
+Now run:
+
+```
+git add conflicting_file_1.txt
+git rebase --continue
+```
+
+Git logs the changes to the conflicting file, and continues applying the commits from our branch until it reaches the end.

+ 15 - 1
docs/newbs_building_firmware.md

@@ -16,12 +16,26 @@ Start by navigating to the `keymaps` folder for your keyboard.
 
 ?> Windows:
 
-    start keyboards/<keyboard_folder>/keymaps
+    start .\\keyboards\\<keyboard_folder>\\keymaps
 
 ## Create a Copy Of The `default` Keymap
 
 Once you have the `keymaps` folder open you will want to create a copy of the `default` folder. We highly recommend you name your folder the same as your GitHub username, but you can use any name you want as long as it contains only lower case letters, numbers, and the underscore character.
 
+To automate the process, you also have the option to run the `new_keymap.sh` script. 
+
+Navigate to the `qmk_firmware/util` directory and type the following:
+
+```
+./new_keymap.sh <keyboard path> <username>
+```
+
+For example, for a user named John, trying to make a new keymap for the 1up60hse, they would type in
+
+```
+./new_keymap.sh 1upkeyboards/1up60hse john
+```
+
 ## Open `keymap.c` In Your Favorite Text Editor
 
 Open up your `keymap.c`. Inside this file you'll find the structure that controls how your keyboard behaves. At the top of `keymap.c` there may be some defines and enums that make the keymap easier to read. Farther down you'll find a line that looks like this:

+ 38 - 40
docs/newbs_getting_started.md

@@ -1,99 +1,97 @@
 # Introduction
 
-Your computer keyboard has a processor inside of it, not unlike the one inside your computer. This processor runs software that is responsible for detecting button presses and sending reports about the state of the keyboard when they are pressed or released. QMK fills the role of that software, detecting button presses and passing that information on to the host computer. When you build your custom layout you are creating the equivalent of an .exe for your keyboard.
+Your computer keyboard has a processor inside of it, not unlike the one inside your computer. This processor runs software that is responsible for detecting button presses and sending reports about the state of the keyboard when buttons are pressed or released. QMK fills the role of that software, detecting button presses and passing that information on to the host computer. When you build your custom keymap, you are creating the equivalent of an executable program for your keyboard.
 
-QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful layouts, you only have to follow a few simple syntax rules.
+QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful keymaps — you only have to follow a few simple syntax rules.
 
 # Getting Started
 
-Before you can build keymaps you need to install some software and setup your build environment. This only has to be done one time no matter how many keyboards you want to compile firmware for.
+Before you can build keymaps, you need to install some software and set up your build environment. This only has to be done once no matter how many keyboards you plan to compile firmware for.
 
 ## Download Software
 
 ### Text Editor
 
-You'll need a program that can edit and save **plain text** files. If you are on Windows you can make due with Notepad, and on Linux you can use Gedit, both of which are simple but functional text editors. On macOS be careful with TextEdit.app, it will not save plain text files unless you make sure to select "Make Plain text" from the "Format" menu, or you can use another program such as Sublime Text.
+You'll need a program that can edit and save **plain text** files. If you're on Windows you can make do with Notepad, and on Linux you can use gedit. Both of these are simple but functional text editors. On macOS, be careful with the default TextEdit app: it will not save plain text files unless you explicitly select _Make Plain Text_ from the _Format_ menu.
+
+You can also download and install a dedicated text editor like [Sublime Text](https://www.sublimetext.com/) or [VS Code](https://code.visualstudio.com/). This is probably the best way to go regardless of platform, as these programs are specifically made for editing code.
 
 ?> Not sure which text editor to use? Laurence Bradford wrote [a great introduction](https://learntocodewith.me/programming/basics/text-editors/) to the subject.
 
 ### QMK Toolbox
 
-QMK Toolbox is an optional graphical Windows and macOS program that allows you to both program and debug your custom keyboard. You will likely prefer it to easily flash your keyboard and receive the debugging messages that your keyboard will print.
-
-Download the files from the links below:
-
-For Windows: "qmk_toolbox.exe" or "qmk_toolbox_install.exe" (with installer)
+QMK Toolbox is an optional graphical program for Windows and macOS that allows you to both program and debug your custom keyboard. You will likely find it invaluable for easily flashing your keyboard and viewing debug messages that it prints.
 
-For Mac: "QMK.Toolbox.app.zip" or "QMK.Toolbox.pkg" (with installer)
+[Download the latest release here.](https://github.com/qmk/qmk_toolbox/releases/latest)
 
-* [Newest Release](https://github.com/qmk/qmk_toolbox/releases/latest)
-* [Source Code](https://github.com/qmk/qmk_toolbox/)
+* For Windows: `qmk_toolbox.exe` (portable) or `qmk_toolbox_install.exe` (installer)
+* For macOS: `QMK.Toolbox.app.zip` (portable) or `QMK.Toolbox.pkg` (installer)
 
-## Environment Setup
+## Set Up Your Environment
 
-We've tried to make QMK as easy to setup as possible. You only have to prepare your Linux or Unix environment and let QMK install the rest.
+We've tried to make QMK as easy to set up as possible. You only have to prepare your Linux or Unix environment, then let QMK install the rest.
 
-?> If you haven't worked with the Linux/Unix command line before there are a few basic concepts and commands you should learn. These resources will teach you enough to work with QMK:<br>
+?> If you haven't worked with the Linux/Unix command line before, there are a few basic concepts and commands you should learn. These resources will teach you enough to be able to work with QMK:<br>
 [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)<br>
 [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html)
 
 ### Windows
 
-You will need to install msys2 and git.
+You will need to install MSYS2 and Git.
 
-* Follow the installation instructions on the msys2 homepage: http://www.msys2.org
-* Close any open msys2 terminals, and open a new terminal
-* Install git by running this command: `pacman -S git`
+* Follow the installation instructions on the [MSYS2 homepage](http://www.msys2.org).
+* Close any open MSYS2 terminals and open a new MSYS2 MinGW 64-bit terminal.
+* Install Git by running this command: `pacman -S git`.
 
 ### macOS
 
-You will need to install homebrew. Follow the instructions on the homebrew homepage: https://brew.sh
+You will need to install Homebrew. Follow the instructions on the [Homebrew homepage](https://brew.sh).
 
-After homebrew is installed continue with "Download QMK", following step "Setup QMK" runs a script that will install other packages.
+After Homebrew is installed, continue with _Set Up QMK_. In that step you will run a script that will install other packages.
 
 ### Linux
 
-You will need to install git. It's extremely likely you already have it, but if not one of the following commands should install it:
+You will need to install Git. It's very likely that you already have it, but if not, one of the following commands should install it:
 
-* Debian/Ubuntu/Devuan: `apt-get install git`
-* Fedora/Redhat/Centos: `yum install git`
+* Debian / Ubuntu / Devuan: `apt-get install git`
+* Fedora / Red Hat / CentOS: `yum install git`
 * Arch: `pacman -S git`
 
-## Download QMK
+?> Docker is also an option on all platforms. [Click here for details.](getting_started_build_tools.md#docker)
 
-Once you have setup your Linux/Unix environment you are ready to download QMK. We will do this by using git to "clone" the QMK repository. Open a Terminal or MSYS2 Console window and leave it open for the remainder of this guide. Inside that window run these two commands:
+## Set Up QMK
+
+Once you have set up your Linux/Unix environment, you are ready to download QMK. We will do this by using Git to "clone" the QMK repository. Open a Terminal or MSYS2 MinGW window and leave it open for the remainder of this guide. Inside that window run these two commands:
 
     git clone https://github.com/qmk/qmk_firmware.git
     cd qmk_firmware
 
-?> If you already know [how to use GitHub](getting_started_github.md) we recommend you create and clone your own fork instead. If you don't know what that means you can safely ignore this message.
-
-## Setup QMK
+?> If you already know [how to use GitHub](getting_started_github.md), we recommend that you create and clone your own fork instead. If you don't know what that means, you can safely ignore this message.
 
-QMK comes with a script to help you setup the rest of what you'll need. You should run it now by typing in this command:
+QMK comes with a script to help you set up the rest of what you'll need. You should run it now by typing in this command:
 
-    ./util/qmk_install.sh
+    util/qmk_install.sh
 
 ## Test Your Build Environment
 
-Now that your QMK build environment is setup you can build a firmware for your keyboard. Start by trying to build the default layout for your keyboard. You should be able to do that with a command in this format:
+Now that your QMK build environment is set up, you can build a firmware for your keyboard. Start by trying to build the keyboard's default keymap. You should be able to do that with a command in this format:
 
     make <keyboard>:default
 
-For example, to build a firmware for a Clueboard 66% use:
+For example, to build a firmware for a Clueboard 66% you would use:
 
     make clueboard/66/rev3:default
 
 When it is done you should have a lot of output that ends similar to this:
 
 ```
-Linking: .build/clueboard_66_rev2_default.elf                                                       [OK]
-Creating load file for flashing: .build/clueboard_66_rev2_default.hex                               [OK]
-Copying clueboard_66_rev2_default.hex to qmk_firmware folder                                        [OK]
-Checking file size of clueboard_66_rev2_default.hex                                                 [OK]
- * File size is fine - 25174/28672
+Linking: .build/clueboard_66_rev3_default.elf                                                       [OK]
+Creating load file for flashing: .build/clueboard_66_rev3_default.hex                               [OK]
+Copying clueboard_66_rev3_default.hex to qmk_firmware folder                                        [OK]
+Checking file size of clueboard_66_rev3_default.hex                                                 [OK]
+ * The firmware size is fine - 26356/28672 (2316 bytes free)
 ```
 
-## Creating Your Layout
+# Creating Your Keymap
 
-Now you are ready to create your own personal layout. Move on to [Building Your First Firmware](newbs_building_firmware.md) for that.
+You are now ready to create your own personal keymap! Move on to [Building Your First Firmware](newbs_building_firmware.md) for that.

+ 9 - 7
docs/newbs_learn_more_resources.md

@@ -1,13 +1,15 @@
 # Learning Resources
-These resources are aimed at giving new members in the qmk community more understanding to the information provided in the newbs docs.
+
+These resources are aimed at giving new members in the QMK community more understanding to the information provided in the Newbs docs.
 
 Git resources:
-*
-*[Great General Tutorial](https://www.codecademy.com/learn/learn-git)
-*[Git Game To Learn From Examples](https://learngitbranching.js.org/)
-*[Git Resources to Learn More About Github](getting_started_github.md)
-*[Git Resources Aimed Specificly toward QMK](contributing.md)
+
+* [Great General Tutorial](https://www.codecademy.com/learn/learn-git)
+* [Git Game To Learn From Examples](https://learngitbranching.js.org/)
+* [Git Resources to Learn More About Github](getting_started_github.md)
+* [Git Resources Aimed Specifically toward QMK](contributing.md)
 
 
 Command Line resources:
-*[Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line)
+
+* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line)

+ 1 - 1
docs/newbs_testing_debugging.md

@@ -28,6 +28,6 @@ Sometimes it's useful to print debug messages from within your [custom code](cus
 After that you can use a few different print functions:
 
 * `print("string")`: Print a simple string.
-* `sprintf("%s string", var)`: Print a formatted string
+* `uprintf("%s string", var)`: Print a formatted string
 * `dprint("string")` Print a simple string, but only when debug mode is enabled
 * `dprintf("%s string", var)`: Print a formatted string, but only when debug mode is enabled

+ 13 - 12
docs/quantum_keycodes.md

@@ -8,15 +8,16 @@ On this page we have documented keycodes between `0x00FF` and `0xFFFF` which are
 
 ## QMK Keycodes
 
-|Key          |Aliases    |Description                                                          |
-|-------------|-----------|---------------------------------------------------------------------|
-|`RESET`      |           |Put the keyboard into DFU mode for flashing                          |
-|`DEBUG`      |           |Toggle debug mode                                                    |
-|`KC_GESC`    |`GRAVE_ESC`|Escape when tapped, <code>&#96;</code> when pressed with Shift or GUI|
-|`KC_LSPO`    |           |Left Shift when held, `(` when tapped                                |
-|`KC_RSPC`    |           |Right Shift when held, `)` when tapped                               |
-|`KC_LEAD`    |           |The [Leader key](feature_leader_key.md)                              |
-|`KC_LOCK`    |           |The [Lock key](feature_key_lock.md)                                  |
-|`FUNC(n)`    |`F(n)`     |Call `fn_action(n)` (deprecated)                                     |
-|`M(n)`       |           |Call macro `n`                                                       |
-|`MACROTAP(n)`|           |Macro-tap `n` idk FIXME                                              |
+|Key            |Aliases    |Description                                                          |
+|---------------|-----------|---------------------------------------------------------------------|
+|`RESET`        |           |Put the keyboard into DFU mode for flashing                          |
+|`DEBUG`        |           |Toggle debug mode                                                    |
+|`EEPROM_RESET` |`EEP_RST`  |Resets EEPROM state by reinitializing it                             |
+|`KC_GESC`      |`GRAVE_ESC`|Escape when tapped, <code>&#96;</code> when pressed with Shift or GUI|
+|`KC_LSPO`      |           |Left Shift when held, `(` when tapped                                |
+|`KC_RSPC`      |           |Right Shift when held, `)` when tapped                               |
+|`KC_LEAD`      |           |The [Leader key](feature_leader_key.md)                              |
+|`KC_LOCK`      |           |The [Lock key](feature_key_lock.md)                                  |
+|`FUNC(n)`      |`F(n)`     |Call `fn_action(n)` (deprecated)                                     |
+|`M(n)`         |           |Call macro `n`                                                       |
+|`MACROTAP(n)`  |           |Macro-tap `n` idk FIXME                                              |

+ 1 - 1
docs/redirects.json

@@ -34,7 +34,7 @@
             },
             {
                 "from": "space_cadet_shift.html",
-                "to": "feature_space_cadet.html"
+                "to": "feature_space_cadet_shift.html"
             },
             {
                 "from": "tap_dance.html",

+ 119 - 0
docs/ref_functions.md

@@ -0,0 +1,119 @@
+# List of Useful Core Functions To Make Your Keyboard Better
+
+There are a lot of hidden functions in QMK that are incredible useful, or may add a bit of functionality that you've been wanting.  Functions that are specific to certain features are not included here, as those will be on their respective feature page.
+
+## (OLKB) Tri Layers
+
+There are actually separate functions that you can use there, depending on what you're after.
+
+### `update_tri_layer(x, y, z)`
+
+The first is the `update_tri_layer(x, y, z)` function.   This function check to see if layers `x` and `y` are both on. If they are both on, then it runs on layer `z`.  Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it runs off layer `z`.
+
+This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this.
+
+#### Example
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    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;
+    }
+  return true;
+}
+```
+
+### `update_tri_layer_state(state, x, y, z)`
+The other function is `update_tri_layer_state(state, x, y, z)`.  This function is meant to be called from they [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code).  This means that any time that you use a keycode to change the layer, this will be checked.  So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check.
+
+The caveat to this method is that you cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it.
+
+#### Example
+
+```c
+uint32_t layer_state_set_user(uint32_t state) {
+  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
+```
+
+Alternatively, you don't have to immediately "return" the value.  This is useful if you want to add multiple tri layers, or if you want to add additional effects.
+
+```c
+uint32_t layer_state_set_user(uint32_t state) {
+  state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+  state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL);
+  return state;
+}
+```
+
+## Setting the Persistent Default Layer
+
+Do you want to set the default layer, so that it's retained even after you unplug the board?  If so, this is the function for you.
+
+To use this, you would use `set_single_persistent_default_layer(layer)`.  If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK).
+
+This will set the default layer, update the persistent settings, and play a tune if you have [Audio](feature_audio.md) enabled on your board, and the default layer sounds set.
+
+To configure the default layer sounds, you would want to define this in your `config.h` file, like this:
+
+```c
+#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
+                              SONG(COLEMAK_SOUND), \
+                              SONG(DVORAK_SOUND) \
+                            }
+```
+
+
+?> There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use.
+
+## Reseting the keyboard
+
+There is the `RESET` quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that.
+
+And to do so, add `reset_keyboard()` to your function or macro, and this will reset to bootloader.
+
+## Wiping the EEPROM (Persistent Storage)
+
+If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage).  Bootmagic is one way to do this, but if that isn't enabled, then you can use a custom macro to do so.
+
+To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default.
+
+## Tap random key
+
+If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`).  
+
+?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords.
+
+## Software Timers
+
+It's possible to start timers and read values for time-specific events. Here's an example:
+
+```c
+static uint16_t key_timer;
+key_timer = timer_read();
+
+if (timer_elapsed(key_timer) < 100) {
+  // do something if less than 100ms have passed
+} else {
+  // do something if 100ms or more have passed
+}
+```

+ 195 - 0
docs/reference_configurator_support.md

@@ -0,0 +1,195 @@
+# Supporting Your Keyboard in QMK Configurator
+
+This page covers how to properly support keyboards in the [QMK Configurator](https://config.qmk.fm/).
+
+
+## How the Configurator Understands Keyboards
+
+To understand how the Configurator understands keyboards, first one must understand layout macros. For this exercise, we're going to imagine a 17-key numpad PCB, which we're going to call `numpad`.
+
+```
+┌───┬───┬───┬───┐
+│NLk│ / │ * │ - │
+├───┼───┼───┼───┤
+│7  │8  │9  │ + │
+├───┼───┼───┤   │
+│4  │5  │6  │   │
+├───┼───┼───┼───┤
+│1  │2  │3  │Ent│
+├───┴───┼───┤   │
+│0      │ . │   │
+└───────┴───┴───┘
+```
+
+?> For more on layout macros, see [Understanding QMK: Matrix Scanning](understanding_qmk.md?id=matrix-scanning) and [Understanding QMK: Matrix to Physical Layout Map](understanding_qmk.md?id=matrix-to-physical-layout-map).
+
+The Configurator's API reads the keyboard's `.h` file from `qmk_firmware/keyboards/<keyboard>/<keyboard>.h`. For our numpad, this file would be `qmk_firmware/keyboards/numpad/numpad.h`:
+
+```c
+#pragma once
+
+#define LAYOUT( \
+    k00, k01, k02, k03, \
+    k10, k11, k12, k13, \
+    k20, k21, k22,      \
+    k30, k31, k32, k33, \
+    k40,      k42       \
+  ) { \
+    { k00, k01,   k02, k03   }, \
+    { k10, k11,   k12, k13   }, \
+    { k20, k21,   k22, KC_NO }, \
+    { k30, k31,   k32, k33   }, \
+    { k40, KC_NO, k42, KC_NO }  \
+}
+```
+
+QMK uses `KC_NO` to designate places in the switch matrix where there is no switch. Sometimes, `XXX`, `___` or `____` are used as shorthand to make this section easier to read if it needs to be debugged. This is usually defined near the beginning of the `.h` file:
+
+```c
+#pragma once
+
+#define XXX KC_NO
+
+#define LAYOUT( \
+    k00, k01, k02, k03, \
+    k10, k11, k12, k13, \
+    k20, k21, k22,      \
+    k30, k31, k32, k33, \
+    k40,      k42       \
+  ) { \
+    { k00, k01, k02, k03 }, \
+    { k10, k11, k12, k13 }, \
+    { k20, k21, k22, XXX }, \
+    { k30, k31, k32, k33 }, \
+    { k40, XXX, k42, XXX }  \
+}
+```
+
+!> This usage differs from that of keymap macros, which almost always use `XXXXXXX` (seven capital X's) for `KC_NO` and `_______` (seven underscores) for `KC_TRNS`.
+
+!> To prevent user confusion, using `KC_NO` is preferred.
+
+The layout macro tells the Configurator that our keyboard has 17 keys, arranged in five rows of four columns each. Our switch positions are named `k<row><column>`, counting from 0. The names themselves actually don't matter, as long as they match between the top section, which receives the keycodes from the keymap, and the bottom half which designates where each key is in the matrix.
+
+To display our keyboard in a way that resembles the physical keyboard, we need to build a JSON file that tells the Configurator how to tie the physical locations and sizes of our keys to our switch matrix.
+
+## Building the JSON file
+
+To build the JSON file, the easiest way is to build the layout in [Keyboard Layout Editor](http://www.keyboard-layout-editor.com/) ("KLE"), from which we'll feed the Raw Data into a QMK tool that converts this data into a JSON the Configurator will read and use. Since KLE opens by default with a numpad layout, we're just going to remove the Getting Started instructions, and use what's left.
+
+Once the layout is as desired, move to the Raw Data tab in KLE, and copy the contents:
+
+```
+["Num Lock","/","*","-"],
+["7\nHome","8\n↑","9\nPgUp",{h:2},"+"],
+["4\n←","5","6\n→"],
+["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"],
+[{w:2},"0\nIns",".\nDel"]
+```
+
+To convert this data into our JSON, go to the [QMK KLE-JSON Converter](https://qmk.fm/converter/), paste the Raw Data into the Input field, and click the Convert button. After a moment, our JSON data will appear in the Output field. Copy the contents to a new text document, and name the document `info.json`, saving it in the same folder that contains `numpad.h`.
+
+Use the `keyboard_name` object to set the name of the keyboard. The `bootloader` object is deprecated, so it can be deleted. For instruction purposes, we will put each key's object on its own line. This is only to make the file more human-readable, and does not affect the Configurator's functionality.
+
+```json
+{
+    "keyboard_name": "Numpad",
+    "url": "",
+    "maintainer": "qmk",
+    "tags": {
+        "form_factor": "numpad"
+    },
+    "width": 4,
+    "height": 5,
+    "layouts": {
+        "LAYOUT": {
+            "layout": [
+                {"label":"Num Lock", "x":0, "y":0},
+                {"label":"/", "x":1, "y":0},
+                {"label":"*", "x":2, "y":0},
+                {"label":"-", "x":3, "y":0},
+                {"label":"7", "x":0, "y":1},
+                {"label":"8", "x":1, "y":1},
+                {"label":"9", "x":2, "y":1},
+                {"label":"+", "x":3, "y":1, "h":2},
+                {"label":"4", "x":0, "y":2},
+                {"label":"5", "x":1, "y":2},
+                {"label":"6", "x":2, "y":2},
+                {"label":"1", "x":0, "y":3},
+                {"label":"2", "x":1, "y":3},
+                {"label":"3", "x":2, "y":3},
+                {"label":"Enter", "x":3, "y":3, "h":2},
+                {"label":"0", "x":0, "y":4, "w":2},
+                {"label":".", "x":2, "y":4}
+            ]
+        }
+    }
+}
+```
+
+The `layouts` object contains the data that represents the physical layout of the keyboard. It has an object `LAYOUT`, which needs to match the name of our layout macro from `numpad.h`. The `LAYOUT` object itself has an object named `layout`, which contains one JSON object for each physical key on our keyboard, formatted as follows:
+
+```
+  ┌ The name of the key. Not displayed in the Configurator.
+  │                   ┌ The key's X-axis location, in key units from the
+  │                   │ keyboard's left edge.
+  │                   │      ┌ The key's Y-axis location, in key units from
+  │                   │      │ the keyboard's top (rear-facing) edge.
+  ↓                   ↓      ↓
+{"label":"Num Lock", "x":0, "y":0},
+```
+
+Some objects will also have `"w"` and `"h"` keys, which represent a key's width and height, respectively.
+
+?> For more on the `info.json` files, see [QMK Keyboard Guidelines: Keyboard Metadata](hardware_keyboard_guidelines.md?id=keyboard-metadata)
+
+
+## How the Configurator Programs Keys
+
+The Configurator's API uses the layout macro and the JSON file we've given it to create a visual representation of the keyboard that has each visual object tied to a specific key, in sequence:
+
+key in layout macro | JSON object used
+:---: | :----
+k00   | {"label":"Num Lock", "x":0, "y":0}
+k01   | {"label":"/", "x":1, "y":0}
+k02   | {"label":"*", "x":2, "y":0}
+k03   | {"label":"-", "x":3, "y":0}
+k10   | {"label":"7", "x":0, "y":1}
+k11   | {"label":"8", "x":1, "y":1}
+k12   | {"label":"9", "x":2, "y":1}
+k13   | {"label":"+", "x":3, "y":1, "h":2}
+k20   | {"label":"4", "x":0, "y":2}
+k21   | {"label":"5", "x":1, "y":2}
+k22   | {"label":"6", "x":2, "y":2}
+k30   | {"label":"1", "x":0, "y":3}
+k31   | {"label":"2", "x":1, "y":3}
+k32   | {"label":"3", "x":2, "y":3}
+k33   | {"label":"Enter", "x":3, "y":3, "h":2}
+k40   | {"label":"0", "x":0, "y":4, "w":2}
+k42   | {"label":".", "x":2, "y":4}
+
+When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the Configurator builds a keymap file with `KC_NLCK` as the first key, and so on as the keymap is built. The `label` keys are not used; they are only for the user's reference in identifying specific keys when debugging the `info.json` file.
+
+
+## Issues and Hazards
+
+Currently, the Configurator does not support key rotation or non-rectangular key shapes like ISO Enter. Additionally, keys that are vertically-offset from their "row" &mdash; the arrow keys on 1800-layouts like the [TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/) being a prominent example &mdash; confuse the KLE-to-JSON Converter, if not adjusted for by the contributor of the `info.json` file.
+
+### Workarounds
+
+#### Non-rectangular keys
+
+For ISO Enter keys, QMK custom is to display it as a rectangular key, 1.25u wide and 2u high, aligned so its right edge is aligned with the right edge of the alphanumeric key block.
+
+![](https://i.imgur.com/JKngtTw.png)  
+*A 60% keyboard in standard ISO layout, as rendered by QMK Configurator.*
+
+#### Vertically-offset keys
+
+For vertically-offset keys, place them in KLE as if they were not offset, then edit the Y-values as needed in the converted JSON file
+
+![](https://i.imgur.com/fmDvDzR.png)  
+*An 1800-layout keyboard as rendered in Keyboard Layout Editor, without the vertical offset applied to the arrow keys.*
+
+![](https://i.imgur.com/8beYMBR.png)  
+*A Unix diff file, showing the changes needed to vertically-offset the arrow keys in our keyboard's JSON file.*

+ 2 - 2
docs/reference_glossary.md

@@ -128,12 +128,12 @@ The standard Deutsche (German) keyboard layout. Named for the first 6 letters on
 The term for pressing a key while a key is already held down. Variants include 2KRO, 6KRO, and NKRO.
 
 ## Scancode
-A 1 byte number that is sent as part of a HID report over USB that represents a single key. These numbers are documented in the [HID Usage Tables](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf) published by the [USB-IF](http://www.usb.org/).
+A 1 byte number that is sent as part of a HID report over USB that represents a single key. These numbers are documented in the [HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) published by the [USB-IF](http://www.usb.org/).
 
 ## Space Cadet Shift
 A special set of shift keys which allow you to type various types of braces by tapping the left or right shift one or more times.
 
-* [Space Cadet Shift Documentation](feature_space_cadet.md)
+* [Space Cadet Shift Documentation](feature_space_cadet_shift.md)
 
 ## Tap
 Pressing and releasing a key. In some situations you will need to distinguish between a key down and a key up event, and Tap always refers to both at once.

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 28 - 23
docs/understanding_qmk.md


+ 32 - 0
docs/zh/README.md

@@ -0,0 +1,32 @@
+# QMK鍵盤固件
+
+[![當前版本](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags)
+[![築邦](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware)
+[![不和諧](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh)
+[![文檔狀態](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm)
+[![GitHub的貢獻者](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly)
+[![GitHub的叉](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/)
+
+## 什麼是QMK固件?
+
+QMK是一個由社群維護的開源鍵盤韌體,其中包含了QMK Toolbox、qmk.fm和其它文件。QMK韌體是以[tmk\_keyboard](http://github.com/tmk/tmk_keyboard)為基礎,讓一些有用的功能在Atmel AVR控制器實現,使用於[OLKB](https://olkb.com)、[ergodox EZ](http://www.ergodox-ez.com),和[Clueboard](http://clueboard.co/)的產品中。它也被移植到使用ChibiOS的ARM晶片上。你也可以用它來讓你徒手佈線,或是客製的鍵盤PCB發揮功能。
+
+## 如何得到QMK
+
+如果你打算貢獻鍵盤佈局,鍵盤或功能QMK,最容易做的事情是[叉通過Github上爬行](https://github.com/qmk/qmk_firmware#fork-destination-box),和克隆你爬在本地進行更改,推動他們,然後打開從你的叉子[拉請求](https://github.com/qmk/qmk_firmware/pulls)。
+
+否則,您可以直接下載([拉鍊](https://github.com/qmk/qmk_firmware/zipball/master) [焦油](https://github.com/qmk/qmk_firmware/tarball/master)),或者通過GIT中克隆它(`git@github.com:qmk/qmk_firmware.git`)或HTTP(`https://github.com/qmk/qmk_firmware.git`)。
+
+## 如何編譯
+
+你可以編譯之前,你需要[安裝環境](getting_started_build_tools.md)用於AVR或/和ARM開發。一旦完成,你會使用`make`命令建立一個鍵盤並用以下符號鍵盤佈局
+
+    make planck/rev4:default
+
+這將建立`rev4` `planck`的修訂與`default`鍵盤映射。並非所有鍵盤有一個修訂版(也稱為子項目或文件夾),在這種情況下,它可以被省略:
+
+    make preonic:default
+
+## 如何赶近
+
+QMK有很多[特點](features.md)探索和很好的協議[參考文獻](http://docs.qmk.fm)挖通的。大部分功能通過修改[鍵盤映射(keymap.md),並改變[鍵碼](keycodes.md)冤大頭。

+ 99 - 0
docs/zh/_sidebar.md

@@ -0,0 +1,99 @@
+* [完全指南菜鳥](zh/newbs.md)
+  * [入門](zh/newbs_getting_started.md)
+  * [構建第一個固件](zh/newbs_building_firmware.md)
+  * [刷新固件](zh/newbs_flashing.md)
+  * [測試和調試](zh/newbs_testing_debugging.md)
+  * [最佳實踐](zh/newbs_best_practices.md)
+  * [學習資源](zh/newbs_learn_more_resources.md)
+
+* [QMK基礎](zh/README.md)
+  * [QMK簡介](zh/getting_started_introduction.md)
+  * [特約QMK](zh/contributing.md)
+  * [如何使用Github上](zh/getting_started_github.md)
+  * [獲得幫助](zh/getting_started_getting_help.md)
+
+* [常問問題](zh/faq.md)
+  * [常問問題](zh/faq_general.md)
+  * [構建/編譯QMK](zh/faq_build.md)
+  * [調試/故障排除QMK](zh/faq_debug.md)
+  * [鍵盤佈局](zh/faq_keymap.md)
+
+* 詳細指南
+  * [安裝編譯工具](zh/getting_started_build_tools.md)
+  * [流浪漢指南](zh/getting_started_vagrant.md)
+  * [構建/編譯器指令](zh/getting_started_make_guide.md)
+  * [刷新固件](zh/flashing.md)
+  * [定制功能](zh/custom_quantum_functions.md)
+  * [鍵盤映射概述](zh/keymap.md)
+
+* [硬件](zh/hardware.md)
+  * [AVR處理器](zh/hardware_avr.md)
+  * [司機](zh/hardware_drivers.md)
+
+* 參考
+  * [Keyboard Guidelines](zh/hardware_keyboard_guidelines.md)
+  * [Config Options](zh/config_options.md)
+  * [Keycodes](zh/keycodes.md)
+  * [Documentation Best Practices](zh/documentation_best_practices.md)
+  * [Documentation Templates](zh/documentation_templates.md)
+  * [Glossary](zh/reference_glossary.md)
+  * [Unit Testing](zh/unit_testing.md)
+  * [Useful Functions](zh/ref_functions.md)
+  * [Configurator Support](zh/reference_configurator_support.md)
+
+* [特點](zh/features.md)
+  * [Basic Keycodes](zh/keycodes_basic.md)
+  * [Quantum Keycodes](zh/quantum_keycodes.md)
+  * [Advanced Keycodes](zh/feature_advanced_keycodes.md)
+  * [Audio](zh/feature_audio.md)
+  * [Auto Shift](zh/feature_auto_shift.md)
+  * [Backlight](zh/feature_backlight.md)
+  * [Bluetooth](zh/feature_bluetooth.md)
+  * [Bootmagic](zh/feature_bootmagic.md)
+  * [Combos](zh/feature_combo)
+  * [Command](zh/feature_command.md)
+  * [Dynamic Macros](zh/feature_dynamic_macros.md)
+  * [Encoders](zh/feature_encoders.md)
+  * [Grave Escape](zh/feature_grave_esc.md)
+  * [Key Lock](zh/feature_key_lock.md)
+  * [Layouts](zh/feature_layouts.md)
+  * [Leader Key](zh/feature_leader_key.md)
+  * [Macros](zh/feature_macros.md)
+  * [Mouse Keys](zh/feature_mouse_keys.md)
+  * [One Shot Keys](zh/feature_advanced_keycodes.md#one-shot-keys)
+  * [Pointing Device](zh/feature_pointing_device.md)
+  * [PS/2 Mouse](zh/feature_ps2_mouse.md)
+  * [RGB Lighting](zh/feature_rgblight.md)
+  * [RGB Matrix](zh/feature_rgb_matrix.md)
+  * [Space Cadet Shift](zh/feature_space_cadet_shift.md)
+  * [Space Cadet Shift Enter](zh/feature_space_cadet_shift_enter.md)
+  * [Stenography](zh/feature_stenography.md)
+  * [Swap Hands](zh/feature_swap_hands.md)
+  * [Tap Dance](zh/feature_tap_dance.md)
+  * [Terminal](zh/feature_terminal.md)
+  * [Thermal Printer](zh/feature_thermal_printer.md)
+  * [Unicode](zh/feature_unicode.md)
+  * [Userspace](zh/feature_userspace.md)
+  * [US ANSI Shifted Keys](zh/keycodes_us_ansi_shifted.md)
+
+* 對於製造商和遊戲模組
+  * [Hand Wiring Guide](zh/hand_wire.md)
+  * [ISP Flashing Guide](zh/isp_flashing_guide.md)
+  * [ARM Debugging Guide](zh/arm_debugging.md)
+  * [I2C Driver](zh/i2c_driver.md)
+
+* 為了更深入的了解
+  * [How Keyboards Work](zh/how_keyboards_work.md)
+  * [Understanding QMK](zh/understanding_qmk.md)
+
+* 其它主題
+  * [Using Eclipse with QMK](zh/eclipse.md)
+
+* QMK內部(進行中)
+  * [Defines](zh/internals_defines.md)
+  * [Input Callback Reg](zh/internals_input_callback_reg.md)
+  * [Midi Device](zh/internals_midi_device.md)
+  * [Midi Device Setup Process](zh/internals_midi_device_setup_process.md)
+  * [Midi Util](zh/internals_midi_util.md)
+  * [Send Functions](zh/internals_send_functions.md)
+  * [Sysex Tools](zh/internals_sysex_tools.md)

+ 107 - 0
drivers/arm/i2c_master.c

@@ -0,0 +1,107 @@
+/* Copyright 2018 Jack Humbert
+ * Copyright 2018 Yiancar
+ *
+ * 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/>.
+ */
+
+/* This library is only valid for STM32 processors.
+ * This library follows the convention of the AVR i2c_master library.
+ * As a result addresses are expected to be already shifted (addr << 1).
+ * I2CD1 is the default driver which corresponds to pins B6 and B7. This
+ * can be changed.
+ * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
+ * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. Pins B6 and B7 are used
+ * but using any other I2C pins should be trivial.
+ */
+
+#include "i2c_master.h"
+#include "quantum.h"
+#include <string.h>
+#include <hal.h>
+
+static uint8_t i2c_address;
+
+// This configures the I2C clock to 400Mhz assuming a 72Mhz clock
+// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
+static const I2CConfig i2cconfig = {
+  STM32_TIMINGR_PRESC(15U) |
+  STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
+  STM32_TIMINGR_SCLH(15U)  | STM32_TIMINGR_SCLL(21U),
+  0,
+  0
+};
+
+__attribute__ ((weak))
+void i2c_init(void)
+{
+  setPinInput(B6); // Try releasing special pins for a short time
+  setPinInput(B7);
+  chThdSleepMilliseconds(10);
+
+  palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
+  palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
+
+  //i2cInit(); //This is invoked by halInit() so no need to redo it.
+}
+
+// This is usually not needed
+uint8_t i2c_start(uint8_t address)
+{
+  i2c_address = address;
+  i2cStart(&I2C_DRIVER, &i2cconfig);
+  return 0;
+}
+
+uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
+{
+  i2c_address = address;
+  i2cStart(&I2C_DRIVER, &i2cconfig);
+  return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout));
+}
+
+uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
+{
+  i2c_address = address;
+  i2cStart(&I2C_DRIVER, &i2cconfig);
+  return i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout));
+}
+
+uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
+{
+  i2c_address = devaddr;
+  i2cStart(&I2C_DRIVER, &i2cconfig);
+
+  uint8_t complete_packet[length + 1];
+  for(uint8_t i = 0; i < length; i++)
+  {
+    complete_packet[i+1] = data[i];
+  }
+  complete_packet[0] = regaddr;
+
+  return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
+}
+
+uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
+{
+  i2c_address = devaddr;
+  i2cStart(&I2C_DRIVER, &i2cconfig);
+  return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), regaddr, 1, data, length, MS2ST(timeout));
+}
+
+// This is usually not needed. It releases the driver to allow pins to become GPIO again.
+uint8_t i2c_stop(uint16_t timeout)
+{
+  i2cStop(&I2C_DRIVER);
+  return 0;
+}

+ 39 - 0
drivers/arm/i2c_master.h

@@ -0,0 +1,39 @@
+/* Copyright 2018 Jack Humbert
+ * Copyright 2018 Yiancar
+ *
+ * This program is free sofare: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Sofare 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/>.
+ */
+
+/* This library follows the convention of the AVR i2c_master library.
+ * As a result addresses are expected to be already shifted (addr << 1).
+ * I2CD1 is the default driver which corresponds to pins B6 and B7. This
+ * can be changed.
+ * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
+ * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
+ */
+
+#include "ch.h"
+#include <hal.h>
+
+#ifndef I2C_DRIVER
+  #define I2C_DRIVER I2CD1
+#endif
+
+void i2c_init(void);
+uint8_t i2c_start(uint8_t address);
+uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
+uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
+uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
+uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
+uint8_t i2c_stop(uint16_t timeout);

+ 1 - 1
drivers/arm/ws2812.c

@@ -183,7 +183,7 @@ void WS2812_send_color( uint8_t index ) {
   setColor(led_array[index].b, (fb+24*index)+16, sMask);
 }
 
-void WS2812_set_color( uint8_t index, uint8_t red, uint8_t green, uint8_t blue ) {
+void WS2812_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) {
   led_array[index].r = red;
   led_array[index].g = green;
   led_array[index].b = blue;

+ 1 - 1
drivers/arm/ws2812.h

@@ -30,7 +30,7 @@ void ws2812_setleds_rgbw(LED_TYPE *ledarray, uint16_t number_of_leds);
 
 
 void WS2812_init(void);
-void WS2812_set_color( uint8_t index, uint8_t red, uint8_t green, uint8_t blue );
+void WS2812_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
 void WS2812_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
 void WS2812_send_colors(void);
 

+ 57 - 55
drivers/avr/i2c_master.c

@@ -8,22 +8,24 @@
 #include "i2c_master.h"
 #include "timer.h"
 
+#ifndef F_SCL
 #define F_SCL 400000UL // SCL frequency
+#endif
 #define Prescaler 1
 #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)
 
 void i2c_init(void)
 {
   TWSR = 0;     /* no prescaler */
-	TWBR = (uint8_t)TWBR_val;
+  TWBR = (uint8_t)TWBR_val;
 }
 
 i2c_status_t i2c_start(uint8_t address, uint16_t timeout)
 {
-	// reset TWI control register
-	TWCR = 0;
-	// transmit START condition
-	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
+  // reset TWI control register
+  TWCR = 0;
+  // transmit START condition
+  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
 
   uint16_t timeout_timer = timer_read();
   while( !(TWCR & (1<<TWINT)) ) {
@@ -32,13 +34,13 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout)
     }
   }
 
-	// check if the start condition was successfully transmitted
-	if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return I2C_STATUS_ERROR; }
+  // check if the start condition was successfully transmitted
+  if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return I2C_STATUS_ERROR; }
 
-	// load slave address into data register
-	TWDR = address;
-	// start transmission of address
-	TWCR = (1<<TWINT) | (1<<TWEN);
+  // load slave address into data register
+  TWDR = address;
+  // start transmission of address
+  TWCR = (1<<TWINT) | (1<<TWEN);
 
   timeout_timer = timer_read();
   while( !(TWCR & (1<<TWINT)) ) {
@@ -47,19 +49,19 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout)
     }
   }
 
-	// check if the device has acknowledged the READ / WRITE mode
-	uint8_t twst = TW_STATUS & 0xF8;
-	if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return I2C_STATUS_ERROR;
+  // check if the device has acknowledged the READ / WRITE mode
+  uint8_t twst = TW_STATUS & 0xF8;
+  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return I2C_STATUS_ERROR;
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 i2c_status_t i2c_write(uint8_t data, uint16_t timeout)
 {
-	// load data into data register
-	TWDR = data;
-	// start transmission of data
-	TWCR = (1<<TWINT) | (1<<TWEN);
+  // load data into data register
+  TWDR = data;
+  // start transmission of data
+  TWCR = (1<<TWINT) | (1<<TWEN);
 
   uint16_t timeout_timer = timer_read();
   while( !(TWCR & (1<<TWINT)) ) {
@@ -68,16 +70,16 @@ i2c_status_t i2c_write(uint8_t data, uint16_t timeout)
     }
   }
 
-	if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return I2C_STATUS_ERROR; }
+  if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return I2C_STATUS_ERROR; }
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 int16_t i2c_read_ack(uint16_t timeout)
 {
 
-	// start TWI module and acknowledge data after reception
-	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
+  // start TWI module and acknowledge data after reception
+  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
 
   uint16_t timeout_timer = timer_read();
   while( !(TWCR & (1<<TWINT)) ) {
@@ -86,15 +88,15 @@ int16_t i2c_read_ack(uint16_t timeout)
     }
   }
 
-	// return received data from TWDR
-	return TWDR;
+  // return received data from TWDR
+  return TWDR;
 }
 
 int16_t i2c_read_nack(uint16_t timeout)
 {
 
-	// start receiving without acknowledging reception
-	TWCR = (1<<TWINT) | (1<<TWEN);
+  // start receiving without acknowledging reception
+  TWCR = (1<<TWINT) | (1<<TWEN);
 
   uint16_t timeout_timer = timer_read();
   while( !(TWCR & (1<<TWINT)) ) {
@@ -103,39 +105,39 @@ int16_t i2c_read_nack(uint16_t timeout)
     }
   }
 
-	// return received data from TWDR
-	return TWDR;
+  // return received data from TWDR
+  return TWDR;
 }
 
 i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
 {
   i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
-	if (status) return status;
+  if (status) return status;
 
-	for (uint16_t i = 0; i < length; i++) {
-		status = i2c_write(data[i], timeout);
+  for (uint16_t i = 0; i < length; i++) {
+    status = i2c_write(data[i], timeout);
     if (status) return status;
-	}
+  }
 
-	status = i2c_stop(timeout);
+  status = i2c_stop(timeout);
   if (status) return status;
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)
 {
   i2c_status_t status = i2c_start(address | I2C_READ, timeout);
-	if (status) return status;
+  if (status) return status;
 
-	for (uint16_t i = 0; i < (length-1); i++) {
+  for (uint16_t i = 0; i < (length-1); i++) {
     status = i2c_read_ack(timeout);
     if (status >= 0) {
       data[i] = status;
     } else {
       return status;
     }
-	}
+  }
 
   status = i2c_read_nack(timeout);
   if (status >= 0 ) {
@@ -147,47 +149,47 @@ i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16
   status = i2c_stop(timeout);
   if (status) return status;
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
 {
   i2c_status_t status = i2c_start(devaddr | 0x00, timeout);
-	if (status) return status;
+  if (status) return status;
 
-	status = i2c_write(regaddr, timeout);
+  status = i2c_write(regaddr, timeout);
   if (status) return status;
 
-	for (uint16_t i = 0; i < length; i++) {
+  for (uint16_t i = 0; i < length; i++) {
     status = i2c_write(data[i], timeout);
-		if (status) return status;
-	}
+    if (status) return status;
+  }
 
-	status = i2c_stop(timeout);
+  status = i2c_stop(timeout);
   if (status) return status;
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
 {
   i2c_status_t status = i2c_start(devaddr, timeout);
-	if (status) return status;
+  if (status) return status;
 
   status = i2c_write(regaddr, timeout);
   if (status) return status;
 
   status = i2c_start(devaddr | 0x01, timeout);
-	if (status) return status;
+  if (status) return status;
 
-	for (uint16_t i = 0; i < (length-1); i++) {
-		status = i2c_read_ack(timeout);
+  for (uint16_t i = 0; i < (length-1); i++) {
+    status = i2c_read_ack(timeout);
     if (status >= 0) {
       data[i] = status;
     } else {
       return status;
     }
-	}
+  }
 
   status = i2c_read_nack(timeout);
   if (status >= 0 ) {
@@ -199,13 +201,13 @@ i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16
   status = i2c_stop(timeout);
   if (status) return status;
 
-	return I2C_STATUS_SUCCESS;
+  return I2C_STATUS_SUCCESS;
 }
 
 i2c_status_t i2c_stop(uint16_t timeout)
 {
-	// transmit STOP condition
-	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
+  // transmit STOP condition
+  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
 
   uint16_t timeout_timer = timer_read();
   while(TWCR & (1<<TWSTO)) {
@@ -215,4 +217,4 @@ i2c_status_t i2c_stop(uint16_t timeout)
   }
 
   return I2C_STATUS_SUCCESS;
-}
+}

+ 1 - 1
drivers/avr/i2c_master.h

@@ -28,4 +28,4 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint1
 i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
 i2c_status_t i2c_stop(uint16_t timeout);
 
-#endif // I2C_MASTER_H
+#endif // I2C_MASTER_H

+ 51 - 83
drivers/avr/i2c_slave.c

@@ -5,96 +5,64 @@
 #include <avr/io.h>
 #include <util/twi.h>
 #include <avr/interrupt.h>
+#include <stdbool.h>
 
 #include "i2c_slave.h"
 
 void i2c_init(uint8_t address){
-	// load address into TWI address register
-	TWAR = (address << 1);
-	// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
-	TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
+    // load address into TWI address register
+    TWAR = (address << 1);
+    // set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
+    TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
 }
 
 void i2c_stop(void){
-	// clear acknowledge and enable bits
-	TWCR &= ~( (1<<TWEA) | (1<<TWEN) );
+    // clear acknowledge and enable bits
+    TWCR &= ~((1 << TWEA) | (1 << TWEN));
 }
 
 ISR(TWI_vect){
-	
-	// temporary stores the received data
-	uint8_t data;
-	
-	// own address has been acknowledged
-	if( (TWSR & 0xF8) == TW_SR_SLA_ACK ){  
-		buffer_address = 0xFF;
-		// clear TWI interrupt flag, prepare to receive next byte and acknowledge
-		TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
-	}
-	else if( (TWSR & 0xF8) == TW_SR_DATA_ACK ){ // data has been received in slave receiver mode
-		
-		// save the received byte inside data 
-		data = TWDR;
-		
-		// check wether an address has already been transmitted or not
-		if(buffer_address == 0xFF){
-			
-			buffer_address = data; 
-			
-			// clear TWI interrupt flag, prepare to receive next byte and acknowledge
-			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
-		}
-		else{ // if a databyte has already been received
-			
-			// store the data at the current address
-			rxbuffer[buffer_address] = data;
-			
-			// increment the buffer address
-			buffer_address++;
-			
-			// if there is still enough space inside the buffer
-			if(buffer_address < 0xFF){
-				// clear TWI interrupt flag, prepare to receive next byte and acknowledge
-				TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
-			}
-			else{
-				// Don't acknowledge
-				TWCR &= ~(1<<TWEA); 
-				// clear TWI interrupt flag, prepare to receive last byte.
-				TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEN); 
-			}
-		}
-	}
-	else if( (TWSR & 0xF8) == TW_ST_DATA_ACK ){ // device has been addressed to be a transmitter
-		
-		// copy data from TWDR to the temporary memory
-		data = TWDR;
-		
-		// if no buffer read address has been sent yet
-		if( buffer_address == 0xFF ){
-			buffer_address = data;
-		}
-		
-		// copy the specified buffer address into the TWDR register for transmission
-		TWDR = txbuffer[buffer_address];
-		// increment buffer read address
-		buffer_address++;
-		
-		// if there is another buffer address that can be sent
-		if(buffer_address < 0xFF){
-			// clear TWI interrupt flag, prepare to send next byte and receive acknowledge
-			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (1<<TWEN); 
-		}
-		else{
-			// Don't acknowledge
-			TWCR &= ~(1<<TWEA); 
-			// clear TWI interrupt flag, prepare to receive last byte.
-			TWCR |= (1<<TWIE) | (1<<TWINT) | (1<<TWEN); 
-		}
-		
-	}
-	else{
-		// if none of the above apply prepare TWI to be addressed again
-		TWCR |= (1<<TWIE) | (1<<TWEA) | (1<<TWEN);
-	} 
-}
+    uint8_t ack = 1;
+    // temporary stores the received data
+    //uint8_t data;
+    
+    switch(TW_STATUS){
+        case TW_SR_SLA_ACK:
+            // The device is now a slave receiver
+            slave_has_register_set = false;
+            break;
+
+        case TW_SR_DATA_ACK:
+            // This device is a slave receiver and has received data
+            // First byte is the location then the bytes will be writen in buffer with auto-incriment
+            if(!slave_has_register_set){
+                buffer_address = TWDR;
+
+                if (buffer_address >= RX_BUFFER_SIZE){ // address out of bounds dont ack
+                    ack = 0;
+                    buffer_address = 0;
+                }
+                slave_has_register_set = true; // address has been receaved now fill in buffer
+            } else {
+                rxbuffer[buffer_address] = TWDR;
+                buffer_address++;
+            }
+            break;
+
+        case TW_ST_SLA_ACK:
+        case TW_ST_DATA_ACK:
+            // This device is a slave transmitter and master has requested data
+            TWDR = txbuffer[buffer_address];
+            buffer_address++;
+            break;
+
+        case TW_BUS_ERROR:
+            // We got an error, reset i2c
+            TWCR = 0;
+        default:
+            break;
+    }
+
+    // Reset i2c state mahcine to be ready for next interrupt
+    TWCR |= (1 << TWIE) | (1 << TWINT) | (ack << TWEA) | (1 << TWEN);
+}

+ 7 - 3
drivers/avr/i2c_slave.h

@@ -8,12 +8,16 @@
 #ifndef I2C_SLAVE_H
 #define I2C_SLAVE_H
 
+#define TX_BUFFER_SIZE 30
+#define RX_BUFFER_SIZE 30
+
 volatile uint8_t buffer_address;
-volatile uint8_t txbuffer[0xFF];
-volatile uint8_t rxbuffer[0xFF];
+static volatile bool slave_has_register_set = false;
+volatile uint8_t txbuffer[TX_BUFFER_SIZE];
+volatile uint8_t rxbuffer[RX_BUFFER_SIZE];
 
 void i2c_init(uint8_t address);
 void i2c_stop(void);
 ISR(TWI_vect);
 
-#endif // I2C_SLAVE_H
+#endif // I2C_SLAVE_H

+ 0 - 262
drivers/avr/is31fl3731.c

@@ -1,262 +0,0 @@
-/* Copyright 2017 Jason Williams
- * Copyright 2018 Jack Humbert
- *
- * 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 "is31fl3731.h"
-#include <avr/interrupt.h>
-#include <avr/io.h>
-#include <util/delay.h>
-#include <string.h>
-#include "i2c_master.h"
-#include "progmem.h"
-
-// This is a 7-bit address, that gets left-shifted and bit 0
-// set to 0 for write, 1 for read (as per I2C protocol)
-// The address will vary depending on your wiring:
-// 0b1110100 AD <-> GND
-// 0b1110111 AD <-> VCC
-// 0b1110101 AD <-> SCL
-// 0b1110110 AD <-> SDA
-#define ISSI_ADDR_DEFAULT 0x74
-
-#define ISSI_REG_CONFIG  0x00
-#define ISSI_REG_CONFIG_PICTUREMODE 0x00
-#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
-#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
-
-#define ISSI_CONF_PICTUREMODE 0x00
-#define ISSI_CONF_AUTOFRAMEMODE 0x04
-#define ISSI_CONF_AUDIOMODE 0x08
-
-#define ISSI_REG_PICTUREFRAME  0x01
-
-#define ISSI_REG_SHUTDOWN 0x0A
-#define ISSI_REG_AUDIOSYNC 0x06
-
-#define ISSI_COMMANDREGISTER 0xFD
-#define ISSI_BANK_FUNCTIONREG 0x0B    // helpfully called 'page nine'
-
-#ifndef ISSI_TIMEOUT
-  #define ISSI_TIMEOUT 100
-#endif
-
-#ifndef ISSI_PERSISTENCE
-  #define ISSI_PERSISTENCE 0
-#endif
-
-// Transfer buffer for TWITransmitData()
-uint8_t g_twi_transfer_buffer[20];
-
-// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
-// Storing them like this is optimal for I2C transfers to the registers.
-// We could optimize this and take out the unused registers from these
-// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
-// probably not worth the extra complexity.
-uint8_t g_pwm_buffer[DRIVER_COUNT][144];
-bool g_pwm_buffer_update_required = false;
-
-uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
-bool g_led_control_registers_update_required = false;
-
-// This is the bit pattern in the LED control registers
-// (for matrix A, add one to register for matrix B)
-//
-//  reg -  b7  b6  b5  b4  b3  b2  b1  b0
-// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
-// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
-// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
-// 0x06 -  - , - , - , - , - ,B02,B01,B00
-// 0x08 -  - , - , - , - , - , - , - , -
-// 0x0A - B17,B16,B15, - , - , - , - , -
-// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
-// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
-// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
-
-
-void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
-{
-	g_twi_transfer_buffer[0] = reg;
-	g_twi_transfer_buffer[1] = data;
-
-  #if ISSI_PERSISTENCE > 0
-    for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
-      if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
-        break;
-    }
-  #else
-    i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
-  #endif
-}
-
-void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
-{
-	// assumes bank is already selected
-
-	// transmit PWM registers in 9 transfers of 16 bytes
-	// g_twi_transfer_buffer[] is 20 bytes
-
-	// iterate over the pwm_buffer contents at 16 byte intervals
-	for ( int i = 0; i < 144; i += 16 ) {
-		// set the first register, e.g. 0x24, 0x34, 0x44, etc.
-		g_twi_transfer_buffer[0] = 0x24 + i;
-		// copy the data from i to i+15
-		// device will auto-increment register for data after the first byte
-		// thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
-		for ( int j = 0; j < 16; j++ ) {
-			g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
-		}
-
-    #if ISSI_PERSISTENCE > 0
-      for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
-        if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
-          break;
-      }
-    #else
-      i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
-    #endif
-	}
-}
-
-void IS31FL3731_init( uint8_t addr )
-{
-	// In order to avoid the LEDs being driven with garbage data
-	// in the LED driver's PWM registers, first enable software shutdown,
-	// then set up the mode and other settings, clear the PWM registers,
-	// then disable software shutdown.
-
-	// select "function register" bank
-	IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
-
-	// enable software shutdown
-	IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
-	// this delay was copied from other drivers, might not be needed
-	_delay_ms( 10 );
-
-	// picture mode
-	IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
-	// display frame 0
-	IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
-	// audio sync off
-	IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
-
-	// select bank 0
-	IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
-
-	// turn off all LEDs in the LED control register
-	for ( int i = 0x00; i <= 0x11; i++ )
-	{
-		IS31FL3731_write_register( addr, i, 0x00 );
-	}
-
-	// turn off all LEDs in the blink control register (not really needed)
-	for ( int i = 0x12; i <= 0x23; i++ )
-	{
-		IS31FL3731_write_register( addr, i, 0x00 );
-	}
-
-	// set PWM on all LEDs to 0
-	for ( int i = 0x24; i <= 0xB3; i++ )
-	{
-		IS31FL3731_write_register( addr, i, 0x00 );
-	}
-
-	// select "function register" bank
-	IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
-
-	// disable software shutdown
-	IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
-
-	// select bank 0 and leave it selected.
-	// most usage after initialization is just writing PWM buffers in bank 0
-	// as there's not much point in double-buffering
-	IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
-
-}
-
-void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
-{
-	if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
-		is31_led led = g_is31_leds[index];
-
-		// Subtract 0x24 to get the second index of g_pwm_buffer
-		g_pwm_buffer[led.driver][led.r - 0x24] = red;
-		g_pwm_buffer[led.driver][led.g - 0x24] = green;
-		g_pwm_buffer[led.driver][led.b - 0x24] = blue;
-		g_pwm_buffer_update_required = true;
-	}
-}
-
-void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
-{
-	for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
-	{
-		IS31FL3731_set_color( i, red, green, blue );
-	}
-}
-
-void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
-{
-	is31_led led = g_is31_leds[index];
-
-  uint8_t control_register_r = (led.r - 0x24) / 8;
-  uint8_t control_register_g = (led.g - 0x24) / 8;
-  uint8_t control_register_b = (led.b - 0x24) / 8;
-  uint8_t bit_r = (led.r - 0x24) % 8;
-  uint8_t bit_g = (led.g - 0x24) % 8;
-  uint8_t bit_b = (led.b - 0x24) % 8;
-
-	if ( red ) {
-		g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
-	} else {
-		g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
-	}
-	if ( green ) {
-		g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
-	} else {
-		g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
-	}
-	if ( blue ) {
-		g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
-	} else {
-		g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
-	}
-
-	g_led_control_registers_update_required = true;
-
-}
-
-void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
-{
-	if ( g_pwm_buffer_update_required )
-	{
-		IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
-		IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
-	}
-	g_pwm_buffer_update_required = false;
-}
-
-void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
-{
-	if ( g_led_control_registers_update_required )
-	{
-		for ( int i=0; i<18; i++ )
-		{
-			IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
-			IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
-		}
-	}
-}
-

+ 0 - 214
drivers/avr/is31fl3731.h

@@ -1,214 +0,0 @@
-/* Copyright 2017 Jason Williams
- * Copyright 2018 Jack Humbert
- *
- * 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 IS31FL3731_DRIVER_H
-#define IS31FL3731_DRIVER_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef struct is31_led {
-	uint8_t driver:2;
-  uint8_t r;
-  uint8_t g;
-  uint8_t b;
-} __attribute__((packed)) is31_led;
-
-extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
-
-void IS31FL3731_init( uint8_t addr );
-void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data );
-void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
-
-void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
-void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
-
-void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
-
-// This should not be called from an interrupt
-// (eg. from a timer interrupt).
-// Call this while idle (in between matrix scans).
-// If the buffer is dirty, it will update the driver with the buffer.
-void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
-void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
-
-#define C1_1  0x24
-#define C1_2  0x25
-#define C1_3  0x26
-#define C1_4  0x27
-#define C1_5  0x28
-#define C1_6  0x29
-#define C1_7  0x2A
-#define C1_8  0x2B
-
-#define C1_9  0x2C
-#define C1_10 0x2D
-#define C1_11 0x2E
-#define C1_12 0x2F
-#define C1_13 0x30
-#define C1_14 0x31
-#define C1_15 0x32
-#define C1_16 0x33
-
-#define C2_1  0x34
-#define C2_2  0x35
-#define C2_3  0x36
-#define C2_4  0x37
-#define C2_5  0x38
-#define C2_6  0x39
-#define C2_7  0x3A
-#define C2_8  0x3B
-
-#define C2_9  0x3C
-#define C2_10 0x3D
-#define C2_11 0x3E
-#define C2_12 0x3F
-#define C2_13 0x40
-#define C2_14 0x41
-#define C2_15 0x42
-#define C2_16 0x43
-
-#define C3_1  0x44
-#define C3_2  0x45
-#define C3_3  0x46
-#define C3_4  0x47
-#define C3_5  0x48
-#define C3_6  0x49
-#define C3_7  0x4A
-#define C3_8  0x4B
-
-#define C3_9  0x4C
-#define C3_10 0x4D
-#define C3_11 0x4E
-#define C3_12 0x4F
-#define C3_13 0x50
-#define C3_14 0x51
-#define C3_15 0x52
-#define C3_16 0x53
-
-#define C4_1  0x54
-#define C4_2  0x55
-#define C4_3  0x56
-#define C4_4  0x57
-#define C4_5  0x58
-#define C4_6  0x59
-#define C4_7  0x5A
-#define C4_8  0x5B
-
-#define C4_9  0x5C
-#define C4_10 0x5D
-#define C4_11 0x5E
-#define C4_12 0x5F
-#define C4_13 0x60
-#define C4_14 0x61
-#define C4_15 0x62
-#define C4_16 0x63
-
-#define C5_1  0x64
-#define C5_2  0x65
-#define C5_3  0x66
-#define C5_4  0x67
-#define C5_5  0x68
-#define C5_6  0x69
-#define C5_7  0x6A
-#define C5_8  0x6B
-
-#define C5_9  0x6C
-#define C5_10 0x6D
-#define C5_11 0x6E
-#define C5_12 0x6F
-#define C5_13 0x70
-#define C5_14 0x71
-#define C5_15 0x72
-#define C5_16 0x73
-
-#define C6_1  0x74
-#define C6_2  0x75
-#define C6_3  0x76
-#define C6_4  0x77
-#define C6_5  0x78
-#define C6_6  0x79
-#define C6_7  0x7A
-#define C6_8  0x7B
-
-#define C6_9  0x7C
-#define C6_10 0x7D
-#define C6_11 0x7E
-#define C6_12 0x7F
-#define C6_13 0x80
-#define C6_14 0x81
-#define C6_15 0x82
-#define C6_16 0x83
-
-#define C7_1  0x84
-#define C7_2  0x85
-#define C7_3  0x86
-#define C7_4  0x87
-#define C7_5  0x88
-#define C7_6  0x89
-#define C7_7  0x8A
-#define C7_8  0x8B
-
-#define C7_9  0x8C
-#define C7_10 0x8D
-#define C7_11 0x8E
-#define C7_12 0x8F
-#define C7_13 0x90
-#define C7_14 0x91
-#define C7_15 0x92
-#define C7_16 0x93
-
-#define C8_1  0x94
-#define C8_2  0x95
-#define C8_3  0x96
-#define C8_4  0x97
-#define C8_5  0x98
-#define C8_6  0x99
-#define C8_7  0x9A
-#define C8_8  0x9B
-
-#define C8_9  0x9C
-#define C8_10 0x9D
-#define C8_11 0x9E
-#define C8_12 0x9F
-#define C8_13 0xA0
-#define C8_14 0xA1
-#define C8_15 0xA2
-#define C8_16 0xA3
-
-#define C9_1  0xA4
-#define C9_2  0xA5
-#define C9_3  0xA6
-#define C9_4  0xA7
-#define C9_5  0xA8
-#define C9_6  0xA9
-#define C9_7  0xAA
-#define C9_8  0xAB
-
-#define C9_9  0xAC
-#define C9_10 0xAD
-#define C9_11 0xAE
-#define C9_12 0xAF
-#define C9_13 0xB0
-#define C9_14 0xB1
-#define C9_15 0xB2
-#define C9_16 0xB3
-
-
-
-#endif // IS31FL3731_DRIVER_H

+ 0 - 3
drivers/avr/ws2812.h

@@ -73,7 +73,4 @@ void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask);
 #define CONCAT_EXP(a, b)   CONCAT(a, b)
 #endif
 
-// #define ws2812_PORTREG  CONCAT_EXP(PORT,ws2812_port)
-// #define ws2812_DDRREG   CONCAT_EXP(DDR,ws2812_port)
-
 #endif /* LIGHT_WS2812_H_ */

+ 102 - 0
drivers/issi/is31fl3218.c

@@ -0,0 +1,102 @@
+/* Copyright 2018 Jason Williams (Wilba)
+ *
+ * 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 "is31fl3218.h"
+#include "i2c_master.h"
+
+// This is the full 8-bit address
+#define ISSI_ADDRESS 0b10101000
+
+// These are the register addresses
+#define ISSI_REG_SHUTDOWN 0x00
+#define ISSI_REG_PWM 0x01
+#define ISSI_REG_CONTROL 0x13
+#define ISSI_REG_UPDATE 0x16
+#define ISSI_REG_RESET 0x17
+
+// Default timeout if no I2C response
+#define ISSI_TIMEOUT 100
+
+// Reusable buffer for transfers
+uint8_t g_twi_transfer_buffer[20];
+
+// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
+// If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB
+uint8_t g_pwm_buffer[18];
+bool g_pwm_buffer_update_required = false;
+
+void IS31FL3218_write_register( uint8_t reg, uint8_t data )
+{
+	g_twi_transfer_buffer[0] = reg;
+	g_twi_transfer_buffer[1] = data;
+	i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
+}
+
+void IS31FL3218_write_pwm_buffer( uint8_t *pwm_buffer )
+{
+	g_twi_transfer_buffer[0] = ISSI_REG_PWM;
+	for ( int i=0; i<18; i++ ) {
+		g_twi_transfer_buffer[1+i] = pwm_buffer[i];
+	}
+	
+	i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT);
+}
+
+void IS31FL3218_init(void)
+{
+	// In case we ever want to reinitialize (?)
+	IS31FL3218_write_register( ISSI_REG_RESET, 0x00 );
+	
+	// Turn off software shutdown
+	IS31FL3218_write_register( ISSI_REG_SHUTDOWN, 0x01 );
+
+	// Set all PWM values to zero
+	for ( uint8_t i = 0; i < 18; i++ ) {
+		IS31FL3218_write_register( ISSI_REG_PWM+i, 0x00 );
+	}
+	
+	// Enable all channels
+	for ( uint8_t i = 0; i < 3; i++ ) {
+		IS31FL3218_write_register( ISSI_REG_CONTROL+i, 0b00111111 );
+	}
+	
+	// Load PWM registers and LED Control register data
+	IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 );
+}
+
+void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
+{
+	g_pwm_buffer[index * 3 + 0] = red;
+	g_pwm_buffer[index * 3 + 1] = green;
+	g_pwm_buffer[index * 3 + 2] = blue;
+	g_pwm_buffer_update_required = true;
+}
+
+void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
+{
+	for ( int i = 0; i < 6; i++ ) {
+		IS31FL3218_set_color( i, red, green, blue );
+	}
+}
+
+void IS31FL3218_update_pwm_buffers(void)
+{
+	if ( g_pwm_buffer_update_required ) {
+		IS31FL3218_write_pwm_buffer( g_pwm_buffer );
+		// Load PWM registers and LED Control register data
+		IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 );
+	}
+	g_pwm_buffer_update_required = false;
+}

+ 24 - 0
drivers/issi/is31fl3218.h

@@ -0,0 +1,24 @@
+/* Copyright 2018 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+void IS31FL3218_init(void);
+void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
+void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
+void IS31FL3218_update_pwm_buffers(void);

+ 270 - 0
drivers/issi/is31fl3731.c

@@ -0,0 +1,270 @@
+/* Copyright 2017 Jason Williams
+ * Copyright 2018 Jack Humbert
+ *
+ * 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/>.
+ */
+
+#ifdef __AVR__
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#else
+#include "wait.h"
+#endif
+
+#include "is31fl3731.h"
+#include <string.h>
+#include "i2c_master.h"
+#include "progmem.h"
+
+// This is a 7-bit address, that gets left-shifted and bit 0
+// set to 0 for write, 1 for read (as per I2C protocol)
+// The address will vary depending on your wiring:
+// 0b1110100 AD <-> GND
+// 0b1110111 AD <-> VCC
+// 0b1110101 AD <-> SCL
+// 0b1110110 AD <-> SDA
+#define ISSI_ADDR_DEFAULT 0x74
+
+#define ISSI_REG_CONFIG  0x00
+#define ISSI_REG_CONFIG_PICTUREMODE 0x00
+#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08
+#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18
+
+#define ISSI_CONF_PICTUREMODE 0x00
+#define ISSI_CONF_AUTOFRAMEMODE 0x04
+#define ISSI_CONF_AUDIOMODE 0x08
+
+#define ISSI_REG_PICTUREFRAME  0x01
+
+#define ISSI_REG_SHUTDOWN 0x0A
+#define ISSI_REG_AUDIOSYNC 0x06
+
+#define ISSI_COMMANDREGISTER 0xFD
+#define ISSI_BANK_FUNCTIONREG 0x0B    // helpfully called 'page nine'
+
+#ifndef ISSI_TIMEOUT
+  #define ISSI_TIMEOUT 100
+#endif
+
+#ifndef ISSI_PERSISTENCE
+  #define ISSI_PERSISTENCE 0
+#endif
+
+// Transfer buffer for TWITransmitData()
+uint8_t g_twi_transfer_buffer[20];
+
+// These buffers match the IS31FL3731 PWM registers 0x24-0xB3.
+// Storing them like this is optimal for I2C transfers to the registers.
+// We could optimize this and take out the unused registers from these
+// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's
+// probably not worth the extra complexity.
+uint8_t g_pwm_buffer[DRIVER_COUNT][144];
+bool g_pwm_buffer_update_required = false;
+
+uint8_t g_led_control_registers[DRIVER_COUNT][18] = { { 0 }, { 0 } };
+bool g_led_control_registers_update_required = false;
+
+// This is the bit pattern in the LED control registers
+// (for matrix A, add one to register for matrix B)
+//
+//  reg -  b7  b6  b5  b4  b3  b2  b1  b0
+// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01
+// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00
+// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00
+// 0x06 -  - , - , - , - , - ,B02,B01,B00
+// 0x08 -  - , - , - , - , - , - , - , -
+// 0x0A - B17,B16,B15, - , - , - , - , -
+// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09
+// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09
+// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
+
+
+void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
+{
+    g_twi_transfer_buffer[0] = reg;
+    g_twi_transfer_buffer[1] = data;
+
+  #if ISSI_PERSISTENCE > 0
+    for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+      if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
+        break;
+    }
+  #else
+    i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
+  #endif
+}
+
+void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
+{
+    // assumes bank is already selected
+
+    // transmit PWM registers in 9 transfers of 16 bytes
+    // g_twi_transfer_buffer[] is 20 bytes
+
+    // iterate over the pwm_buffer contents at 16 byte intervals
+    for ( int i = 0; i < 144; i += 16 ) {
+        // set the first register, e.g. 0x24, 0x34, 0x44, etc.
+        g_twi_transfer_buffer[0] = 0x24 + i;
+        // copy the data from i to i+15
+        // device will auto-increment register for data after the first byte
+        // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer
+        for ( int j = 0; j < 16; j++ ) {
+            g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
+        }
+
+    #if ISSI_PERSISTENCE > 0
+      for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+        if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
+          break;
+      }
+    #else
+      i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
+    #endif
+    }
+}
+
+void IS31FL3731_init( uint8_t addr )
+{
+    // In order to avoid the LEDs being driven with garbage data
+    // in the LED driver's PWM registers, first enable software shutdown,
+    // then set up the mode and other settings, clear the PWM registers,
+    // then disable software shutdown.
+
+    // select "function register" bank
+    IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
+
+    // enable software shutdown
+    IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
+    // this delay was copied from other drivers, might not be needed
+    #ifdef __AVR__
+    _delay_ms( 10 );
+    #else
+    wait_ms(10);
+    #endif
+
+    // picture mode
+    IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
+    // display frame 0
+    IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
+    // audio sync off
+    IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
+
+    // select bank 0
+    IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
+
+    // turn off all LEDs in the LED control register
+    for ( int i = 0x00; i <= 0x11; i++ )
+    {
+        IS31FL3731_write_register( addr, i, 0x00 );
+    }
+
+    // turn off all LEDs in the blink control register (not really needed)
+    for ( int i = 0x12; i <= 0x23; i++ )
+    {
+        IS31FL3731_write_register( addr, i, 0x00 );
+    }
+
+    // set PWM on all LEDs to 0
+    for ( int i = 0x24; i <= 0xB3; i++ )
+    {
+        IS31FL3731_write_register( addr, i, 0x00 );
+    }
+
+    // select "function register" bank
+    IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
+
+    // disable software shutdown
+    IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
+
+    // select bank 0 and leave it selected.
+    // most usage after initialization is just writing PWM buffers in bank 0
+    // as there's not much point in double-buffering
+    IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
+
+}
+
+void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
+{
+    if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
+        is31_led led = g_is31_leds[index];
+
+        // Subtract 0x24 to get the second index of g_pwm_buffer
+        g_pwm_buffer[led.driver][led.r - 0x24] = red;
+        g_pwm_buffer[led.driver][led.g - 0x24] = green;
+        g_pwm_buffer[led.driver][led.b - 0x24] = blue;
+        g_pwm_buffer_update_required = true;
+    }
+}
+
+void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
+{
+    for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
+    {
+        IS31FL3731_set_color( i, red, green, blue );
+    }
+}
+
+void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
+{
+    is31_led led = g_is31_leds[index];
+
+  uint8_t control_register_r = (led.r - 0x24) / 8;
+  uint8_t control_register_g = (led.g - 0x24) / 8;
+  uint8_t control_register_b = (led.b - 0x24) / 8;
+  uint8_t bit_r = (led.r - 0x24) % 8;
+  uint8_t bit_g = (led.g - 0x24) % 8;
+  uint8_t bit_b = (led.b - 0x24) % 8;
+
+    if ( red ) {
+        g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
+    } else {
+        g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
+    }
+    if ( green ) {
+        g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
+    } else {
+        g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
+    }
+    if ( blue ) {
+        g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
+    } else {
+        g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
+    }
+
+    g_led_control_registers_update_required = true;
+
+}
+
+void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_pwm_buffer_update_required )
+    {
+        IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
+        IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
+    }
+    g_pwm_buffer_update_required = false;
+}
+
+void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_led_control_registers_update_required )
+    {
+        for ( int i=0; i<18; i++ )
+        {
+            IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
+            IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
+        }
+    }
+}

+ 214 - 0
drivers/issi/is31fl3731.h

@@ -0,0 +1,214 @@
+/* Copyright 2017 Jason Williams
+ * Copyright 2018 Jack Humbert
+ *
+ * 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 IS31FL3731_DRIVER_H
+#define IS31FL3731_DRIVER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct is31_led {
+  uint8_t driver:2;
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+} __attribute__((packed)) is31_led;
+
+extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
+
+void IS31FL3731_init( uint8_t addr );
+void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data );
+void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
+
+void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
+void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
+
+void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
+
+// This should not be called from an interrupt
+// (eg. from a timer interrupt).
+// Call this while idle (in between matrix scans).
+// If the buffer is dirty, it will update the driver with the buffer.
+void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
+void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
+
+#define C1_1  0x24
+#define C1_2  0x25
+#define C1_3  0x26
+#define C1_4  0x27
+#define C1_5  0x28
+#define C1_6  0x29
+#define C1_7  0x2A
+#define C1_8  0x2B
+
+#define C1_9  0x2C
+#define C1_10 0x2D
+#define C1_11 0x2E
+#define C1_12 0x2F
+#define C1_13 0x30
+#define C1_14 0x31
+#define C1_15 0x32
+#define C1_16 0x33
+
+#define C2_1  0x34
+#define C2_2  0x35
+#define C2_3  0x36
+#define C2_4  0x37
+#define C2_5  0x38
+#define C2_6  0x39
+#define C2_7  0x3A
+#define C2_8  0x3B
+
+#define C2_9  0x3C
+#define C2_10 0x3D
+#define C2_11 0x3E
+#define C2_12 0x3F
+#define C2_13 0x40
+#define C2_14 0x41
+#define C2_15 0x42
+#define C2_16 0x43
+
+#define C3_1  0x44
+#define C3_2  0x45
+#define C3_3  0x46
+#define C3_4  0x47
+#define C3_5  0x48
+#define C3_6  0x49
+#define C3_7  0x4A
+#define C3_8  0x4B
+
+#define C3_9  0x4C
+#define C3_10 0x4D
+#define C3_11 0x4E
+#define C3_12 0x4F
+#define C3_13 0x50
+#define C3_14 0x51
+#define C3_15 0x52
+#define C3_16 0x53
+
+#define C4_1  0x54
+#define C4_2  0x55
+#define C4_3  0x56
+#define C4_4  0x57
+#define C4_5  0x58
+#define C4_6  0x59
+#define C4_7  0x5A
+#define C4_8  0x5B
+
+#define C4_9  0x5C
+#define C4_10 0x5D
+#define C4_11 0x5E
+#define C4_12 0x5F
+#define C4_13 0x60
+#define C4_14 0x61
+#define C4_15 0x62
+#define C4_16 0x63
+
+#define C5_1  0x64
+#define C5_2  0x65
+#define C5_3  0x66
+#define C5_4  0x67
+#define C5_5  0x68
+#define C5_6  0x69
+#define C5_7  0x6A
+#define C5_8  0x6B
+
+#define C5_9  0x6C
+#define C5_10 0x6D
+#define C5_11 0x6E
+#define C5_12 0x6F
+#define C5_13 0x70
+#define C5_14 0x71
+#define C5_15 0x72
+#define C5_16 0x73
+
+#define C6_1  0x74
+#define C6_2  0x75
+#define C6_3  0x76
+#define C6_4  0x77
+#define C6_5  0x78
+#define C6_6  0x79
+#define C6_7  0x7A
+#define C6_8  0x7B
+
+#define C6_9  0x7C
+#define C6_10 0x7D
+#define C6_11 0x7E
+#define C6_12 0x7F
+#define C6_13 0x80
+#define C6_14 0x81
+#define C6_15 0x82
+#define C6_16 0x83
+
+#define C7_1  0x84
+#define C7_2  0x85
+#define C7_3  0x86
+#define C7_4  0x87
+#define C7_5  0x88
+#define C7_6  0x89
+#define C7_7  0x8A
+#define C7_8  0x8B
+
+#define C7_9  0x8C
+#define C7_10 0x8D
+#define C7_11 0x8E
+#define C7_12 0x8F
+#define C7_13 0x90
+#define C7_14 0x91
+#define C7_15 0x92
+#define C7_16 0x93
+
+#define C8_1  0x94
+#define C8_2  0x95
+#define C8_3  0x96
+#define C8_4  0x97
+#define C8_5  0x98
+#define C8_6  0x99
+#define C8_7  0x9A
+#define C8_8  0x9B
+
+#define C8_9  0x9C
+#define C8_10 0x9D
+#define C8_11 0x9E
+#define C8_12 0x9F
+#define C8_13 0xA0
+#define C8_14 0xA1
+#define C8_15 0xA2
+#define C8_16 0xA3
+
+#define C9_1  0xA4
+#define C9_2  0xA5
+#define C9_3  0xA6
+#define C9_4  0xA7
+#define C9_5  0xA8
+#define C9_6  0xA9
+#define C9_7  0xAA
+#define C9_8  0xAB
+
+#define C9_9  0xAC
+#define C9_10 0xAD
+#define C9_11 0xAE
+#define C9_12 0xAF
+#define C9_13 0xB0
+#define C9_14 0xB1
+#define C9_15 0xB2
+#define C9_16 0xB3
+
+
+
+#endif // IS31FL3731_DRIVER_H

+ 252 - 0
drivers/issi/is31fl3733.c

@@ -0,0 +1,252 @@
+/* Copyright 2017 Jason Williams
+ * Copyright 2018 Jack Humbert
+ * Copyright 2018 Yiancar
+ *
+ * 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/>.
+ */
+
+#ifdef __AVR__
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#else
+#include "wait.h"
+#endif
+
+#include <string.h>
+#include "i2c_master.h"
+#include "progmem.h"
+#include "rgb_matrix.h"
+
+// This is a 7-bit address, that gets left-shifted and bit 0
+// set to 0 for write, 1 for read (as per I2C protocol)
+// The address will vary depending on your wiring:
+// 00 <-> GND
+// 01 <-> SCL
+// 10 <-> SDA
+// 11 <-> VCC
+// ADDR1 represents A1:A0 of the 7-bit address.
+// ADDR2 represents A3:A2 of the 7-bit address.
+// The result is: 0b101(ADDR2)(ADDR1)
+#define ISSI_ADDR_DEFAULT 0x50
+
+#define ISSI_COMMANDREGISTER 0xFD
+#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
+#define ISSI_INTERRUPTMASKREGISTER 0xF0
+#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
+
+#define ISSI_PAGE_LEDCONTROL 0x00 //PG0
+#define ISSI_PAGE_PWM 0x01        //PG1
+#define ISSI_PAGE_AUTOBREATH 0x02 //PG2
+#define ISSI_PAGE_FUNCTION 0x03   //PG3
+
+#define ISSI_REG_CONFIGURATION 0x00 //PG3
+#define ISSI_REG_GLOBALCURRENT 0x01 //PG3
+#define ISSI_REG_RESET 0x11// PG3
+#define ISSI_REG_SWPULLUP 0x0F //PG3
+#define ISSI_REG_CSPULLUP 0x10 //PG3
+
+#ifndef ISSI_TIMEOUT
+  #define ISSI_TIMEOUT 100
+#endif
+
+#ifndef ISSI_PERSISTENCE
+  #define ISSI_PERSISTENCE 0
+#endif
+
+// Transfer buffer for TWITransmitData()
+uint8_t g_twi_transfer_buffer[20];
+
+// These buffers match the IS31FL3733 PWM registers.
+// The control buffers match the PG0 LED On/Off registers.
+// Storing them like this is optimal for I2C transfers to the registers.
+// We could optimize this and take out the unused registers from these
+// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
+// probably not worth the extra complexity.
+uint8_t g_pwm_buffer[DRIVER_COUNT][192];
+bool g_pwm_buffer_update_required = false;
+
+uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } };
+bool g_led_control_registers_update_required = false;
+
+void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data )
+{
+    g_twi_transfer_buffer[0] = reg;
+    g_twi_transfer_buffer[1] = data;
+
+  #if ISSI_PERSISTENCE > 0
+    for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+      if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
+        break;
+    }
+  #else
+    i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
+  #endif
+}
+
+void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
+{
+    // assumes PG1 is already selected
+
+    // transmit PWM registers in 12 transfers of 16 bytes
+    // g_twi_transfer_buffer[] is 20 bytes
+
+    // iterate over the pwm_buffer contents at 16 byte intervals
+    for ( int i = 0; i < 192; i += 16 ) {
+        g_twi_transfer_buffer[0] = i;
+        // copy the data from i to i+15
+        // device will auto-increment register for data after the first byte
+        // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
+        for ( int j = 0; j < 16; j++ ) {
+            g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
+        }
+
+    #if ISSI_PERSISTENCE > 0
+      for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+        if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
+          break;
+      }
+    #else
+      i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
+    #endif
+    }
+}
+
+void IS31FL3733_init( uint8_t addr )
+{
+    // In order to avoid the LEDs being driven with garbage data
+    // in the LED driver's PWM registers, shutdown is enabled last.
+    // Set up the mode and other settings, clear the PWM registers,
+    // then disable software shutdown.
+
+    // Unlock the command register.
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG0
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
+    // Turn off all LEDs.
+    for ( int i = 0x00; i <= 0x17; i++ )
+    {
+        IS31FL3733_write_register( addr, i, 0x00 );
+    }
+
+    // Unlock the command register.
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG1
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
+    // Set PWM on all LEDs to 0
+    // No need to setup Breath registers to PWM as that is the default.
+    for ( int i = 0x00; i <= 0xBF; i++ )
+    {
+        IS31FL3733_write_register( addr, i, 0x00 );
+    }
+
+    // Unlock the command register.
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG3
+    IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION );
+    // Set global current to maximum.
+    IS31FL3733_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF );
+    // Disable software shutdown.
+    IS31FL3733_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 );
+
+    // Wait 10ms to ensure the device has woken up.
+    #ifdef __AVR__
+    _delay_ms( 10 );
+    #else
+    wait_ms(10);
+    #endif
+}
+
+void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
+{
+    if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
+        is31_led led = g_is31_leds[index];
+
+        g_pwm_buffer[led.driver][led.r] = red;
+        g_pwm_buffer[led.driver][led.g] = green;
+        g_pwm_buffer[led.driver][led.b] = blue;
+        g_pwm_buffer_update_required = true;
+    }
+}
+
+void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
+{
+    for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
+    {
+        IS31FL3733_set_color( i, red, green, blue );
+    }
+}
+
+void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
+{
+    is31_led led = g_is31_leds[index];
+
+  uint8_t control_register_r = led.r / 8;
+  uint8_t control_register_g = led.g / 8;
+  uint8_t control_register_b = led.b / 8;
+  uint8_t bit_r = led.r % 8;
+  uint8_t bit_g = led.g % 8;
+  uint8_t bit_b = led.b % 8;
+
+    if ( red ) {
+        g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
+    } else {
+        g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
+    }
+    if ( green ) {
+        g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
+    } else {
+        g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
+    }
+    if ( blue ) {
+        g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
+    } else {
+        g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
+    }
+
+    g_led_control_registers_update_required = true;
+
+}
+
+void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_pwm_buffer_update_required )
+    {
+        // Firstly we need to unlock the command register and select PG1
+        IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+        IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
+
+        IS31FL3733_write_pwm_buffer( addr1, g_pwm_buffer[0] );
+        //IS31FL3733_write_pwm_buffer( addr2, g_pwm_buffer[1] );
+    }
+    g_pwm_buffer_update_required = false;
+}
+
+void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_led_control_registers_update_required )
+    {
+        // Firstly we need to unlock the command register and select PG0
+        IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+        IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
+        for ( int i=0; i<24; i++ )
+        {
+            IS31FL3733_write_register(addr1, i, g_led_control_registers[0][i] );
+            //IS31FL3733_write_register(addr2, i, g_led_control_registers[1][i] );
+        }
+    }
+}

+ 255 - 0
drivers/issi/is31fl3733.h

@@ -0,0 +1,255 @@
+/* Copyright 2017 Jason Williams
+ * Copyright 2018 Jack Humbert
+ * Copyright 2018 Yiancar
+ *
+ * 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 IS31FL3733_DRIVER_H
+#define IS31FL3733_DRIVER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct is31_led {
+  uint8_t driver:2;
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+} __attribute__((packed)) is31_led;
+
+extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
+
+void IS31FL3733_init( uint8_t addr );
+void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data );
+void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
+
+void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
+void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
+
+void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
+
+// This should not be called from an interrupt
+// (eg. from a timer interrupt).
+// Call this while idle (in between matrix scans).
+// If the buffer is dirty, it will update the driver with the buffer.
+void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
+void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
+
+#define A_1  0x00
+#define A_2  0x01
+#define A_3  0x02
+#define A_4  0x03
+#define A_5  0x04
+#define A_6  0x05
+#define A_7  0x06
+#define A_8  0x07
+#define A_9  0x08
+#define A_10  0x09
+#define A_11  0x0A
+#define A_12  0x0B
+#define A_13  0x0C
+#define A_14  0x0D
+#define A_15  0x0E
+#define A_16  0x0F
+
+#define B_1  0x10
+#define B_2  0x11
+#define B_3  0x12
+#define B_4  0x13
+#define B_5  0x14
+#define B_6  0x15
+#define B_7  0x16
+#define B_8  0x17
+#define B_9  0x18
+#define B_10  0x19
+#define B_11  0x1A
+#define B_12  0x1B
+#define B_13  0x1C
+#define B_14  0x1D
+#define B_15  0x1E
+#define B_16  0x1F
+
+#define C_1  0x20
+#define C_2  0x21
+#define C_3  0x22
+#define C_4  0x23
+#define C_5  0x24
+#define C_6  0x25
+#define C_7  0x26
+#define C_8  0x27
+#define C_9  0x28
+#define C_10  0x29
+#define C_11  0x2A
+#define C_12  0x2B
+#define C_13  0x2C
+#define C_14  0x2D
+#define C_15  0x2E
+#define C_16  0x2F
+
+#define D_1  0x30
+#define D_2  0x31
+#define D_3  0x32
+#define D_4  0x33
+#define D_5  0x34
+#define D_6  0x35
+#define D_7  0x36
+#define D_8  0x37
+#define D_9  0x38
+#define D_10  0x39
+#define D_11  0x3A
+#define D_12  0x3B
+#define D_13  0x3C
+#define D_14  0x3D
+#define D_15  0x3E
+#define D_16  0x3F
+
+#define E_1  0x40
+#define E_2  0x41
+#define E_3  0x42
+#define E_4  0x43
+#define E_5  0x44
+#define E_6  0x45
+#define E_7  0x46
+#define E_8  0x47
+#define E_9  0x48
+#define E_10  0x49
+#define E_11  0x4A
+#define E_12  0x4B
+#define E_13  0x4C
+#define E_14  0x4D
+#define E_15  0x4E
+#define E_16  0x4F
+
+#define F_1  0x50
+#define F_2  0x51
+#define F_3  0x52
+#define F_4  0x53
+#define F_5  0x54
+#define F_6  0x55
+#define F_7  0x56
+#define F_8  0x57
+#define F_9  0x58
+#define F_10  0x59
+#define F_11  0x5A
+#define F_12  0x5B
+#define F_13  0x5C
+#define F_14  0x5D
+#define F_15  0x5E
+#define F_16  0x5F
+
+#define G_1  0x60
+#define G_2  0x61
+#define G_3  0x62
+#define G_4  0x63
+#define G_5  0x64
+#define G_6  0x65
+#define G_7  0x66
+#define G_8  0x67
+#define G_9  0x68
+#define G_10  0x69
+#define G_11  0x6A
+#define G_12  0x6B
+#define G_13  0x6C
+#define G_14  0x6D
+#define G_15  0x6E
+#define G_16  0x6F
+
+#define H_1  0x70
+#define H_2  0x71
+#define H_3  0x72
+#define H_4  0x73
+#define H_5  0x74
+#define H_6  0x75
+#define H_7  0x76
+#define H_8  0x77
+#define H_9  0x78
+#define H_10  0x79
+#define H_11  0x7A
+#define H_12  0x7B
+#define H_13  0x7C
+#define H_14  0x7D
+#define H_15  0x7E
+#define H_16  0x7F
+
+#define I_1  0x80
+#define I_2  0x81
+#define I_3  0x82
+#define I_4  0x83
+#define I_5  0x84
+#define I_6  0x85
+#define I_7  0x86
+#define I_8  0x87
+#define I_9  0x88
+#define I_10  0x89
+#define I_11  0x8A
+#define I_12  0x8B
+#define I_13  0x8C
+#define I_14  0x8D
+#define I_15  0x8E
+#define I_16  0x8F
+
+#define J_1  0x90
+#define J_2  0x91
+#define J_3  0x92
+#define J_4  0x93
+#define J_5  0x94
+#define J_6  0x95
+#define J_7  0x96
+#define J_8  0x97
+#define J_9  0x98
+#define J_10  0x99
+#define J_11  0x9A
+#define J_12  0x9B
+#define J_13  0x9C
+#define J_14  0x9D
+#define J_15  0x9E
+#define J_16  0x9F
+
+#define K_1  0xA0
+#define K_2  0xA1
+#define K_3  0xA2
+#define K_4  0xA3
+#define K_5  0xA4
+#define K_6  0xA5
+#define K_7  0xA6
+#define K_8  0xA7
+#define K_9  0xA8
+#define K_10  0xA9
+#define K_11  0xAA
+#define K_12  0xAB
+#define K_13  0xAC
+#define K_14  0xAD
+#define K_15  0xAE
+#define K_16  0xAF
+
+#define L_1  0xB0
+#define L_2  0xB1
+#define L_3  0xB2
+#define L_4  0xB3
+#define L_5  0xB4
+#define L_6  0xB5
+#define L_7  0xB6
+#define L_8  0xB7
+#define L_9  0xB8
+#define L_10  0xB9
+#define L_11  0xBA
+#define L_12  0xBB
+#define L_13  0xBC
+#define L_14  0xBD
+#define L_15  0xBE
+#define L_16  0xBF
+
+#endif // IS31FL3733_DRIVER_H

+ 306 - 0
drivers/issi/is31fl3736.c

@@ -0,0 +1,306 @@
+/* Copyright 2018 Jason Williams (Wilba)
+ *
+ * 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/>.
+ */
+
+
+#ifdef __AVR__
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#else
+#include "wait.h"
+#endif
+
+#include "is31fl3736.h"
+#include <string.h>
+#include "i2c_master.h"
+#include "progmem.h"
+
+
+
+// This is a 7-bit address, that gets left-shifted and bit 0
+// set to 0 for write, 1 for read (as per I2C protocol)
+// The address will vary depending on your wiring:
+// 00 <-> GND
+// 01 <-> SCL
+// 10 <-> SDA
+// 11 <-> VCC
+// ADDR1 represents A1:A0 of the 7-bit address.
+// ADDR2 represents A3:A2 of the 7-bit address.
+// The result is: 0b101(ADDR2)(ADDR1)
+#define ISSI_ADDR_DEFAULT 0x50
+
+#define ISSI_COMMANDREGISTER 0xFD
+#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
+#define ISSI_INTERRUPTMASKREGISTER 0xF0
+#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
+
+#define ISSI_PAGE_LEDCONTROL 0x00 //PG0
+#define ISSI_PAGE_PWM 0x01        //PG1
+#define ISSI_PAGE_AUTOBREATH 0x02 //PG2
+#define ISSI_PAGE_FUNCTION 0x03   //PG3
+
+#define ISSI_REG_CONFIGURATION 0x00 //PG3
+#define ISSI_REG_GLOBALCURRENT 0x01 //PG3
+#define ISSI_REG_RESET 0x11// PG3
+#define ISSI_REG_SWPULLUP 0x0F //PG3
+#define ISSI_REG_CSPULLUP 0x10 //PG3
+
+#ifndef ISSI_TIMEOUT
+  #define ISSI_TIMEOUT 100
+#endif
+
+#ifndef ISSI_PERSISTENCE
+  #define ISSI_PERSISTENCE 0
+#endif
+
+// Transfer buffer for TWITransmitData()
+uint8_t g_twi_transfer_buffer[20];
+
+// These buffers match the IS31FL3736 PWM registers.
+// The control buffers match the PG0 LED On/Off registers.
+// Storing them like this is optimal for I2C transfers to the registers.
+// We could optimize this and take out the unused registers from these
+// buffers and the transfers in IS31FL3736_write_pwm_buffer() but it's
+// probably not worth the extra complexity.
+uint8_t g_pwm_buffer[DRIVER_COUNT][192];
+bool g_pwm_buffer_update_required = false;
+
+uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } };
+bool g_led_control_registers_update_required = false;
+
+void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data )
+{
+    g_twi_transfer_buffer[0] = reg;
+    g_twi_transfer_buffer[1] = data;
+
+  #if ISSI_PERSISTENCE > 0
+    for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+      if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
+        break;
+    }
+  #else
+    i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
+  #endif
+}
+
+void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
+{
+    // assumes PG1 is already selected
+
+    // transmit PWM registers in 12 transfers of 16 bytes
+    // g_twi_transfer_buffer[] is 20 bytes
+
+    // iterate over the pwm_buffer contents at 16 byte intervals
+    for ( int i = 0; i < 192; i += 16 ) {
+        g_twi_transfer_buffer[0] = i;
+        // copy the data from i to i+15
+        // device will auto-increment register for data after the first byte
+        // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
+        for ( int j = 0; j < 16; j++ ) {
+            g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
+        }
+
+    #if ISSI_PERSISTENCE > 0
+      for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
+        if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
+          break;
+      }
+    #else
+      i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
+    #endif
+    }
+}
+
+void IS31FL3736_init( uint8_t addr )
+{
+    // In order to avoid the LEDs being driven with garbage data
+    // in the LED driver's PWM registers, shutdown is enabled last.
+    // Set up the mode and other settings, clear the PWM registers,
+    // then disable software shutdown.
+
+    // Unlock the command register.
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG0
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
+    // Turn off all LEDs.
+    for ( int i = 0x00; i <= 0x17; i++ )
+    {
+        IS31FL3736_write_register( addr, i, 0x00 );
+    }
+
+    // Unlock the command register.
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG1
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
+    // Set PWM on all LEDs to 0
+    // No need to setup Breath registers to PWM as that is the default.
+    for ( int i = 0x00; i <= 0xBF; i++ )
+    {
+        IS31FL3736_write_register( addr, i, 0x00 );
+    }
+
+    // Unlock the command register.
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+
+    // Select PG3
+    IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION );
+    // Set global current to maximum.
+    IS31FL3736_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF );
+    // Disable software shutdown.
+    IS31FL3736_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 );
+
+    // Wait 10ms to ensure the device has woken up.
+    #ifdef __AVR__
+    _delay_ms( 10 );
+    #else
+    wait_ms(10);
+    #endif
+}
+
+void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
+{
+    if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
+        is31_led led = g_is31_leds[index];
+
+        g_pwm_buffer[led.driver][led.r] = red;
+        g_pwm_buffer[led.driver][led.g] = green;
+        g_pwm_buffer[led.driver][led.b] = blue;
+        g_pwm_buffer_update_required = true;
+    }
+}
+
+void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
+{
+    for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
+    {
+        IS31FL3736_set_color( i, red, green, blue );
+    }
+}
+
+void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
+{
+    is31_led led = g_is31_leds[index];
+
+    // IS31FL3733
+    // The PWM register for a matrix position (0x00 to 0xBF) can be
+    // divided by 8 to get the LED control register (0x00 to 0x17),
+    // then mod 8 to get the bit position within that register.
+
+    // IS31FL3736
+    // The PWM register for a matrix position (0x00 to 0xBF) is interleaved, so:
+    // A1=0x00 A2=0x02 A3=0x04 A4=0x06 A5=0x08 A6=0x0A A7=0x0C A8=0x0E
+    // B1=0x10 B2=0x12 B3=0x14
+    // But also, the LED control registers (0x00 to 0x17) are also interleaved, so:
+    // A1-A4=0x00 A5-A8=0x01
+    // So, the same math applies.
+
+	uint8_t control_register_r = led.r / 8;
+	uint8_t control_register_g = led.g / 8;
+	uint8_t control_register_b = led.b / 8;
+
+	uint8_t bit_r = led.r % 8;
+	uint8_t bit_g = led.g % 8;
+	uint8_t bit_b = led.b % 8;
+
+    if ( red ) {
+        g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
+    } else {
+        g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
+    }
+    if ( green ) {
+        g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
+    } else {
+        g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
+    }
+    if ( blue ) {
+        g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
+    } else {
+        g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
+    }
+
+    g_led_control_registers_update_required = true;
+
+}
+
+void IS31FL3736_mono_set_brightness( int index, uint8_t value )
+{
+    if ( index >= 0 && index < 96 ) {
+    	// Index in range 0..95 -> A1..A8, B1..B8, etc.
+    	// Map index 0..95 to registers 0x00..0xBE (interleaved)
+    	uint8_t pwm_register = index * 2;
+        g_pwm_buffer[0][pwm_register] = value;
+        g_pwm_buffer_update_required = true;
+    }
+}
+
+void IS31FL3736_mono_set_brightness_all( uint8_t value )
+{
+    for ( int i = 0; i < 96; i++ )
+    {
+    	IS31FL3736_mono_set_brightness( i, value );
+    }
+}
+
+void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled )
+{
+	// Index in range 0..95 -> A1..A8, B1..B8, etc.
+
+	// Map index 0..95 to registers 0x00..0xBE (interleaved)
+	uint8_t pwm_register = index * 2;
+	// Map register 0x00..0xBE (interleaved) into control register and bit
+	uint8_t control_register = pwm_register / 8;
+	uint8_t bit = pwm_register % 8;
+
+    if ( enabled ) {
+        g_led_control_registers[0][control_register] |= (1 << bit);
+    } else {
+        g_led_control_registers[0][control_register] &= ~(1 << bit);
+    }
+
+    g_led_control_registers_update_required = true;
+}
+
+void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_pwm_buffer_update_required )
+    {
+        // Firstly we need to unlock the command register and select PG1
+        IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+        IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
+
+        IS31FL3736_write_pwm_buffer( addr1, g_pwm_buffer[0] );
+        //IS31FL3736_write_pwm_buffer( addr2, g_pwm_buffer[1] );
+    }
+    g_pwm_buffer_update_required = false;
+}
+
+void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
+{
+    if ( g_led_control_registers_update_required )
+    {
+        // Firstly we need to unlock the command register and select PG0
+        IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
+        IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
+        for ( int i=0; i<24; i++ )
+        {
+            IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i] );
+            //IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i] );
+        }
+    }
+}
+

+ 172 - 0
drivers/issi/is31fl3736.h

@@ -0,0 +1,172 @@
+/* Copyright 2018 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+
+// Simple interface option.
+// If these aren't defined, just define them to make it compile
+
+
+#ifndef DRIVER_COUNT
+#define DRIVER_COUNT 2
+#endif
+
+#ifndef DRIVER_LED_TOTAL
+#define DRIVER_LED_TOTAL 96
+#endif
+
+
+typedef struct is31_led {
+  uint8_t driver:2;
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+} __attribute__((packed)) is31_led;
+
+extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
+
+void IS31FL3736_init( uint8_t addr );
+void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data );
+void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
+
+void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
+void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
+
+void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
+
+void IS31FL3736_mono_set_brightness( int index, uint8_t value );
+void IS31FL3736_mono_set_brightness_all( uint8_t value );
+void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled );
+
+// This should not be called from an interrupt
+// (eg. from a timer interrupt).
+// Call this while idle (in between matrix scans).
+// If the buffer is dirty, it will update the driver with the buffer.
+void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
+void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
+
+#define A_1  0x00
+#define A_2  0x02
+#define A_3  0x04
+#define A_4  0x06
+#define A_5  0x08
+#define A_6  0x0A
+#define A_7  0x0C
+#define A_8  0x0E
+
+#define B_1  0x10
+#define B_2  0x12
+#define B_3  0x14
+#define B_4  0x16
+#define B_5  0x18
+#define B_6  0x1A
+#define B_7  0x1C
+#define B_8  0x1E
+
+#define C_1  0x20
+#define C_2  0x22
+#define C_3  0x24
+#define C_4  0x26
+#define C_5  0x28
+#define C_6  0x2A
+#define C_7  0x2C
+#define C_8  0x2E
+
+#define D_1  0x30
+#define D_2  0x32
+#define D_3  0x34
+#define D_4  0x36
+#define D_5  0x38
+#define D_6  0x3A
+#define D_7  0x3C
+#define D_8  0x3E
+
+#define E_1  0x40
+#define E_2  0x42
+#define E_3  0x44
+#define E_4  0x46
+#define E_5  0x48
+#define E_6  0x4A
+#define E_7  0x4C
+#define E_8  0x4E
+
+#define F_1  0x50
+#define F_2  0x52
+#define F_3  0x54
+#define F_4  0x56
+#define F_5  0x58
+#define F_6  0x5A
+#define F_7  0x5C
+#define F_8  0x5E
+
+#define G_1  0x60
+#define G_2  0x62
+#define G_3  0x64
+#define G_4  0x66
+#define G_5  0x68
+#define G_6  0x6A
+#define G_7  0x6C
+#define G_8  0x6E
+
+#define H_1  0x70
+#define H_2  0x72
+#define H_3  0x74
+#define H_4  0x76
+#define H_5  0x78
+#define H_6  0x7A
+#define H_7  0x7C
+#define H_8  0x7E
+
+#define I_1  0x80
+#define I_2  0x82
+#define I_3  0x84
+#define I_4  0x86
+#define I_5  0x88
+#define I_6  0x8A
+#define I_7  0x8C
+#define I_8  0x8E
+
+#define J_1  0x90
+#define J_2  0x92
+#define J_3  0x94
+#define J_4  0x96
+#define J_5  0x98
+#define J_6  0x9A
+#define J_7  0x9C
+#define J_8  0x9E
+
+#define K_1  0xA0
+#define K_2  0xA2
+#define K_3  0xA4
+#define K_4  0xA6
+#define K_5  0xA8
+#define K_6  0xAA
+#define K_7  0xAC
+#define K_8  0xAE
+
+#define L_1  0xB0
+#define L_2  0xB2
+#define L_3  0xB4
+#define L_4  0xB6
+#define L_5  0xB8
+#define L_6  0xBA
+#define L_7  0xBC
+#define L_8  0xBE
+

+ 0 - 58
keyboards/1up60rgb/config.h

@@ -1,58 +0,0 @@
-#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    1upkeyboards
-#define PRODUCT         1UP RGB Underglow PCB
-#define DESCRIPTION     60% keyboard with RGB underglow
-
-/* key matrix size */
-#define MATRIX_ROWS 5
-#define MATRIX_COLS 15
-
-/* key matrix pins */
-#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }
-#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B7, D4, B1, B0, B5, B4, D7, D6, B3, F4 }
-#define UNUSED_PINS
-
-/* COL2ROW or ROW2COL */
-#define DIODE_DIRECTION COL2ROW
-
-/* number of backlight levels */
-#define BACKLIGHT_PIN B6
-#ifdef BACKLIGHT_PIN
-#define BACKLIGHT_LEVELS 5
-#endif
-
-/* Set 0 if debouncing isn't needed */
-#define DEBOUNCING_DELAY 5
-
-/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
-#define LOCKING_SUPPORT_ENABLE
-
-/* Locking resynchronize hack */
-#define LOCKING_RESYNC_ENABLE
-
-/* key combination for command */
-#define IS_COMMAND() ( \
-    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
-)
-
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-#define RGB_DI_PIN E2
-#ifdef RGB_DI_PIN
-#define RGBLIGHT_ANIMATIONS
-#define RGBLED_NUM 16
-#define RGBLIGHT_HUE_STEP 8
-#define RGBLIGHT_SAT_STEP 8
-#define RGBLIGHT_VAL_STEP 8
-#endif
-
-#endif

+ 0 - 13
keyboards/1up60rgb/readme.md

@@ -1,13 +0,0 @@
-# 1upkeyboards 60% RGB
-
-Firmware for custom keyboard PCB with 60% key layout.
-
-Keyboard Maintainer: [rempired](https://github.com/rempired)  
-Hardware Supported: 1upkeyboards 60% RGB  
-Hardware Availability: [1upkeyboards](https://1upkeyboards.com/rgb-underglow-1up-pcb.html)
-
-Make example for this keyboard (after setting up your build environment):
-
-    make 1up60rgb:default
-
-See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information.

+ 43 - 0
keyboards/1upkeyboards/1up60hse/1up60hse.c

@@ -0,0 +1,43 @@
+/* Copyright 2018 MechMerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "1up60hse.h"
+
+void matrix_init_kb(void) {
+	// put your keyboard start-up code here
+	// runs once when the firmware starts up
+
+	matrix_init_user();
+}
+
+void matrix_scan_kb(void) {
+	// put your looping keyboard code here
+	// runs every cycle (a lot)
+
+	matrix_scan_user();
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+	// put your per-action keyboard code here
+	// runs for every action, just before processing by the firmware
+
+	return process_record_user(keycode, record);
+}
+
+void led_set_kb(uint8_t usb_led) {
+	// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
+
+	led_set_user(usb_led);
+}

+ 39 - 0
keyboards/1upkeyboards/1up60hse/1up60hse.h

@@ -0,0 +1,39 @@
+/* Copyright 2018 MechMerlin
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KB_H
+#define KB_H
+
+#include "quantum.h"
+
+// This a shortcut to help you visually see your layout.
+// The first section contains all of the arguments representing the physical
+// layout of the board and position of the keys
+// The second converts the arguments into a two-dimensional array which 
+// represents the switch matrix. 
+#define LAYOUT_60_ansi( \
+	K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
+	K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+	K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \
+	K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A,           K3D, \
+	K40, K41, K42,             K45,              K49, K4A, K4B,      K4D  \
+) { \
+	{ K00,  K01,  K02,  K03,   K04,   K05, K06,   K07,   K08,   K09, K0A, K0B,   K0C,   K0D }, \
+	{ K10,  K11,  K12,  K13,   K14,   K15, K16,   K17,   K18,   K19, K1A, K1B,   K1C,   K1D }, \
+	{ K20,  K21,  K22,  K23,   K24,   K25, K26,   K27,   K28,   K29, K2A, K2B,   KC_NO, K2D }, \
+	{ K30,  K31,  K32,  K33,   K34,   K35, K36,   K37,   K38,   K39, K3A, KC_NO, KC_NO, K3D }, \
+	{ K40,  K41,  K42,  KC_NO, KC_NO, K45, KC_NO, KC_NO, KC_NO, K49, K4A, K4B,   KC_NO, K4D }  \
+}
+#endif

+ 224 - 0
keyboards/1upkeyboards/1up60hse/config.h

@@ -0,0 +1,224 @@
+/*
+Copyright 2018 MechMerlin
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID       0xFEED
+#define PRODUCT_ID      0x0000
+#define DEVICE_VER      0x0001
+#define MANUFACTURER    1upkeyboards
+#define PRODUCT         1up60hse
+#define DESCRIPTION     A custom 60% keyboard
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+
+/*
+ * Keyboard Matrix Assignments
+ *
+ * Change this to how you wired your keyboard
+ * COLS: AVR pins used for columns, left to right
+ * ROWS: AVR pins used for rows, top to bottom
+ * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
+ *                  ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
+ *
+*/
+#define MATRIX_ROW_PINS { B3, B2, B1, B0, D4 }
+#define MATRIX_COL_PINS { C7, F7, F6, F5, F4, F1, E6, D1, D0, D2, D3, D5, D6, D7 }
+#define UNUSED_PINS
+
+/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
+#define DIODE_DIRECTION COL2ROW
+
+#define BACKLIGHT_PIN B7
+#define BACKLIGHT_BREATHING
+#define BACKLIGHT_LEVELS 5
+
+#define RGB_DI_PIN F0
+#ifdef RGB_DI_PIN
+#define RGBLIGHT_ANIMATIONS
+#define RGBLED_NUM 14
+#define RGBLIGHT_HUE_STEP 8
+#define RGBLIGHT_SAT_STEP 8
+#define RGBLIGHT_VAL_STEP 8
+#endif
+
+/* 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
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+// #define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/*
+ * Magic Key Options
+ *
+ * Magic keys are hotkey commands that allow control over firmware functions of
+ * the keyboard. They are best used in combination with the HID Listen program,
+ * found here: https://www.pjrc.com/teensy/hid_listen.html
+ *
+ * The options below allow the magic key functionality to be changed. This is
+ * useful if your keyboard/keypad is missing keys and you want magic key support.
+ *
+ */
+
+/* key combination for magic key command */
+#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
+
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+   - MIDI notes can be sent when in Music mode is on
+*/
+//#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+   - MIDI notes can be added to the keymap
+   - Octave shift and transpose
+   - Virtual sustain, portamento, and modulation wheel
+   - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 1
+
+/*
+ * HD44780 LCD Display Configuration
+ */
+/*
+#define LCD_LINES           2     //< number of visible lines of the display
+#define LCD_DISP_LENGTH    16     //< visibles characters per line of the display
+
+#define LCD_IO_MODE      1            //< 0: memory mapped mode, 1: IO port mode
+
+#if LCD_IO_MODE
+#define LCD_PORT         PORTB        //< port for the LCD lines
+#define LCD_DATA0_PORT   LCD_PORT     //< port for 4bit data bit 0
+#define LCD_DATA1_PORT   LCD_PORT     //< port for 4bit data bit 1
+#define LCD_DATA2_PORT   LCD_PORT     //< port for 4bit data bit 2
+#define LCD_DATA3_PORT   LCD_PORT     //< port for 4bit data bit 3
+#define LCD_DATA0_PIN    4            //< pin for 4bit data bit 0
+#define LCD_DATA1_PIN    5            //< pin for 4bit data bit 1
+#define LCD_DATA2_PIN    6            //< pin for 4bit data bit 2
+#define LCD_DATA3_PIN    7            //< pin for 4bit data bit 3
+#define LCD_RS_PORT      LCD_PORT     //< port for RS line
+#define LCD_RS_PIN       3            //< pin  for RS line
+#define LCD_RW_PORT      LCD_PORT     //< port for RW line
+#define LCD_RW_PIN       2            //< pin  for RW line
+#define LCD_E_PORT       LCD_PORT     //< port for Enable line
+#define LCD_E_PIN        1            //< pin  for Enable line
+#endif
+*/
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 12 - 0
keyboards/1upkeyboards/1up60hse/info.json


+ 20 - 0
keyboards/1upkeyboards/1up60hse/keymaps/default/config.h

@@ -0,0 +1,20 @@
+/* Copyright 2018 MechMerlin
+ * Copyright 2018 Logan Huskins
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+// place overrides here

+ 0 - 0
keyboards/1upkeyboards/1up60hse/keymaps/default/keymap.c


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio