Compare commits
209 Commits
Author | SHA1 | Date | |
---|---|---|---|
afacd42368 | |||
23df5fb89a | |||
6bd2b8ded3 | |||
0373c4dc9e | |||
ff758496b3 | |||
922d9b77ad | |||
9d15f48427 | |||
e7d4bc5291 | |||
c6ea96ab43 | |||
63d5c947d3 | |||
466ee76423 | |||
d678724ca8 | |||
14b7602a65 | |||
46dca121fd | |||
1b4ad6b4ae | |||
ccc87421e7 | |||
303f425c6b | |||
9e5676650e | |||
06e5f9b25e | |||
280c10cb09 | |||
24efce0eca | |||
c9108f4b37 | |||
824e48f294 | |||
50b5c6ad72 | |||
5170398479 | |||
2e88f77675 | |||
1ef819ba96 | |||
72ea1fd972 | |||
e6be4484e9 | |||
1806509ad5 | |||
f969d5ed28 | |||
87612df54b | |||
6c1d6c3222 | |||
ec6f3e07c5 | |||
72b276bd8f | |||
c52b3c6126 | |||
9b91789193 | |||
d1dfefc897 | |||
ddb1c83695 | |||
e5540dd055 | |||
9b8fc6f1c0 | |||
3d96359f71 | |||
0495bf4491 | |||
b51ad39047 | |||
ec7223d9f0 | |||
5112af887a | |||
f756b72167 | |||
861dc88bc2 | |||
bde1c9d909 | |||
7a57446f5e | |||
f31a8f2738 | |||
9689944c16 | |||
aade625054 | |||
187d76476e | |||
43e589aa02 | |||
c76ab936c8 | |||
3aeaf4e3ea | |||
1ff7473ce4 | |||
de97c560f5 | |||
bc89c4f104 | |||
2054f20b69 | |||
c7d3f31f64 | |||
7216fd0f47 | |||
3b7b1994cd | |||
19aa2c34e8 | |||
6f37bd6678 | |||
3d6119856a | |||
5dc60c06a9 | |||
01a85b780c | |||
4afd970dc4 | |||
c17d15a305 | |||
625a243be8 | |||
0d98822144 | |||
102433d8bc | |||
376a384b23 | |||
34ce1ed016 | |||
17223166ce | |||
33671e5cd1 | |||
050c21d35f | |||
642bf00baf | |||
510510e9db | |||
6b45e8aec1 | |||
8d65d69b8d | |||
535a4d55ae | |||
66e40529aa | |||
80ccbc7b54 | |||
644efe48bf | |||
10d287d1aa | |||
eb89a372ec | |||
1c6b9323b2 | |||
4ad37331d3 | |||
4674664c4a | |||
32446eeeb6 | |||
1feb42a108 | |||
7d08e48c50 | |||
d1481172bc | |||
f440bbbc11 | |||
eef75b82bd | |||
6beb9d3ac2 | |||
2286cedb70 | |||
a0a4c9102c | |||
fda23af281 | |||
70101cf611 | |||
fb5115f6cd | |||
7801356bd4 | |||
5d5b161d80 | |||
7cb3c0e466 | |||
3c224bffc8 | |||
5ca9aecfb4 | |||
33fdd1d255 | |||
d1c3419d2a | |||
9a7347e357 | |||
e36d6bbbe3 | |||
14b2a35571 | |||
1bb77c0875 | |||
4e4101efdf | |||
46d12d90df | |||
c604cd6fd7 | |||
2a63e21279 | |||
503335be25 | |||
0912c42f04 | |||
3ea8bcb8ae | |||
0ce2cc8915 | |||
ded9390944 | |||
3cab04dfa3 | |||
1de6458921 | |||
3bb647910a | |||
5ec3bd9e40 | |||
d3c6da7aff | |||
47f55f417b | |||
eaa0b24335 | |||
75360ebdae | |||
8ec2269519 | |||
5226e4c79b | |||
7dda7158fb | |||
8b0b17a369 | |||
23b45710ac | |||
b4bdebab9a | |||
3d3c093173 | |||
a7fca47686 | |||
9ab786d1d8 | |||
ec9058f227 | |||
5aada76f12 | |||
e9d32b60b7 | |||
e2fb3079c7 | |||
13cdfb465d | |||
1b711453ca | |||
5d36118eaa | |||
b7d095fdc3 | |||
ed62c6e146 | |||
32fd5e4f61 | |||
fe8b9d0d0f | |||
412af0f4e7 | |||
d55ee204db | |||
cdb967f22b | |||
28307be72f | |||
530dd446cb | |||
22215a0e92 | |||
5319667c55 | |||
f10a0ae547 | |||
3d3716bbf7 | |||
6982e63a4a | |||
e8082b5f9e | |||
4cfd1e30fc | |||
0c4a6bf2db | |||
3caf0761cd | |||
05dcb48aa9 | |||
244b1ef79b | |||
0545428c14 | |||
885f06c6cf | |||
a33c0949e0 | |||
955a6586a3 | |||
f32e0200ed | |||
1f77868427 | |||
958521c359 | |||
3b525dcf9c | |||
f4a9e98383 | |||
c0baf2a964 | |||
5f4c2dfd84 | |||
b7dc17ef33 | |||
a859a2ee96 | |||
0f0c2da983 | |||
d78e630641 | |||
8478ef648f | |||
4cb7907547 | |||
25b1d02157 | |||
4feaf1fd76 | |||
d777a05864 | |||
7bbc9ccc31 | |||
0d0664a214 | |||
011039afca | |||
6cc9d59ee8 | |||
f281f7dc3a | |||
ba2cab1a89 | |||
738588618b | |||
67268db576 | |||
c25f0e6983 | |||
f6b3c67678 | |||
67053712f8 | |||
0ca6b53f89 | |||
6f3cbdb5f7 | |||
162a67cbc5 | |||
cc323df9ba | |||
deb5a4b6a9 | |||
61a2169ff9 | |||
adae37f19f | |||
015aed50a3 | |||
c6b5ce61e8 | |||
a74f866941 |
.gitignorebootloader.mkbuild_keyboard.mkcommon_features.mklets_split.hreadme.mdreadme.md
docs
.nojekyllREADME.md_sidebar.mdconfig_options.mddocumentation_best_practices.mdfeature_advanced_keycodes.mdfeature_audio.mdfeature_auto_shift.mdfeature_bootmagic.mdfeature_macros.mdfeature_rgb_matrix.mdfeature_stenography.mdfeature_tap_dance.mdfeature_terminal.mdfeature_userspace.mdflashing.mdgetting_started_github.mdhardware_avr.mdhardware_keyboard_guidelines.mdindex.htmlnewbs_building_firmware.mdnewbs_flashing.mdnewbs_getting_started.mdqmk.csssw.js
drivers
keyboards
1up60rgb
alf_x2
alpha
alps64
amj40
amj96
amjpad
atom47
atomic
atreus
atreus62
bananasplit
bananasplit.hinfo.jsonrules.mk
keymaps
0010
coloneljesus
default
hhkbanana
jockyxu1122_ansi
jockyxu1122_iso
kamon
nic
rask
bfake
bfo9000
bfo9000.cbfo9000.hconfig.hi2c.ci2c.h
keymaps/default
matrix.creadme.mdrules.mkserial.cserial.hsplit_util.csplit_util.hbigseries
ca66
chibios_test
chimera_ortho
christmas_tree
clueboard
2x1800
2x1800.c2x1800.hconfig.hinfo.jsonreadme.mdrules.mk
keymaps
default
default_4u
default_7u
macroboard
mouseboard_left
mouseboard_right
60
66
66_hotswap
readme.mdcontra
converter/ibm_terminal
cu24
cu75
deltasplit75
dilly/keymaps
diverge3
do60
dz60
dz60.hinfo.json
keymaps
256k_HHKB
60_ansi_arrow_fkeys
60_plus_arrows
Ansi_plus_fn_arrows
LEdiodes
atlacat
dbroqua
default
eric
f3d3
iso_6u_space
iso_7u_space
iso_vim_arrow
itsaferbie
model42
n0velty
tailcall
weeheavy
e6v2
eagle_viper
ergo42
keymaps
biacco-macOS
biacco
default-illustrator
default
hdbx
rev1
ergodone
ergodox_ez
ergodox_infinity
fc660c
fc980c
four_banger/keymaps/default
fourier
frosty_flake/keymaps/nikchi
gh60
handwired
arrow_pad/keymaps
dactyl
dactyl_manuform
maartenwut
numpad20
onekey
ortho5x13
terminus_mini
helix
hhkb
infinity60
iris
info.jsoniris.h
keymaps
davidrambo
default
drashna
hag
hexwire
impstyle
lewisridden
rdhaene
swedish
transmogrified
yanfali
rev1
rev1_led
rev2
jc65
v32a
v32u4
jd40
jd45
jj40
README.md
keymaps
jm60
k_type
kbd66
kbd75
kbd8x
kc60
kinesis
kmac
knops/mini
launchpad
lets_split
keymaps
DE_simple
OLED_sample
adam
cpeters1982
default
dlaroe
fabian
heartrobotninja
henxing
khord
kris
krusli
mbsurfer
mjt
normacos
piemod
pitty
poker
smt
waples
xk
xyverz
zer09
rev1
rev2
rules.mksockets
levinson
lfkeyboards
lightsaver
m10a
mechmini/v2
meira
meme
mf68
mf68_ble
minidox
mitosis
nakey
nano
niu_mini
novelpad
nyquist
octagon
omnikey_blackheart
orthodox
keymaps
rev1
rev3
rev3_teensy
pearl
phantom
planck
info.json
keymaps
ajp10304
altgr
beakl.hcolemak.h
common
chord_layout.hinit.hkeycode_functions.hnumber_fkey_layout.hnumber_fkey_layout.save.hplover_keybind.hsounds.hsteno_layout.hsymbol_guifn_layout.htapdance.htoggle_layout.h
config.hkeymap.cprivate_string.hqwerty.hreadme.mdrules.mkdanielhklein
davidrambo
default
dr_notsokind
hiea
common
chord_layout.hinit.hkeycode_functions.hnumber_fkey_layout.hplover_keybind.hsounds.hsteno_layout.hsymbol_guifn_layout.htapdance.htoggle_layout.h
config.hhiea.hkeymap.cqwerty.hreadme.mdrules.mkhieax
common
chord_layout.hinit.hkeycode_functions.hnumber_fkey_layout.hplover_keybind.hsounds.hsteno_layout.hsymbol_guifn_layout.htapdance.htoggle_layout.h
config.hhiea.hhiea.sync-conflict-20180501-144403-SMV4TP4.hkeymap.creadme.mdrules.mksascha
sdothum
light
rev3
rev4
rev5
rules.mkpreonic
info.json
keymaps
0xdec
CMD-Preonic
blake-newman
bucktooth
choromanski
default
dlaroe
dudeofawesome
ekis_isa
fig-r
jacwib
kinesis
nikchi
smt
that_canadian
xyverz
zach
rev1
rev2
ps2avrGB
rama/m6_a
redox
config.hi2c.ci2c.h
keymaps/default
matrix.creadme.mdredox.credox.hrev1
rules.mkserial.cserial.hsplit_util.csplit_util.hs60_x
default
keymaps
amnesia0287
ansi_qwertz
bluebear
custom
dbroqua
default
default_rgb
hasu
hhkb
iso
iso_rgb
jpec
plain
poker
poker_bit
poker_set
spacefn
rgb
s65_x
satan
keymaps
satan.hscrabblepad
speedo
staryu
sweet16
tada68
info.json
keymaps
tanuki
tkc1800
tv44
ut47
v60_type_r
viterbi
whitefox
xd60
info.jsonxd60.h
keymaps
Jos
birkir
cheese
default
edulpn
iso
kmontag42
krusli
petesmom
rooski
split_bksp_arrows
stanleylai
supercoffee
yuuki
xd75/keymaps
layouts/community
60_ansi
60_ansi_split_bs_rshift
ergodox
drashna
haegin
qwerty_code_friendly
zweihander-macos
ortho_4x12
quantum
audio
color.ccolor.hprocess_keycode
process_audio.cprocess_clicky.cprocess_clicky.hprocess_midi.cprocess_music.cprocess_music.hprocess_steno.cprocess_steno.hprocess_terminal.c
quantum.cquantum.hquantum_keycodes.hrgb.hrgb_matrix.crgb_matrix.hrgblight.crgblight.htemplate
tmk_core
users
drashna
losinggeneration
talljoe
zer09
util
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,6 +43,7 @@ doxygen/
|
||||
.project
|
||||
.settings/
|
||||
.idea
|
||||
*.iml
|
||||
.browse.VC.db*
|
||||
*.stackdump
|
||||
util/Win_Check_Output.txt
|
||||
|
@ -32,21 +32,41 @@
|
||||
ifeq ($(strip $(BOOTLOADER)), atmel-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_ATMEL_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_SIZE = 4096
|
||||
ifeq ($(strip $(MCU)), atmega32u4)
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifeq ($(strip $(MCU)), at90usb1286)
|
||||
BOOTLOADER_SIZE = 8192
|
||||
endif
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), lufa-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_LUFA_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_SIZE = 4096
|
||||
ifeq ($(strip $(MCU)), atmega32u4)
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifeq ($(strip $(MCU)), at90usb1286)
|
||||
BOOTLOADER_SIZE = 8192
|
||||
endif
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), qmk-dfu)
|
||||
OPT_DEFS += -DBOOTLOADER_QMK_DFU
|
||||
OPT_DEFS += -DBOOTLOADER_DFU
|
||||
BOOTLOADER_SIZE = 4096
|
||||
ifeq ($(strip $(MCU)), atmega32u4)
|
||||
BOOTLOADER_SIZE = 4096
|
||||
endif
|
||||
ifeq ($(strip $(MCU)), at90usb1286)
|
||||
BOOTLOADER_SIZE = 8192
|
||||
endif
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), halfkay)
|
||||
OPT_DEFS += -DBOOTLOADER_HALFKAY
|
||||
BOOTLOADER_SIZE = 512
|
||||
ifeq ($(strip $(MCU)), atmega32u4)
|
||||
BOOTLOADER_SIZE = 512
|
||||
endif
|
||||
ifeq ($(strip $(MCU)), at90usb1286)
|
||||
BOOTLOADER_SIZE = 1024
|
||||
endif
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), caterina)
|
||||
OPT_DEFS += -DBOOTLOADER_CATERINA
|
||||
@ -59,4 +79,4 @@ endif
|
||||
|
||||
ifdef BOOTLOADER_SIZE
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
|
||||
endif
|
||||
endif
|
||||
|
@ -143,6 +143,8 @@ ifeq ($(PLATFORM),CHIBIOS)
|
||||
OPT_DEFS += -include $(KEYBOARD_PATH_1)/bootloader_defs.h
|
||||
else ifneq ("$(wildcard $(KEYBOARD_PATH_1)/boards/$(BOARD)/bootloader_defs.h)","")
|
||||
OPT_DEFS += -include $(KEYBOARD_PATH_1)/boards/$(BOARD)/bootloader_defs.h
|
||||
else ifneq ("$(wildcard $(TOP_DIR)/drivers/boards/$(BOARD)/bootloader_defs.h)","")
|
||||
OPT_DEFS += -include $(TOP_DIR)/drivers/boards/$(BOARD)/bootloader_defs.h
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -202,8 +204,16 @@ else
|
||||
endif
|
||||
|
||||
# User space stuff
|
||||
USER_PATH := users/$(KEYMAP)
|
||||
ifeq ("$(USER_NAME)","")
|
||||
USER_NAME := $(KEYMAP)
|
||||
endif
|
||||
USER_PATH := users/$(USER_NAME)
|
||||
|
||||
-include $(USER_PATH)/rules.mk
|
||||
ifneq ("$(wildcard users/$(KEYMAP)/config.h)","")
|
||||
CONFIG_H += users/$(KEYMAP)/config.h
|
||||
endif
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
|
@ -34,6 +34,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes)
|
||||
OPT_DEFS += -DAUDIO_ENABLE
|
||||
MUSIC_ENABLE := 1
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
SRC += $(QUANTUM_DIR)/audio/audio.c
|
||||
else
|
||||
@ -113,6 +114,15 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
OPT_DEFS += -DRGB_MATRIX_ENABLE
|
||||
SRC += is31fl3731.c
|
||||
SRC += TWIlib.c
|
||||
SRC += $(QUANTUM_DIR)/color.c
|
||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||
CIE1931_CURVE = yes
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
||||
OPT_DEFS += -DTAP_DANCE_ENABLE
|
||||
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
||||
|
@ -1,18 +1,25 @@
|
||||
# Quantum Mechanical Keyboard Firmware
|
||||
|
||||
## What is QMK Firmware? {#what-is-qmk-firmware}
|
||||
[](https://github.com/qmk/qmk_firmware/tags)
|
||||
[](https://travis-ci.org/qmk/qmk_firmware)
|
||||
[](https://discord.gg/Uq7gcHh)
|
||||
[](https://docs.qmk.fm)
|
||||
[](https://github.com/qmk/qmk_firmware/pulse/monthly)
|
||||
[](https://github.com/qmk/qmk_firmware/)
|
||||
|
||||
## What is QMK Firmware?
|
||||
|
||||
QMK (*Quantum Mechanical Keyboard*) is an open source community that maintains QMK Firmware, QMK Flasher, qmk.fm, and these docs. QMK Firmware is a keyboard firmware based on the [tmk\_keyboard](http://github.com/tmk/tmk_keyboard) with some useful features for Atmel AVR controllers, and more specifically, the [OLKB product line](http://olkb.com), the [ErgoDox EZ](http://www.ergodox-ez.com) keyboard, and the [Clueboard product line](http://clueboard.co/). It has also been ported to ARM chips using ChibiOS. You can use it to power your own hand-wired or custom keyboard PCB.
|
||||
|
||||
## How to Get It {#how-to-get-it}
|
||||
## How to Get It
|
||||
|
||||
If you plan on contributing a keymap, keyboard, or features to QMK, the easiest thing to do is [fork the repo through Github](https://github.com/qmk/qmk_firmware#fork-destination-box), and clone your repo locally to make your changes, push them, then open a [Pull Request](https://github.com/qmk/qmk_firmware/pulls) from your fork.
|
||||
|
||||
Otherwise, you can either download it directly ([zip](https://github.com/qmk/qmk_firmware/zipball/master), [tar](https://github.com/qmk/qmk_firmware/tarball/master)), or clone it via git (`git@github.com:qmk/qmk_firmware.git`), or https (`https://github.com/qmk/qmk_firmware.git`).
|
||||
|
||||
## How to Compile {#how-to-compile}
|
||||
## How to Compile
|
||||
|
||||
Before you are able to compile, you'll need to [install an environment](getting_started_build_tools.md) for AVR or/and ARM development. Once that is complete, you'll use the `make` command to build a keyboard and keymap with the following notation:
|
||||
Before you are able to compile, you'll need to [install an environment](01_Getting_Started/01_Install_Build_Tools.md) for AVR or/and ARM development. Once that is complete, you'll use the `make` command to build a keyboard and keymap with the following notation:
|
||||
|
||||
make planck/rev4:default
|
||||
|
||||
@ -20,6 +27,6 @@ This would build the `rev4` revision of the `planck` with the `default` keymap.
|
||||
|
||||
make preonic:default
|
||||
|
||||
## How to Customize {#how-to-customize}
|
||||
## How to Customize
|
||||
|
||||
QMK has lots of [features](features.md) to explore, and a good deal of [reference documentation](http://docs.qmk.fm) to dig through. Most features are taken advantage of by modifying your [keymap](keymap.md), and changing the [keycodes](keycodes.md).
|
||||
QMK has lots of [features](05_Features/index.md) to explore, and a good deal of [reference documentation](http://docs.qmk.fm) to dig through. Most features are taken advantage of by modifying your [keymap](07_Reference/Keymap_Overview.md), and changing the [keycodes](06_Keycodes/index.md).
|
||||
|
99
docs/_sidebar.md
Normal file
99
docs/_sidebar.md
Normal file
@ -0,0 +1,99 @@
|
||||
* [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)
|
||||
|
||||
* [FAQ](faq.md)
|
||||
* [General FAQ](faq_general.md)
|
||||
* [Build/Compile QMK](faq_build.md)
|
||||
* [Debugging/Troubleshooting QMK](faq_debug.md)
|
||||
* [Keymap](faq_keymap.md)
|
||||
|
||||
* [Hardware](hardware.md)
|
||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||
* [AVR Processors](hardware_avr.md)
|
||||
* ARM Processors (TBD)
|
||||
* [Drivers](hardware_drivers.md)
|
||||
|
||||
* [Features](features.md)
|
||||
* [Advanced Keycodes](feature_advanced_keycodes.md)
|
||||
* [Audio](feature_audio.md)
|
||||
* [Auto Shift](feature_auto_shift.md)
|
||||
* [Backlight](feature_backlight.md)
|
||||
* [Bootmagic](feature_bootmagic.md)
|
||||
* [Command](feature_command.md)
|
||||
* [Dynamic Macros](feature_dynamic_macros.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)
|
||||
* [Pointing Device](feature_pointing_device.md)
|
||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||
* [RGB Lighting](feature_rgblight.md)
|
||||
* [Space Cadet Shift](feature_space_cadet.md)
|
||||
* [Space Cadet Shift Enter](feature_space_shift_cadet.md)
|
||||
* [Stenography](feature_stenography.md)
|
||||
* [Swap Hands](feature_swap_hands.md)
|
||||
* [Tap Dance](feature_tap_dance.md)
|
||||
* [Terminal](feature_terminal.md)
|
||||
* [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)
|
||||
|
||||
* For a Deeper Understanding
|
||||
* [How Keyboards Work](how_keyboards_work.md)
|
||||
* [Understanding QMK](understanding_qmk.md)
|
||||
|
||||
* Other Topics
|
||||
* [Using Eclipse with QMK](eclipse.md)
|
||||
|
||||
* QMK Internals (In Progress)
|
||||
* [Defines](internals_defines.md)
|
||||
* [Input Callback Reg](internals_input_callback_reg.md)
|
||||
* [Midi Device](internals_midi_device.md)
|
||||
* [Midi Device Setup Process](internals_midi_device_setup_process.md)
|
||||
* [Midi Util](internals_midi_util.md)
|
||||
* [Send Functions](internals_send_functions.md)
|
||||
* [Sysex Tools](internals_sysex_tools.md)
|
@ -61,10 +61,18 @@ This is a C header file that is one of the first things included, and will persi
|
||||
* COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows.
|
||||
* `#define AUDIO_VOICES`
|
||||
* turns on the alternate audio voices (to cycle through)
|
||||
* `#define C4_AUDIO`
|
||||
* enables audio on pin C4
|
||||
* `#define C5_AUDIO`
|
||||
* enables audio on pin C5
|
||||
* `#define C6_AUDIO`
|
||||
* enables audio on pin C6
|
||||
* `#define B5_AUDIO`
|
||||
* enables audio on pin B5 (duophony is enable if both are enabled)
|
||||
* enables audio on pin B5 (duophony is enables if one of B[5-7]_AUDIO is enabled along with one of C[4-6]_AUDIO)
|
||||
* `#define B6_AUDIO`
|
||||
* enables audio on pin B6 (duophony is enables if one of B[5-7]_AUDIO is enabled along with one of C[4-6]_AUDIO)
|
||||
* `#define B7_AUDIO`
|
||||
* enables audio on pin B7 (duophony is enables if one of B[5-7]_AUDIO is enabled along with one of C[4-6]_AUDIO)
|
||||
* `#define BACKLIGHT_PIN B7`
|
||||
* pin of the backlight - B5, B6, B7 use PWM, others use softPWM
|
||||
* `#define BACKLIGHT_LEVELS 3`
|
||||
@ -81,6 +89,8 @@ This is a C header file that is one of the first things included, and will persi
|
||||
* tries to keep switch state consistent with keyboard LED state
|
||||
* `#define IS_COMMAND() ( keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) )`
|
||||
* 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)
|
||||
|
||||
## Features That Can Be Disabled
|
||||
|
||||
@ -108,7 +118,7 @@ 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`
|
||||
* when switching layers, this will release all mods
|
||||
* 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
|
||||
|
||||
## Behaviors That Can Be Configured
|
||||
|
||||
|
@ -22,60 +22,27 @@ Your page should generally have multiple "H1" headings. Only H1 and H2 headings
|
||||
|
||||
You can have styled hint blocks drawn around text to draw attention to it.
|
||||
|
||||
```
|
||||
{% hint style='info' %}
|
||||
This uses `hint style='info'`
|
||||
{% endhint %}
|
||||
```
|
||||
|
||||
### Examples:
|
||||
|
||||
{% hint style='info' %}
|
||||
This uses `hint style='info'`
|
||||
{% endhint %}
|
||||
|
||||
{% hint style='tip' %}
|
||||
This uses `hint style='tip'`
|
||||
{% endhint %}
|
||||
|
||||
{% hint style='danger' %}
|
||||
This uses `hint style='danger'`
|
||||
{% endhint %}
|
||||
|
||||
{% hint style='working' %}
|
||||
This uses `hint style='working'`
|
||||
{% endhint %}
|
||||
|
||||
# Styled Terminal Blocks
|
||||
|
||||
You can present styled terminal blocks by including special tokens inside your text block.
|
||||
### Important
|
||||
|
||||
```
|
||||
\`\`\`
|
||||
**[terminal]
|
||||
**[prompt foo@joe]**[path ~]**[delimiter $ ]**[command ./myscript]
|
||||
Normal output line. Nothing special here...
|
||||
But...
|
||||
You can add some colors. What about a warning message?
|
||||
**[warning [WARNING] The color depends on the theme. Could look normal too]
|
||||
What about an error message?
|
||||
**[error [ERROR] This is not the error you are looking for]
|
||||
\`\`\`
|
||||
!> This is important
|
||||
```
|
||||
|
||||
### Example
|
||||
Renders as:
|
||||
|
||||
!> This is important
|
||||
|
||||
### General Tips
|
||||
|
||||
```
|
||||
**[terminal]
|
||||
**[prompt foo@joe]**[path ~]**[delimiter $ ]**[command ./myscript]
|
||||
Normal output line. Nothing special here...
|
||||
But...
|
||||
You can add some colors. What about a warning message?
|
||||
**[warning [WARNING] The color depends on the theme. Could look normal too]
|
||||
What about an error message?
|
||||
**[error [ERROR] This is not the error you are looking for]
|
||||
?> This is a helpful tip.
|
||||
```
|
||||
|
||||
Renders as:
|
||||
|
||||
?> This is a helpful tip.
|
||||
|
||||
|
||||
# Documenting Features
|
||||
|
||||
If you create a new feature for QMK, create a documentation page for it. It doesn't have to be very long, a few sentences describing your feature and a table listing any relevant keycodes is enough. Here is a basic template:
|
||||
@ -94,4 +61,4 @@ This page describes my cool feature. You can use my cool feature to make coffee
|
||||
|KC_SUGAR||Order Sugar|
|
||||
```
|
||||
|
||||
Place your documentation into `docs/feature_<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_summary.md`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.
|
||||
Place your documentation into `docs/feature_<my_cool_feature>.md`, and add that file to the appropriate place in `docs/_sidebar.md`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page.
|
||||
|
@ -19,14 +19,15 @@ Currently, the keycodes able to used with these functions are limited to the [Ba
|
||||
|
||||
# Switching and Toggling Layers
|
||||
|
||||
These functions allow you to activate layers in various ways.
|
||||
These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. For a detailed explanation of layers, see [Keymap Overview](keymap.md#keymap-and-layers)
|
||||
|
||||
* `MO(layer)` - momentary switch to *layer*. As soon as you let go of the key, the layer is deactivated and you pop back out to the previous layer.
|
||||
* `LT(layer, kc)` - momentary switch to *layer* when held, and *kc* when tapped.
|
||||
* `TG(layer)` - toggles a layer on or off.
|
||||
* `TO(layer)` - Goes to a layer. This code is special, because it lets you go either up or down the stack -- just goes directly to the layer you want. So while other codes only let you go _up_ the stack (from layer 0 to layer 3, for example), `TO(2)` is going to get you to layer 2, no matter where you activate it from -- even if you're currently on layer 5. This gets activated on keydown (as soon as the key is pressed).
|
||||
* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, the layer becomes active, and then deactivates when you let go. And if you repeatedly tap it, the layer simply becomes active (toggles on). It needs 5 taps by default, but you can set it by defining `TAPPING_TOGGLE`, for example, `#define TAPPING_TOGGLE 2` for just two taps.
|
||||
* `LM(layer, mod)` - Momentary switch to *layer* (like MO), but with modifier(s) *mod* active. Only supports layers 0-15 and the left modifiers.
|
||||
* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions.md#programming-the-behavior-of-any-keycode).)
|
||||
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
||||
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15 and the left modifiers.
|
||||
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped.
|
||||
* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa
|
||||
* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed).
|
||||
* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps.
|
||||
|
||||
# Working with Layers
|
||||
|
||||
@ -36,9 +37,9 @@ Care must be taken when switching layers, it's possible to lock yourself into a
|
||||
|
||||
If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers:
|
||||
|
||||
* Setup layer 0 as your "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.)
|
||||
* Setup layer 0 as your default, "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.). It's important to set this as the lowest layer since it will typically have most or all of the keyboard's keys defined, so would block other layers from having any effect if it were above them (i.e., had a higher layer number).
|
||||
* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer.
|
||||
* Never try to stack a higher numbered layer on top of a lower numbered layer. Doing so is tricky and error prone.
|
||||
* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone.
|
||||
|
||||
### Intermediate Users
|
||||
|
||||
@ -130,11 +131,9 @@ We've added shortcuts to make common modifier/tap (mod-tap) mappings more compac
|
||||
* `LCAG_T(kc)` - is CtrlAltGui when held and *kc* when tapped
|
||||
* `MEH_T(kc)` - is like Hyper, but not as cool -- does not include the Cmd/Win key, so just sends Alt+Ctrl+Shift.
|
||||
|
||||
{% hint style='info' %}
|
||||
Due to the way that keycodes are structured, any modifiers specified as part of `kc`, such as `LCTL()` or `KC_LPRN`, will only activate when held instead of tapped.
|
||||
?> Due to the way that keycodes are structured, any modifiers specified as part of `kc`, such as `LCTL()` or `KC_LPRN`, will only activate when held instead of tapped.
|
||||
|
||||
Additionally, if there is at least one right modifier, any other modifiers will turn into their right equivalents, so it is not possible to "mix and match" the two.
|
||||
{% endhint %}
|
||||
?> Additionally, if there is at least one right modifier, any other modifiers will turn into their right equivalents, so it is not possible to "mix and match" the two.
|
||||
|
||||
# One Shot Keys
|
||||
|
||||
|
@ -1,6 +1,17 @@
|
||||
# Audio
|
||||
|
||||
Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to the C6 or B5 port (`#define C6_AUDIO` and/or `#define B5_AUDIO`), you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes.
|
||||
Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes.
|
||||
|
||||
Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h:
|
||||
Timer 1:
|
||||
`#define B5_AUDIO`
|
||||
`#define B6_AUDIO`
|
||||
`#define B7_AUDIO`
|
||||
|
||||
Timer 3:
|
||||
`#define C4_AUDIO`
|
||||
`#define C5_AUDIO`
|
||||
`#define C6_AUDIO`
|
||||
|
||||
If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration:
|
||||
|
||||
@ -78,6 +89,20 @@ By default, `MUSIC_MASK` is set to `keycode < 0xFF` which means keycodes less th
|
||||
|
||||
Which will capture all keycodes - be careful, this will get you stuck in music mode until you restart your keyboard!
|
||||
|
||||
For a more advanced way to control which keycodes should still be processed, you can use `music_mask_kb(keycode)` in `<keyboard>.c` and `music_mask_user(keycode)` in your `keymap.c`:
|
||||
|
||||
bool music_mask_user(uint16_t keycode) {
|
||||
switch (keycode) {
|
||||
case RAISE:
|
||||
case LOWER:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Things that return false are not part of the mask, and are always processed.
|
||||
|
||||
The pitch standard (`PITCH_STANDARD_A`) is 440.0f by default - to change this, add something like this to your `config.h`:
|
||||
|
||||
#define PITCH_STANDARD_A 432.0f
|
||||
@ -86,6 +111,36 @@ You can completely disable Music Mode as well. This is useful, if you're pressed
|
||||
|
||||
#define NO_MUSIC_MODE
|
||||
|
||||
## Faux 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
|
||||
|
||||
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:
|
||||
|
||||
| Option | Default Value | Description |
|
||||
|--------|---------------|-------------|
|
||||
| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | Sets the default/starting audio frequency for the clicky sounds. |
|
||||
| `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. |
|
||||
|
||||
|
||||
|
||||
|
||||
## MIDI Functionality
|
||||
|
||||
This is still a WIP, but check out `quantum/keymap_midi.c` to see what's happening. Enable from the Makefile.
|
||||
|
@ -88,10 +88,7 @@ occasion. This is simply due to habit and holding some keys a little longer
|
||||
than others. Once you find this value, work on tapping your problem keys a little
|
||||
quicker than normal and you will be set.
|
||||
|
||||
{% hint style='info' %}
|
||||
Auto Shift has three special keys that can help you get this value right very
|
||||
quick. See "Auto Shift Setup" for more details!
|
||||
{% endhint %}
|
||||
?> Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details!
|
||||
|
||||
### NO_AUTO_SHIFT_SPECIAL (simple define)
|
||||
|
||||
|
@ -6,7 +6,7 @@ Bootmagic is a system for configuring your keyboard while it initializes. To tri
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code.
|
||||
|
||||
{% hint style='danger' %}
|
||||
**Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor.
|
||||
{% endhint %}
|
||||
!> **Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor.
|
||||
|
||||
## The New Way: `SEND_STRING()` & `process_record_user`
|
||||
|
||||
@ -132,9 +130,7 @@ SEND_STRING(".."SS_TAP(X_END));
|
||||
|
||||
## The Old Way: `MACRO()` & `action_get_macro`
|
||||
|
||||
{% hint style='info' %}
|
||||
This is inherited from TMK, and hasn't been updated - it's recommend that you use `SEND_STRING` and `process_record_user` instead.
|
||||
{% endhint %}
|
||||
?> This is inherited from TMK, and hasn't been updated - it's recommend that you use `SEND_STRING` and `process_record_user` instead.
|
||||
|
||||
By default QMK assumes you don't have any macros. To define your macros you create an `action_get_macro()` function. For example:
|
||||
|
||||
|
143
docs/feature_rgb_matrix.md
Normal file
143
docs/feature_rgb_matrix.md
Normal file
@ -0,0 +1,143 @@
|
||||
# RGB Matrix Lighting
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
// 0b1110100 AD <-> GND
|
||||
// 0b1110111 AD <-> VCC
|
||||
// 0b1110101 AD <-> SCL
|
||||
// 0b1110110 AD <-> SDA
|
||||
#define DRIVER_ADDR_1 0b1110100
|
||||
#define DRIVER_ADDR_2 0b1110110
|
||||
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_1_LED_TOTAL 25
|
||||
#define DRIVER_2_LED_TOTAL 24
|
||||
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
|
||||
|
||||
Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations.
|
||||
|
||||
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, C1_3, C2_3, C3_3},
|
||||
....
|
||||
}
|
||||
|
||||
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).
|
||||
|
||||
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
|
||||
/* {row | col << 4}
|
||||
* | {x=0..224, y=0..64}
|
||||
* | | modifier
|
||||
* | | | */
|
||||
{{0|(0<<4)}, {20.36*0, 21.33*0}, 1},
|
||||
{{0|(1<<4)}, {20.36*1, 21.33*0}, 1},
|
||||
....
|
||||
}
|
||||
|
||||
The format for the matrix position used in this array is `{row | (col << 4)}`. The `x` is between (inclusive) 0-224, and `y` is between (inclusive) 0-64. The easiest way to calculate these positions is:
|
||||
|
||||
x = 224 / ( NUMBER_OF_ROWS - 1 ) * ROW_POSITION
|
||||
y = 64 / (NUMBER_OF_COLS - 1 ) * COL_POSITION
|
||||
|
||||
Where all variables are decimels/floats.
|
||||
|
||||
`modifier` is a boolean, whether or not a certain key is considered a modifier (used in some effects).
|
||||
|
||||
## Keycodes
|
||||
|
||||
All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||
|
||||
* `RGB_TOG` - toggle
|
||||
* `RGB_MOD` - cycle through modes
|
||||
* `RGB_HUI` - increase hue
|
||||
* `RGB_HUD` - decrease hue
|
||||
* `RGB_SAI` - increase saturation
|
||||
* `RGB_SAD` - decrease saturation
|
||||
* `RGB_VAI` - increase value
|
||||
* `RGB_VAD` - decrease value
|
||||
* `RGB_SPI` - increase speed effect (no EEPROM support)
|
||||
* `RGB_SPD` - decrease speed effect (no EEPROM support)
|
||||
|
||||
|
||||
* `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system
|
||||
|
||||
## RGB Matrix Effects
|
||||
|
||||
These are the effects that are currently available:
|
||||
|
||||
enum rgb_matrix_effects {
|
||||
RGB_MATRIX_SOLID_COLOR = 1,
|
||||
RGB_MATRIX_SOLID_REACTIVE,
|
||||
RGB_MATRIX_ALPHAS_MODS,
|
||||
RGB_MATRIX_DUAL_BEACON,
|
||||
RGB_MATRIX_GRADIENT_UP_DOWN,
|
||||
RGB_MATRIX_RAINDROPS,
|
||||
RGB_MATRIX_CYCLE_ALL,
|
||||
RGB_MATRIX_CYCLE_LEFT_RIGHT,
|
||||
RGB_MATRIX_CYCLE_UP_DOWN,
|
||||
RGB_MATRIX_RAINBOW_BEACON,
|
||||
RGB_MATRIX_RAINBOW_PINWHEELS,
|
||||
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
|
||||
RGB_MATRIX_JELLYBEAN_RAINDROPS,
|
||||
#ifdef RGB_MATRIX_KEYPRESSES
|
||||
RGB_MATRIX_SPLASH,
|
||||
RGB_MATRIX_MULTISPLASH,
|
||||
RGB_MATRIX_SOLID_SPLASH,
|
||||
RGB_MATRIX_SOLID_MULTISPLASH,
|
||||
#endif
|
||||
RGB_MATRIX_EFFECT_MAX
|
||||
};
|
||||
|
||||
## 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);
|
||||
}
|
||||
|
||||
A similar function works in the keymap as `rgb_matrix_indicators_user`.
|
||||
|
||||
## Additional `config.h` Options
|
||||
|
||||
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
|
||||
#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
|
||||
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
|
||||
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended
|
||||
#define RGB_MATRIX_SKIP_FRAMES 1 // number of frames to skip when displaying animations (0 is full effect)
|
||||
|
||||
## EEPROM storage
|
||||
|
||||
The EEPROM for it is currently shared with the RGBLIGHT system (it's generally assumed only one RGB would be used at a time), but could be configured to use its own 32bit address with:
|
||||
|
||||
#define EECONFIG_RGB_MATRIX (uint32_t *)16
|
||||
|
||||
Where `16` is an unused index from `eeconfig.h`.
|
||||
|
||||
## Suspended state
|
||||
|
||||
To use the suspend feature, add this to your `<keyboard>.c`:
|
||||
|
||||
void suspend_power_down_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(true);
|
||||
}
|
||||
|
||||
void suspend_wakeup_init_kb(void)
|
||||
{
|
||||
rgb_matrix_set_suspend_state(false);
|
||||
}
|
@ -56,6 +56,29 @@ On the display tab click 'Open stroke display'. With Plover disabled you should
|
||||
* [Steno Jig](https://joshuagrams.github.io/steno-jig/)
|
||||
* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki
|
||||
|
||||
## Interfacing with the code
|
||||
|
||||
The steno code has three interceptible hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things.
|
||||
|
||||
```C
|
||||
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]);
|
||||
```
|
||||
|
||||
This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen.
|
||||
|
||||
```C
|
||||
bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
|
||||
```
|
||||
|
||||
This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values.
|
||||
|
||||
```C
|
||||
bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
|
||||
```
|
||||
|
||||
This function is called after a key has been processed, but before any decision about whether or not to send a chord. If `IS_PRESSED(record->event)` is false, and `pressed` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This is where to put hooks for things like, say, live displays of steno chords or keys.
|
||||
|
||||
|
||||
## Keycode Reference
|
||||
|
||||
As defined in `keymap_steno.h`.
|
||||
@ -106,3 +129,4 @@ As defined in `keymap_steno.h`.
|
||||
|`STN_RES1`||(GeminiPR only)|
|
||||
|`STN_RES2`||(GeminiPR only)|
|
||||
|`STN_PWR`||(GeminiPR only)|
|
||||
|
||||
|
@ -22,7 +22,7 @@ This array specifies what actions shall be taken when a tap-dance key is in acti
|
||||
* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action.
|
||||
* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function on when the dance action finishes (like the previous option), and the last function when the tap dance action resets.
|
||||
|
||||
The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise.
|
||||
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.
|
||||
|
||||
And that's the bulk of it!
|
||||
|
||||
@ -179,42 +179,124 @@ Below is a specific example:
|
||||
* Double Tap = Send `Escape`
|
||||
* Double Tap and Hold = Send `Alt`
|
||||
|
||||
The following example can be easily expanded to more than 4 quite easily:
|
||||
## Setup
|
||||
|
||||
You will need a few things that can be used for 'Quad Function Tap-Dance'. The suggested setup is to create a user directory for yourself. This directory will contain rules.mk `<your_name>.c` and `<your_name>.h`. This directory should be called `<your_name>`, and located in the top level `users` directory. There should already be a few examples to look at there.
|
||||
|
||||
### In `/qmk_firmware/users/<your_name>/rules.mk`
|
||||
|
||||
Put the following:
|
||||
```c
|
||||
//**************** Definitions needed for quad function to work *********************//
|
||||
//Enums used to clearly convey the state of the tap dance
|
||||
TAP_DANCE_ENABLE = yes
|
||||
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`
|
||||
|
||||
You will need a few things in this file:
|
||||
|
||||
```c
|
||||
#ifndef YOUR_NAME
|
||||
#define YOUR_NAME
|
||||
|
||||
#include "quantum.h"
|
||||
#include "process_keycode/process_tap_dance.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool is_press_action;
|
||||
int state;
|
||||
} xtap;
|
||||
|
||||
enum {
|
||||
SINGLE_TAP = 1,
|
||||
SINGLE_HOLD = 2,
|
||||
DOUBLE_TAP = 3,
|
||||
DOUBLE_HOLD = 4,
|
||||
DOUBLE_SINGLE_TAP = 5 //send SINGLE_TAP twice - NOT DOUBLE_TAP
|
||||
// Add more enums here if you want for triple, quadruple, etc.
|
||||
DOUBLE_SINGLE_TAP = 5, //send two single taps
|
||||
TRIPLE_TAP = 6,
|
||||
TRIPLE_HOLD = 7
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
bool is_press_action;
|
||||
int state;
|
||||
} tap;
|
||||
//Tap dance enums
|
||||
enum {
|
||||
CTL_X = 0,
|
||||
SOME_OTHER_DANCE
|
||||
}
|
||||
|
||||
int cur_dance (qk_tap_dance_state_t *state);
|
||||
|
||||
//for the x tap dance. Put it here so it can be used in any keymap
|
||||
void x_finished (qk_tap_dance_state_t *state, void *user_data);
|
||||
void x_reset (qk_tap_dance_state_t *state, void *user_data);
|
||||
```
|
||||
|
||||
### In `/qmk_firmware/users/<your_name>/<your_name>.c`
|
||||
|
||||
And then in your user's `.c` file you implement the functions above:
|
||||
|
||||
```c
|
||||
#include "gordon.h"
|
||||
#include "quantum.h"
|
||||
#include "action.h"
|
||||
#include "process_keycode/process_tap_dance.h"
|
||||
|
||||
/* Return an integer that corresponds to what kind of tap dance should be executed.
|
||||
*
|
||||
* How to figure out tap dance state: interrupted and pressed.
|
||||
*
|
||||
* Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
|
||||
* under the tapping term. This is typically indicitive that you are trying to "tap" the key.
|
||||
*
|
||||
* Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
|
||||
* has ended, but the key is still being pressed down. This generally means the key is being "held".
|
||||
*
|
||||
* One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
|
||||
* feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
|
||||
* For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
|
||||
*
|
||||
* Good places to put an advanced tap dance:
|
||||
* z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
|
||||
*
|
||||
* Criteria for "good placement" of a tap dance key:
|
||||
* Not a key that is hit frequently in a sentence
|
||||
* Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
|
||||
* in a web form. So 'tab' would be a poor choice for a tap dance.
|
||||
* Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
|
||||
* letter 'p', the word 'pepper' would be quite frustating to type.
|
||||
*
|
||||
* For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested
|
||||
*
|
||||
*/
|
||||
int cur_dance (qk_tap_dance_state_t *state) {
|
||||
if (state->count == 1) {
|
||||
//If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP
|
||||
if (state->interrupted || state->pressed==0) return SINGLE_TAP;
|
||||
if (state->interrupted || !state->pressed) return SINGLE_TAP;
|
||||
//key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'.
|
||||
else return SINGLE_HOLD;
|
||||
}
|
||||
//If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
|
||||
//with single tap. In example below, that means to send `xx` instead of `Escape`.
|
||||
else if (state->count == 2) {
|
||||
/*
|
||||
* DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
|
||||
* action when hitting 'pp'. Suggested use case for this return value is when you want to send two
|
||||
* keystrokes of the key, and not the 'double tap' action/macro.
|
||||
*/
|
||||
if (state->interrupted) return DOUBLE_SINGLE_TAP;
|
||||
else if (state->pressed) return DOUBLE_HOLD;
|
||||
else return DOUBLE_TAP;
|
||||
}
|
||||
else return 6; //magic number. At some point this method will expand to work for more presses
|
||||
//Assumes no one is trying to type the same letter three times (at least not quickly).
|
||||
//If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add
|
||||
//an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP'
|
||||
if (state->count == 3) {
|
||||
if (state->interrupted || !state->pressed) return TRIPLE_TAP;
|
||||
else return TRIPLE_HOLD;
|
||||
}
|
||||
else return 8; //magic number. At some point this method will expand to work for more presses
|
||||
}
|
||||
|
||||
//**************** Definitions needed for quad function to work *********************//
|
||||
|
||||
//instanalize an instance of 'tap' for the 'x' tap dance.
|
||||
static tap xtap_state = {
|
||||
.is_press_action = true,
|
||||
@ -245,6 +327,10 @@ void x_reset (qk_tap_dance_state_t *state, void *user_data) {
|
||||
}
|
||||
xtap_state.state = 0;
|
||||
}
|
||||
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
[X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,x_finished, x_reset)
|
||||
};
|
||||
```
|
||||
And then simply add this to your list of tap dance functions:
|
||||
`[X_TAP_DANCE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)`
|
||||
|
||||
And then simply use TD(X_CTL) anywhere in your keymap.
|
||||
|
@ -14,12 +14,14 @@ When enabled, a `> ` prompt will appear, where you'll be able to type, backspace
|
||||
|
||||
`#define TERMINAL_HELP` enables some other output helpers that aren't really needed with this page.
|
||||
|
||||
Pressing "up" and "down" will allow you to cycle through the past 5 commands entered.
|
||||
|
||||
## Future Ideas
|
||||
|
||||
* Keyboard/user-extensible commands
|
||||
* Smaller footprint
|
||||
* Arrow key support
|
||||
* Command history
|
||||
* Command history - Done
|
||||
* SD card support
|
||||
* LCD support for buffer display
|
||||
* Keycode -> name string LUT
|
||||
@ -43,14 +45,39 @@ QMK Firmware
|
||||
Built: 2017-08-29-20:24:44
|
||||
```
|
||||
|
||||
|
||||
### `print-buffer`
|
||||
|
||||
Outputs the last 5 commands entered
|
||||
|
||||
```
|
||||
> print-buffer
|
||||
0. print-buffer
|
||||
1. help
|
||||
2. about
|
||||
3. keymap 0
|
||||
4. help
|
||||
5. flush-buffer
|
||||
```
|
||||
|
||||
### `flush-buffer`
|
||||
|
||||
Clears command buffer
|
||||
```
|
||||
> flush-buffer
|
||||
Buffer cleared!
|
||||
```
|
||||
|
||||
|
||||
### `help`
|
||||
|
||||
|
||||
Prints out the available commands:
|
||||
|
||||
```
|
||||
> help
|
||||
commands available:
|
||||
about help keycode keymap exit
|
||||
about help keycode keymap exit print-buffer flush-buffer
|
||||
```
|
||||
|
||||
### `keycode <layer> <row> <col>`
|
||||
|
@ -3,10 +3,11 @@
|
||||
If you use more than one keyboard with a similar keymap, you might see the benefit in being able to share code between them. Create your own folder in `users/` named the same as your keymap (ideally your github username, `<name>`) with the following structure:
|
||||
|
||||
* `/users/<name>/` (added to the path automatically)
|
||||
* `readme.md`
|
||||
* `readme.md` (optional, recommended)
|
||||
* `rules.mk` (included automatically)
|
||||
* `<name>.h` (optional)
|
||||
* `<name>.c` (optional)
|
||||
* `config.h` (optional)
|
||||
|
||||
`<name>.c` will need to be added to the SRC in `rules.mk` like this:
|
||||
|
||||
@ -24,10 +25,31 @@ For example,
|
||||
|
||||
Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`.
|
||||
|
||||
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.
|
||||
|
||||
## Readme
|
||||
|
||||
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`
|
||||
|
||||
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:
|
||||
|
||||
```c
|
||||
#ifndef USERSPACE_CONFIG_H
|
||||
#define USERSPACE_CONFIG_H
|
||||
|
||||
// Put normal config.h settings here:
|
||||
|
||||
#endif // !USERSPACE_CONFIG_H
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
## Example
|
||||
|
||||
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/` .
|
||||
@ -93,3 +115,11 @@ 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.
|
||||
|
||||
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
|
||||
```
|
@ -20,7 +20,7 @@ Compatible flashers:
|
||||
|
||||
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI)
|
||||
* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` in QMK (recommended command line)
|
||||
* [Atmel's Flip](http://www.atmel.com/tools/flip.aspx) (not recommended)
|
||||
* [Atmel's Flip](http://www.microchip.com/developmenttools/productdetails.aspx?partno=flip) (not recommended)
|
||||
|
||||
Flashing sequence:
|
||||
|
||||
|
@ -2,9 +2,7 @@
|
||||
|
||||
Github can be a little tricky to those that aren't familiar with it - this guide will walk through each step of forking, cloning, and submitting a pull request with QMK.
|
||||
|
||||
{% hint style='info' %}
|
||||
This guide assumes you're somewhat comfortable with running things at the command line, and have git installed on your system.
|
||||
{% endhint %}
|
||||
?> This guide assumes you're somewhat comfortable with running things at the command line, and have git installed on your system.
|
||||
|
||||
Start on the [QMK Github page](https://github.com/qmk/qmk_firmware), and you'll see a button in the upper right that says "Fork":
|
||||
|
||||
|
@ -66,9 +66,7 @@ Do change the `MANUFACTURER`, `PRODUCT`, and `DESCRIPTION` lines to accurately r
|
||||
#define DESCRIPTION A custom keyboard
|
||||
```
|
||||
|
||||
{% hint style='info' %}
|
||||
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.
|
||||
{% endhint %}
|
||||
?> 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.
|
||||
|
||||
### Keyboard Matrix Configuration
|
||||
|
||||
|
@ -22,7 +22,7 @@ Given the amount of functionality that QMK exposes it's very easy to confuse new
|
||||
|
||||
### Bootmagic and Command
|
||||
|
||||
(Bootmagic)[feature_bootmagic.md) and (Command)[feature_command.md) are two related features that allow a user to control their keyboard in non-obvious ways. We recommend you think long and hard about if you're going to enable either feature, and how you will expose this functionality. Keep in mind that users who want this functionality can enable it in their personal keymaps without affecting all the novice users who may be using your keyboard as their first programmable board.
|
||||
[Bootmagic](feature_bootmagic.md) and [Command](feature_command.md) are two related features that allow a user to control their keyboard in non-obvious ways. We recommend you think long and hard about if you're going to enable either feature, and how you will expose this functionality. Keep in mind that users who want this functionality can enable it in their personal keymaps without affecting all the novice users who may be using your keyboard as their first programmable board.
|
||||
|
||||
By far the most common problem new users encounter is accidentally triggering Bootmagic while they're plugging in their keyboard. They're holding the keyboard by the bottom, unknowingly pressing in alt and spacebar, and then they find that these keys have been swapped on them. We recommend leaving this feature disabled by default, but if you do turn it on consider setting `BOOTMAGIC_KEY_SALT` to a key that is hard to press while plugging your keyboard in.
|
||||
|
||||
@ -30,7 +30,7 @@ If your keyboard does not have 2 shift keys you should provide a working default
|
||||
|
||||
## Custom Keyboard Programming
|
||||
|
||||
As documented on (Customizing Functionality)[custom_quantum_functions.md] you can define custom functions for your keyboard. Please keep in mind that your users may want to customize that behavior as well, and make it possible for them to do that. If you are providing a custom function, for example `process_record_kb()`, make sure that your function calls the `_user()` version of the call too. You should also take into account the return value of the `_user()` version, and only run your custom code if the user returns `true`.
|
||||
As documented on [Customizing Functionality](custom_quantum_functions.md) you can define custom functions for your keyboard. Please keep in mind that your users may want to customize that behavior as well, and make it possible for them to do that. If you are providing a custom function, for example `process_record_kb()`, make sure that your function calls the `_user()` version of the call too. You should also take into account the return value of the `_user()` version, and only run your custom code if the user returns `true`.
|
||||
|
||||
## Keyboard Metadata
|
||||
|
||||
@ -45,17 +45,8 @@ The `info.json` file is a JSON formatted dictionary with the following keys avai
|
||||
* `keyboard_name`
|
||||
* A free-form text string describing the keyboard.
|
||||
* Example: `Clueboard 66%`
|
||||
* `manufacturer`
|
||||
* A free-form text string naming the manufacturer.
|
||||
* Example: `Clueboard`
|
||||
* `identifier`
|
||||
* The Vendor, Product, and Revision ID's joined by a :
|
||||
* Example: `c1ed:2370:0001`
|
||||
* `url`
|
||||
* A URL to the keyboard's product page, [QMK.fm/keyboards](https://qmk.fm/keyboards) page, or other page describing information about the keyboard.
|
||||
* `processor`
|
||||
* The MCU or CPU this keyboard uses.
|
||||
* Example: `atmega32u4` or `stm32f303`
|
||||
* `bootloader`
|
||||
* What bootloader this keyboard uses. Available options:
|
||||
* `atmel-dfu`
|
||||
|
45
docs/index.html
Normal file
45
docs/index.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Document</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Description">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" title="light">
|
||||
<link rel="stylesheet" href="qmk.css" title="dark" disabled>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: 'QMK Firmware',
|
||||
nameLink: 'https://qmk.fm/',
|
||||
repo: 'qmk/qmk_firmware',
|
||||
loadSidebar: true,
|
||||
auto2top: true,
|
||||
formatUpdated: '{YYYY}/{MM}/{DD} {HH}:{mm}',
|
||||
search: {
|
||||
paths: 'auto',
|
||||
placeholder: 'Search Documentation...',
|
||||
noData: 'We could not find any documents matching your search.',
|
||||
depth: 6
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-c.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-cpp.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-json.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-makefile.min.js"></script>
|
||||
<script>
|
||||
// Register the offline cache worker
|
||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||
navigator.serviceWorker.register('sw.js')
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -8,17 +8,15 @@ If you have closed and reopened your terminal window since following the first p
|
||||
|
||||
Start by navigating to the `keymaps` folder for your keyboard.
|
||||
|
||||
{% hint style='info' %}
|
||||
If you are on macOS or Windows there are commands you can use to easily open the keymaps folder.
|
||||
?> If you are on macOS or Windows there are commands you can use to easily open the keymaps folder.
|
||||
|
||||
macOS:
|
||||
?> macOS:
|
||||
|
||||
open keyboards/<keyboard_folder>/keymaps
|
||||
|
||||
Windows:
|
||||
?> Windows:
|
||||
|
||||
start keyboards/<keyboard_folder>/keymaps
|
||||
{% endhint %}
|
||||
|
||||
## Create a Copy Of The `default` Keymap
|
||||
|
||||
@ -32,9 +30,7 @@ Open up your `keymap.c`. Inside this file you'll find the structure that control
|
||||
|
||||
This line indicates the start of the list of Layers. Below that you'll find lines containing either `LAYOUT` or `KEYMAP`, and these lines indicate the start of a layer. Below that line is the list of keys that comprise a that particular layer.
|
||||
|
||||
{% hint style='danger' %}
|
||||
When editing your keymap file be careful not to add or remove any commas. If you do you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is.
|
||||
{% endhint %}
|
||||
!> When editing your keymap file be careful not to add or remove any commas. If you do you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is.
|
||||
|
||||
## Customize The Layout To Your Liking
|
||||
|
||||
@ -44,9 +40,7 @@ How to complete this step is entirely up to you. Make the one change that's been
|
||||
* [Features](features.md)
|
||||
* [FAQ](faq.md)
|
||||
|
||||
{% hint style='info' %}
|
||||
While you get a feel for how keymaps work, keep each change small. Bigger changes make it harder to debug any problems that arise.
|
||||
{% endhint %}
|
||||
?> While you get a feel for how keymaps work, keep each change small. Bigger changes make it harder to debug any problems that arise.
|
||||
|
||||
## Build Your Firmware
|
||||
|
||||
|
@ -12,17 +12,15 @@ However, the QMK Toolbox is only available for Windows and macOS currently. If
|
||||
|
||||
Begin by opening the QMK Toolbox application. You'll want to locate the firmware file in Finder or Explorer. Your keyboard firmware may be in one of two formats- `.hex` or `.bin`. QMK tries to copy the appropriate one for your keyboard into the root `qmk_firmware` directory.
|
||||
|
||||
{% hint style='info' %}
|
||||
If you are on Windows or macOS there are commands you can use to easily open the current firmware folder in Explorer or Finder.
|
||||
?> If you are on Windows or macOS there are commands you can use to easily open the current firmware folder in Explorer or Finder.
|
||||
|
||||
Windows:
|
||||
?> Windows:
|
||||
|
||||
start .
|
||||
|
||||
macOS:
|
||||
?> macOS:
|
||||
|
||||
open .
|
||||
{% endhint %}
|
||||
|
||||
The firmware file always follows this naming format:
|
||||
|
||||
|
@ -14,9 +14,7 @@ Before you can build keymaps you need to install some software and setup your bu
|
||||
|
||||
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 you can not use TextEdit.app, it will not save plain text files. You will need to install another program such as Sublime Text.
|
||||
|
||||
{% hint style='info' %}
|
||||
Not sure which text editor to use? Laurence Bradford wrote [a great introduction](https://learntocodewith.me/programming/basics/text-editors/) to the subject.
|
||||
{% endhint %}
|
||||
?> 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
|
||||
|
||||
@ -29,12 +27,9 @@ QMK Toolbox is a Windows and macOS program that allows you to both program and d
|
||||
|
||||
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.
|
||||
|
||||
{% hint style="info" %}
|
||||
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:
|
||||
|
||||
* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
|
||||
* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html)
|
||||
{% endhint %}
|
||||
?> 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>
|
||||
[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
|
||||
|
||||
@ -63,9 +58,7 @@ Once you have setup your Linux/Unix environment you are ready to download QMK. W
|
||||
git clone https://github.com/qmk/qmk_firmware.git
|
||||
cd qmk_firmware
|
||||
|
||||
{% hint style='info' %}
|
||||
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.
|
||||
{% endhint %}
|
||||
?> 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
|
||||
|
||||
|
862
docs/qmk.css
Normal file
862
docs/qmk.css
Normal file
File diff suppressed because it is too large
Load Diff
83
docs/sw.js
Normal file
83
docs/sw.js
Normal file
@ -0,0 +1,83 @@
|
||||
/* ===========================================================
|
||||
* docsify sw.js
|
||||
* ===========================================================
|
||||
* Copyright 2016 @huxpro
|
||||
* Licensed under Apache 2.0
|
||||
* Register service worker.
|
||||
* ========================================================== */
|
||||
|
||||
const RUNTIME = 'docsify'
|
||||
const HOSTNAME_WHITELIST = [
|
||||
self.location.hostname,
|
||||
'fonts.gstatic.com',
|
||||
'fonts.googleapis.com',
|
||||
'unpkg.com'
|
||||
]
|
||||
|
||||
// The Util Function to hack URLs of intercepted requests
|
||||
const getFixedUrl = (req) => {
|
||||
var now = Date.now()
|
||||
var url = new URL(req.url)
|
||||
|
||||
// 1. fixed http URL
|
||||
// Just keep syncing with location.protocol
|
||||
// fetch(httpURL) belongs to active mixed content.
|
||||
// And fetch(httpRequest) is not supported yet.
|
||||
url.protocol = self.location.protocol
|
||||
|
||||
// 2. add query for caching-busting.
|
||||
// Github Pages served with Cache-Control: max-age=600
|
||||
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
|
||||
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
|
||||
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
|
||||
if (url.hostname === self.location.hostname) {
|
||||
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
|
||||
}
|
||||
return url.href
|
||||
}
|
||||
|
||||
/**
|
||||
* @Lifecycle Activate
|
||||
* New one activated when old isnt being used.
|
||||
*
|
||||
* waitUntil(): activating ====> activated
|
||||
*/
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil(self.clients.claim())
|
||||
})
|
||||
|
||||
/**
|
||||
* @Functional Fetch
|
||||
* All network requests are being intercepted here.
|
||||
*
|
||||
* void respondWith(Promise<Response> r)
|
||||
*/
|
||||
self.addEventListener('fetch', event => {
|
||||
// Skip some of cross-origin requests, like those for Google Analytics.
|
||||
if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) {
|
||||
// Stale-while-revalidate
|
||||
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
|
||||
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
|
||||
const cached = caches.match(event.request)
|
||||
const fixedUrl = getFixedUrl(event.request)
|
||||
const fetched = fetch(fixedUrl, { cache: 'no-store' })
|
||||
const fetchedCopy = fetched.then(resp => resp.clone())
|
||||
|
||||
// Call respondWith() with whatever we get first.
|
||||
// If the fetch fails (e.g disconnected), wait for the cache.
|
||||
// If there’s nothing in cache, wait for the fetch.
|
||||
// If neither yields a response, return offline pages.
|
||||
event.respondWith(
|
||||
Promise.race([fetched.catch(_ => cached), cached])
|
||||
.then(resp => resp || fetched)
|
||||
.catch(_ => { /* eat any errors */ })
|
||||
)
|
||||
|
||||
// Update the cache with the version we fetched (only for ok status)
|
||||
event.waitUntil(
|
||||
Promise.all([fetchedCopy, caches.open(RUNTIME)])
|
||||
.then(([response, cache]) => response.ok && cache.put(event.request, response))
|
||||
.catch(_ => { /* eat any errors */ })
|
||||
)
|
||||
}
|
||||
})
|
232
drivers/avr/TWIlib.c
Normal file
232
drivers/avr/TWIlib.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* TWIlib.c
|
||||
*
|
||||
* Created: 6/01/2014 10:41:33 PM
|
||||
* Author: Chris Herring
|
||||
* http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "TWIlib.h"
|
||||
#include "util/delay.h"
|
||||
|
||||
void TWIInit()
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWIInfo.repStart = 0;
|
||||
// Set pre-scalers (no pre-scaling)
|
||||
TWSR = 0;
|
||||
// Set bit rate
|
||||
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
|
||||
// Enable TWI and interrupt
|
||||
TWCR = (1 << TWIE) | (1 << TWEN);
|
||||
}
|
||||
|
||||
uint8_t isTWIReady()
|
||||
{
|
||||
if ( (TWIInfo.mode == Ready) | (TWIInfo.mode == RepeatedStartSent) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TWITransmitData(void *const TXdata, uint8_t dataLen, uint8_t repStart)
|
||||
{
|
||||
if (dataLen <= TXMAXBUFLEN)
|
||||
{
|
||||
// Wait until ready
|
||||
while (!isTWIReady()) {_delay_us(1);}
|
||||
// Set repeated start mode
|
||||
TWIInfo.repStart = repStart;
|
||||
// Copy data into the transmit buffer
|
||||
uint8_t *data = (uint8_t *)TXdata;
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
{
|
||||
TWITransmitBuffer[i] = data[i];
|
||||
}
|
||||
// Copy transmit info to global variables
|
||||
TXBuffLen = dataLen;
|
||||
TXBuffIndex = 0;
|
||||
|
||||
// If a repeated start has been sent, then devices are already listening for an address
|
||||
// and another start does not need to be sent.
|
||||
if (TWIInfo.mode == RepeatedStartSent)
|
||||
{
|
||||
TWIInfo.mode = Initializing;
|
||||
TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
|
||||
TWISendTransmit(); // Send the data
|
||||
}
|
||||
else // Otherwise, just send the normal start signal to begin transmission.
|
||||
{
|
||||
TWIInfo.mode = Initializing;
|
||||
TWISendStart();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; // return an error if data length is longer than buffer
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t TWIReadData(uint8_t TWIaddr, uint8_t bytesToRead, uint8_t repStart)
|
||||
{
|
||||
// Check if number of bytes to read can fit in the RXbuffer
|
||||
if (bytesToRead < RXMAXBUFLEN)
|
||||
{
|
||||
// Reset buffer index and set RXBuffLen to the number of bytes to read
|
||||
RXBuffIndex = 0;
|
||||
RXBuffLen = bytesToRead;
|
||||
// Create the one value array for the address to be transmitted
|
||||
uint8_t TXdata[1];
|
||||
// Shift the address and AND a 1 into the read write bit (set to write mode)
|
||||
TXdata[0] = (TWIaddr << 1) | 0x01;
|
||||
// Use the TWITransmitData function to initialize the transfer and address the slave
|
||||
TWITransmitData(TXdata, 1, repStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ISR (TWI_vect)
|
||||
{
|
||||
switch (TWI_STATUS)
|
||||
{
|
||||
// ----\/ ---- MASTER TRANSMITTER OR WRITING ADDRESS ----\/ ---- //
|
||||
case TWI_MT_SLAW_ACK: // SLA+W transmitted and ACK received
|
||||
// Set mode to Master Transmitter
|
||||
TWIInfo.mode = MasterTransmitter;
|
||||
case TWI_START_SENT: // Start condition has been transmitted
|
||||
case TWI_MT_DATA_ACK: // Data byte has been transmitted, ACK received
|
||||
if (TXBuffIndex < TXBuffLen) // If there is more data to send
|
||||
{
|
||||
TWDR = TWITransmitBuffer[TXBuffIndex++]; // Load data to transmit buffer
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendTransmit(); // Send the data
|
||||
}
|
||||
// This transmission is complete however do not release bus yet
|
||||
else if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
|
||||
// ----\/ ---- MASTER RECEIVER ----\/ ---- //
|
||||
|
||||
case TWI_MR_SLAR_ACK: // SLA+R has been transmitted, ACK has been received
|
||||
// Switch to Master Receiver mode
|
||||
TWIInfo.mode = MasterReceiver;
|
||||
// If there is more than one byte to be read, receive data byte and return an ACK
|
||||
if (RXBuffIndex < RXBuffLen-1)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendACK();
|
||||
}
|
||||
// Otherwise when a data byte (the only data byte) is received, return NACK
|
||||
else
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendNACK();
|
||||
}
|
||||
break;
|
||||
|
||||
case TWI_MR_DATA_ACK: // Data has been received, ACK has been transmitted.
|
||||
|
||||
/// -- HANDLE DATA BYTE --- ///
|
||||
TWIReceiveBuffer[RXBuffIndex++] = TWDR;
|
||||
// If there is more than one byte to be read, receive data byte and return an ACK
|
||||
if (RXBuffIndex < RXBuffLen-1)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendACK();
|
||||
}
|
||||
// Otherwise when a data byte (the only data byte) is received, return NACK
|
||||
else
|
||||
{
|
||||
TWIInfo.errorCode = TWI_NO_RELEVANT_INFO;
|
||||
TWISendNACK();
|
||||
}
|
||||
break;
|
||||
|
||||
case TWI_MR_DATA_NACK: // Data byte has been received, NACK has been transmitted. End of transmission.
|
||||
|
||||
/// -- HANDLE DATA BYTE --- ///
|
||||
TWIReceiveBuffer[RXBuffIndex++] = TWDR;
|
||||
// This transmission is complete however do not release bus yet
|
||||
if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = 0xFF;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
|
||||
// ----\/ ---- MT and MR common ----\/ ---- //
|
||||
|
||||
case TWI_MR_SLAR_NACK: // SLA+R transmitted, NACK received
|
||||
case TWI_MT_SLAW_NACK: // SLA+W transmitted, NACK received
|
||||
case TWI_MT_DATA_NACK: // Data byte has been transmitted, NACK received
|
||||
case TWI_LOST_ARBIT: // Arbitration has been lost
|
||||
// Return error and send stop and set mode to ready
|
||||
if (TWIInfo.repStart)
|
||||
{
|
||||
TWIInfo.errorCode = TWI_STATUS;
|
||||
TWISendStart();
|
||||
}
|
||||
// All transmissions are complete, exit
|
||||
else
|
||||
{
|
||||
TWIInfo.mode = Ready;
|
||||
TWIInfo.errorCode = TWI_STATUS;
|
||||
TWISendStop();
|
||||
}
|
||||
break;
|
||||
case TWI_REP_START_SENT: // Repeated start has been transmitted
|
||||
// Set the mode but DO NOT clear TWINT as the next data is not yet ready
|
||||
TWIInfo.mode = RepeatedStartSent;
|
||||
break;
|
||||
|
||||
// ----\/ ---- SLAVE RECEIVER ----\/ ---- //
|
||||
|
||||
// TODO IMPLEMENT SLAVE RECEIVER FUNCTIONALITY
|
||||
|
||||
// ----\/ ---- SLAVE TRANSMITTER ----\/ ---- //
|
||||
|
||||
// TODO IMPLEMENT SLAVE TRANSMITTER FUNCTIONALITY
|
||||
|
||||
// ----\/ ---- MISCELLANEOUS STATES ----\/ ---- //
|
||||
case TWI_NO_RELEVANT_INFO: // It is not really possible to get into this ISR on this condition
|
||||
// Rather, it is there to be manually set between operations
|
||||
break;
|
||||
case TWI_ILLEGAL_START_STOP: // Illegal START/STOP, abort and return error
|
||||
TWIInfo.errorCode = TWI_ILLEGAL_START_STOP;
|
||||
TWIInfo.mode = Ready;
|
||||
TWISendStop();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user