Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fe4097792 | ||
|
|
652f4492d3 | ||
|
|
910c466cfe | ||
|
|
19dbcf3814 | ||
|
|
c89012566c | ||
|
|
9dfebb9d67 | ||
|
|
2a31fbf9a6 | ||
|
|
cce2420bb2 | ||
|
|
b272c035ba | ||
|
|
5f1f370463 | ||
|
|
49a2fbea0c | ||
|
|
4b1430fd09 | ||
|
|
f1c6fa3895 | ||
|
|
fe1a055391 | ||
|
|
c18b51e68e | ||
|
|
dc68418660 | ||
|
|
499d7c8ce6 | ||
|
|
60b020acab | ||
|
|
b5be96f8bb | ||
|
|
7aa21cc287 | ||
|
|
d597af9e1e | ||
|
|
03ed819717 | ||
|
|
141535c9db | ||
|
|
a92947fcdb | ||
|
|
cde5237a88 | ||
|
|
dc79792ab4 | ||
|
|
e6a9f700de | ||
|
|
0fdd37ee19 | ||
|
|
40e8d60ecd | ||
|
|
f81b0e35a6 | ||
|
|
5e98eaaaff | ||
|
|
9e8767917d | ||
|
|
f89439ae09 | ||
|
|
3cd2a27ac0 | ||
|
|
28d94b7248 | ||
|
|
abd8e75cb7 | ||
|
|
9046107183 | ||
|
|
2b63896466 | ||
|
|
6734a39811 | ||
|
|
799acb2802 | ||
|
|
18bc525493 | ||
|
|
4edb5a5e8c | ||
|
|
3b5fd4cc51 | ||
|
|
cd9a430d66 | ||
|
|
1b267d4840 | ||
|
|
32d03eef90 | ||
|
|
f2f2afe13b | ||
|
|
3a3ea03b6e | ||
|
|
f3afc716cb | ||
|
|
e72562fe6f | ||
|
|
2b66acf04a | ||
|
|
5ac6fe1888 | ||
|
|
979ac0d8da | ||
|
|
7a89b51018 | ||
|
|
2a05d433c9 | ||
|
|
1aa40dde46 | ||
|
|
2ffb08843b | ||
|
|
2a8ccafe6e | ||
|
|
1757960b7b | ||
|
|
668121bbf8 | ||
|
|
483ab88489 | ||
|
|
dbbab40981 | ||
|
|
20a0fa9209 | ||
|
|
2d14d12c74 | ||
|
|
0ba352356d | ||
|
|
a4fd5e2491 | ||
|
|
5e3951b361 | ||
|
|
5e4fcfac1c | ||
|
|
89ef9de98c | ||
|
|
6c8d815f2e | ||
|
|
2271da00bc | ||
|
|
6e28ff24ba | ||
|
|
d526117896 | ||
|
|
cf40c33c90 | ||
|
|
4b7a3b2265 | ||
|
|
829906969c | ||
|
|
e0d15e6182 | ||
|
|
3a303bd2ae | ||
|
|
d7ba0ad684 | ||
|
|
c4d8e56928 | ||
|
|
5e1ce3988d | ||
|
|
dd05007f3b | ||
|
|
2306c974e5 | ||
|
|
833c5ae87a | ||
|
|
57de9e65ef | ||
|
|
6b6e47cbf1 | ||
|
|
54b6bf5910 | ||
|
|
73728e9bec | ||
|
|
4f1a62ca1d | ||
|
|
4e826ba61f | ||
|
|
b438c6f8ea | ||
|
|
bad9468ce1 | ||
|
|
9810756ee0 | ||
|
|
918a85d342 | ||
|
|
116c0e44a1 | ||
|
|
3c0ef04390 | ||
|
|
fd7b52cc64 | ||
|
|
d0d6fb27c4 | ||
|
|
b368db9e02 | ||
|
|
76189d9a28 | ||
|
|
2939751eb3 | ||
|
|
772bacb770 | ||
|
|
961477c791 | ||
|
|
6956784ac1 | ||
|
|
54c58ea6de | ||
|
|
a95a314f78 | ||
|
|
bc31ebd0c4 | ||
|
|
fbf27e7444 | ||
|
|
8b5ca3d110 | ||
|
|
06708b9dc8 | ||
|
|
772d5264d6 | ||
|
|
994de86121 | ||
|
|
906bdce6ce | ||
|
|
3bd65d2173 | ||
|
|
d5f34c4810 | ||
|
|
503b52652c | ||
|
|
b5030907eb | ||
|
|
8b0fdc82dc | ||
|
|
8d8d61b3c5 | ||
|
|
f86fd0cd14 | ||
|
|
12e43230c6 | ||
|
|
55c5b82638 | ||
|
|
9035c3497e | ||
|
|
5d35098bfc | ||
|
|
8249a288d7 | ||
|
|
45e218ceec | ||
|
|
86f6405574 | ||
|
|
99850aabca | ||
|
|
3c98854044 | ||
|
|
7b1b53054f | ||
|
|
a701c15d87 | ||
|
|
1b7fa46f8e | ||
|
|
58fb57bfa7 | ||
|
|
6af58fc25e | ||
|
|
e01763b8e5 | ||
|
|
cdb5c074d3 | ||
|
|
3f1e47dbcd | ||
|
|
d1c0710dec | ||
|
|
5b14456082 | ||
|
|
d1c18086d2 | ||
|
|
4ef10a424a | ||
|
|
23c31dd929 | ||
|
|
921e18988f | ||
|
|
7e30d189e9 | ||
|
|
8fd8454308 | ||
|
|
8e229f0db6 | ||
|
|
95ce19f846 | ||
|
|
9550ab3342 | ||
|
|
607e2f6c31 | ||
|
|
2d1081c296 | ||
|
|
0275098bdd | ||
|
|
0c9171a619 | ||
|
|
23eb9f4fe5 | ||
|
|
31662af342 | ||
|
|
8c3ff3f32c | ||
|
|
910d603c65 | ||
|
|
ad96e995af | ||
|
|
ed6586e25b | ||
|
|
acaecb4f94 | ||
|
|
53ac4d214f | ||
|
|
bff56aa46c | ||
|
|
ce30cd2a01 | ||
|
|
552f8d81b9 | ||
|
|
abd36de5ad | ||
|
|
b72a1aa3fe | ||
|
|
78069d4826 | ||
|
|
c543ccf07c | ||
|
|
88356c85c4 | ||
|
|
3dc061ac78 | ||
|
|
95124bf933 | ||
|
|
e7fb873ee2 | ||
|
|
629950e51b | ||
|
|
1ec8a7205f | ||
|
|
ce604e1629 | ||
|
|
c9e3fa6f70 | ||
|
|
f513a9193c | ||
|
|
21715210e2 | ||
|
|
f74c769a19 | ||
|
|
bb47236490 | ||
|
|
f5d1409c26 | ||
|
|
d0c3acbe3e | ||
|
|
c775104b9f | ||
|
|
8d9c800da0 | ||
|
|
cae91510dc | ||
|
|
26eef35f07 | ||
|
|
85041ff05b | ||
|
|
7eab5ad60f | ||
|
|
ae46e6ace9 | ||
|
|
444fd3b1cc | ||
|
|
e18be69104 | ||
|
|
4667bc554e | ||
|
|
d52cd8886c | ||
|
|
61b71320f7 | ||
|
|
b949343b78 | ||
|
|
f6111d49bb | ||
|
|
891d28a379 | ||
|
|
bb8d4b4d23 | ||
|
|
93c5307fd6 | ||
|
|
088b64ab3d | ||
|
|
ef8878fba5 | ||
|
|
f673c965ba | ||
|
|
a2c0c1479c | ||
|
|
20e1c8c571 | ||
|
|
40f7981395 | ||
|
|
156c9c4ec0 | ||
|
|
371ff9dd6f | ||
|
|
716c29881c | ||
|
|
f76f9c7d2a | ||
|
|
530c997638 | ||
|
|
b353028ea5 | ||
|
|
eb9c2429c6 | ||
|
|
1327208449 | ||
|
|
d99404388f | ||
|
|
3157f5f436 | ||
|
|
8d11359886 | ||
|
|
a4af41cb13 | ||
|
|
032fbf3f24 | ||
|
|
a7d859dab8 | ||
|
|
1751c3cc25 | ||
|
|
67ee050a0e | ||
|
|
562482c234 | ||
|
|
66d7fc34b2 | ||
|
|
81423cc817 | ||
|
|
7707724dc4 | ||
|
|
42d6270f28 | ||
|
|
19c9141473 | ||
|
|
c4dce3b5a7 | ||
|
|
443bd98041 | ||
|
|
419002a63b | ||
|
|
1566f0a997 | ||
|
|
8225b172b9 | ||
|
|
0f500eb336 | ||
|
|
675ac4ac4a | ||
|
|
79d5903b6c | ||
|
|
a2081171de | ||
|
|
c66930445f | ||
|
|
58724f8dcb | ||
|
|
e7e38fe80e | ||
|
|
0d3f0889c5 | ||
|
|
79e6b78669 | ||
|
|
5e79da9f32 | ||
|
|
bbe8180ad9 | ||
|
|
eabdef3b4d | ||
|
|
e279b0a1a2 | ||
|
|
de462761c9 | ||
|
|
17ff551275 | ||
|
|
e208cb46ae | ||
|
|
89c3355fd8 | ||
|
|
58101cbb73 | ||
|
|
512261b343 | ||
|
|
3db41817e0 | ||
|
|
8eeab1112a | ||
|
|
988bfffca2 | ||
|
|
8ff72d9517 | ||
|
|
4445e0a459 | ||
|
|
3ed1223678 | ||
|
|
d257a98cb8 | ||
|
|
f8002828ca | ||
|
|
26f53d38d9 | ||
|
|
f96085af38 | ||
|
|
e46cc2db8c | ||
|
|
c3b168e6fd | ||
|
|
62c1bcba71 | ||
|
|
057c7d0ffe | ||
|
|
1d3271999a | ||
|
|
409c610543 | ||
|
|
348266bd5b | ||
|
|
eb1f99c5f9 | ||
|
|
4eed0331bf | ||
|
|
66177aa5e0 | ||
|
|
ac0947c9e8 | ||
|
|
806cd392e7 | ||
|
|
9241d11dc5 | ||
|
|
31aadc8725 | ||
|
|
014ad1d747 | ||
|
|
1a77abfe64 | ||
|
|
667b29b77c | ||
|
|
7740470a94 | ||
|
|
eaf32621aa | ||
|
|
f318d6fffc | ||
|
|
177666cbc8 | ||
|
|
9456832a3b | ||
|
|
78e060f55a | ||
|
|
c53d4ecf32 | ||
|
|
6a165c41cb | ||
|
|
387c486e57 | ||
|
|
a624c439a4 | ||
|
|
fba9971555 | ||
|
|
310b2f1be4 | ||
|
|
1fed214490 | ||
|
|
f4c1e066ba | ||
|
|
4b7d46ced0 | ||
|
|
cabe4dfa72 | ||
|
|
5279571e41 | ||
|
|
9398c11b51 | ||
|
|
89c528e443 | ||
|
|
8f333138f5 | ||
|
|
35c4dbe688 | ||
|
|
c3200aa8fc | ||
|
|
6052aa499e | ||
|
|
2fe288d01d | ||
|
|
b6e23f974b | ||
|
|
174a15d07d | ||
|
|
5ab0eeb513 | ||
|
|
75e7018f72 | ||
|
|
8fe29f2784 | ||
|
|
dd6f92541d | ||
|
|
610cf729af | ||
|
|
96a4388c43 | ||
|
|
a86a8a236a | ||
|
|
f44a89ca77 | ||
|
|
a1a88b8ac7 | ||
|
|
df029f9660 | ||
|
|
b62829031d | ||
|
|
43c0a9293e | ||
|
|
4962b743d2 | ||
|
|
ea2fcb5b08 | ||
|
|
fd2ac4b4d5 | ||
|
|
7182e9a8ad | ||
|
|
3b1f29a5d6 | ||
|
|
707c04b4ab | ||
|
|
be05de6a3d | ||
|
|
889eb51fb5 | ||
|
|
e77188458f | ||
|
|
774cbbf879 | ||
|
|
c93093569e | ||
|
|
fb6f581157 | ||
|
|
e43d143ab0 | ||
|
|
a73c38112d | ||
|
|
e3444084fb | ||
|
|
d84eb14b3a | ||
|
|
fe814be287 | ||
|
|
6a0e155afe | ||
|
|
917eebcfac | ||
|
|
de288adb97 | ||
|
|
78ae77f307 | ||
|
|
b015c37922 | ||
|
|
ae7b208d32 | ||
|
|
9fe0c87e9a | ||
|
|
b32a9a201d | ||
|
|
fb980cf032 | ||
|
|
d3286af398 | ||
|
|
aed18a5ff3 | ||
|
|
307be48de9 | ||
|
|
a557a5b2c5 | ||
|
|
a6b0a74d95 | ||
|
|
393937b43f | ||
|
|
efe8bd8e92 | ||
|
|
74e3cad728 | ||
|
|
0010d0c45e | ||
|
|
8a749a7a8e | ||
|
|
964ed17716 | ||
|
|
50554ca270 | ||
|
|
c6f389b527 | ||
|
|
5780c94423 | ||
|
|
acef512730 | ||
|
|
fa9c74c6a2 | ||
|
|
b2ce2f8a34 | ||
|
|
5b91c3e0a0 | ||
|
|
1877736fa4 | ||
|
|
c096be3831 | ||
|
|
4888a118c3 | ||
|
|
e036b94a21 | ||
|
|
1a79f14e43 | ||
|
|
4e6d1ae0ea | ||
|
|
1858c3ed11 | ||
|
|
8e550fc11a | ||
|
|
1aee492c0f | ||
|
|
fdabf524f2 | ||
|
|
e565948ffd | ||
|
|
5c5a05212e | ||
|
|
b28ee6b039 | ||
|
|
6544bd2e65 | ||
|
|
f31411af17 | ||
|
|
479c6a68cf | ||
|
|
eb309be6f0 | ||
|
|
4139de3cc9 | ||
|
|
7514f5124a | ||
|
|
31e4583f4a | ||
|
|
17a089d21b | ||
|
|
db2f187493 | ||
|
|
d2e1cc4d48 | ||
|
|
0f7d294ac3 | ||
|
|
c66a4a9831 | ||
|
|
e57af8db0d | ||
|
|
0968cf8b00 | ||
|
|
0f9982c53e | ||
|
|
6d5812a86c | ||
|
|
1249594cf0 | ||
|
|
e04c5edaae | ||
|
|
66fe3001e4 | ||
|
|
7149557bb4 | ||
|
|
2abc0e17e7 | ||
|
|
197a401be6 | ||
|
|
4a208b8951 | ||
|
|
1e90f5c71c | ||
|
|
0d80c7bd59 | ||
|
|
4d06d2835c | ||
|
|
92c62352cf | ||
|
|
1f0404e3c5 | ||
|
|
ee88feb759 | ||
|
|
eb5e513d26 | ||
|
|
a539bd63fe | ||
|
|
1b7a003d84 | ||
|
|
0804f0a5dd | ||
|
|
7342c335d2 | ||
|
|
50855593ff | ||
|
|
9a0245b778 | ||
|
|
43d2a0e167 | ||
|
|
212aeee202 | ||
|
|
5fb95c5f94 | ||
|
|
05d6e6ca78 | ||
|
|
992656e753 | ||
|
|
ee86be9dca | ||
|
|
98e5555705 | ||
|
|
d3abebb601 | ||
|
|
645c5fabf2 | ||
|
|
7f7b6b08e8 | ||
|
|
72d7661b30 | ||
|
|
d0d106cef7 | ||
|
|
d603e94f68 | ||
|
|
9ff61601e3 | ||
|
|
09370a95db | ||
|
|
e9ffc53476 | ||
|
|
480a391929 | ||
|
|
154336ee27 | ||
|
|
d4ccb2e0e6 | ||
|
|
5e65af3a76 | ||
|
|
6efcfaa264 | ||
|
|
e4a0f841e1 | ||
|
|
4867a9b1e6 | ||
|
|
9a9eaa8100 | ||
|
|
339e29d5af | ||
|
|
b568999769 | ||
|
|
fe50883c15 | ||
|
|
d13ada1162 | ||
|
|
6ff093efbe | ||
|
|
c3835262d8 | ||
|
|
1a40af74da | ||
|
|
9e6e01cabb | ||
|
|
a561443fca | ||
|
|
e0a0430c31 | ||
|
|
49c3a1cda5 | ||
|
|
ba264c69c2 | ||
|
|
8e500c3670 | ||
|
|
bf4611c7b7 | ||
|
|
f773056750 | ||
|
|
b70500806a | ||
|
|
9b6b54cdaa | ||
|
|
37db6012a7 | ||
|
|
6f176dfc7c | ||
|
|
dee1d68dde | ||
|
|
123ae73efc | ||
|
|
2566992c9a | ||
|
|
5f35203d1b | ||
|
|
c23b73530f | ||
|
|
61dbb92679 | ||
|
|
e3d59a72f9 | ||
|
|
484a9b12bc | ||
|
|
ce81c4f89b | ||
|
|
ef8a4e5aaf | ||
|
|
1f86e8ae9a | ||
|
|
e7f6e90a22 | ||
|
|
20290a1cff | ||
|
|
80d329bb55 | ||
|
|
251a69ea3d | ||
|
|
31c0fe69f6 | ||
|
|
65f7bfcc8d | ||
|
|
4da241968c | ||
|
|
dd2b793c0c | ||
|
|
ef33befa06 | ||
|
|
2bddfb986d | ||
|
|
667045b492 | ||
|
|
f5209aa4e9 | ||
|
|
eb5d267e63 | ||
|
|
eaed517c0b | ||
|
|
ba628a28bc | ||
|
|
a1452db98a | ||
|
|
9b9a0f0bcb | ||
|
|
6b17067b15 | ||
|
|
055e940f06 | ||
|
|
3dd43d9cab | ||
|
|
6e710426a4 | ||
|
|
d11238f748 | ||
|
|
95c24bbaf8 | ||
|
|
1b0854fdca | ||
|
|
75d4ff7d51 | ||
|
|
952e805edb | ||
|
|
1fcd0b2578 | ||
|
|
619ee543b8 | ||
|
|
b6d8840915 | ||
|
|
d6e6feb377 | ||
|
|
919d69266e | ||
|
|
1e670f5e67 | ||
|
|
bf397fdd9f | ||
|
|
5153580698 | ||
|
|
3a69232213 | ||
|
|
2a6cb426ef | ||
|
|
2081c5e40e | ||
|
|
48cac9e3c8 | ||
|
|
537b8713e5 | ||
|
|
61cd180163 | ||
|
|
b69b1ad4fc | ||
|
|
bb652314be | ||
|
|
9b4052e5a3 | ||
|
|
58d27cf404 | ||
|
|
44168baaa7 | ||
|
|
c7b2d60a23 | ||
|
|
c58f7857bd | ||
|
|
e80fdbf3dc | ||
|
|
83be1aed76 | ||
|
|
c293d9049a | ||
|
|
f609e125e4 | ||
|
|
94ea13e73d | ||
|
|
240e1ef6fd | ||
|
|
1b8cb95f2e | ||
|
|
390a4fdc9d | ||
|
|
1034df577d | ||
|
|
869ce2f500 | ||
|
|
af03ff145d | ||
|
|
be7d70b15c | ||
|
|
b89e35bdd3 | ||
|
|
2ce3025be2 | ||
|
|
ff5742da9f | ||
|
|
5cb83dd5d7 | ||
|
|
b187139f64 | ||
|
|
9bbce7a231 | ||
|
|
21d6cb18ed | ||
|
|
09b4457bf2 | ||
|
|
b6917c782f | ||
|
|
08cd996839 | ||
|
|
8b9d4fd341 | ||
|
|
81ec3b5f81 | ||
|
|
8f47e62b36 | ||
|
|
e905d86fc5 | ||
|
|
c6f47b5bd7 | ||
|
|
70309bef3d | ||
|
|
2d051d8de3 | ||
|
|
578f54ee94 | ||
|
|
7d7bb5bf82 | ||
|
|
b1b52c37c7 | ||
|
|
af77912d2d | ||
|
|
9397bffd01 | ||
|
|
7f388b6553 | ||
|
|
e34af631c2 | ||
|
|
5a02cc00a4 | ||
|
|
886eb98e2a | ||
|
|
2cd338cf7e | ||
|
|
caa70df816 | ||
|
|
71de09d751 | ||
|
|
d3bd1d893b | ||
|
|
d2e6a4bf5e | ||
|
|
fe860131dd | ||
|
|
4a09679d74 | ||
|
|
331bbd602d | ||
|
|
9086d720e0 | ||
|
|
8fa64568f0 | ||
|
|
fdc144d215 | ||
|
|
ee70d496f4 | ||
|
|
0027a0a948 | ||
|
|
0c86cfeaed | ||
|
|
b69457a192 | ||
|
|
cf30c5d17f | ||
|
|
957b8f553c | ||
|
|
004ef3fad7 | ||
|
|
10d18820d2 | ||
|
|
6486c7809c | ||
|
|
37d7fd12e2 | ||
|
|
5f795d8382 | ||
|
|
00d3061e02 | ||
|
|
b3b115bcc4 | ||
|
|
f2c61f8840 | ||
|
|
12c6f9a412 | ||
|
|
a68f514a8a | ||
|
|
59c783df48 | ||
|
|
d4b15cd93a | ||
|
|
2908f1f963 | ||
|
|
dcb7ca3f79 | ||
|
|
c1feeaa57f | ||
|
|
6e520a721d | ||
|
|
8b80cf853b | ||
|
|
0f43c26525 | ||
|
|
2c14172467 | ||
|
|
320822d75b | ||
|
|
b362595665 | ||
|
|
2dc0fd2b50 | ||
|
|
48eda75c83 | ||
|
|
3951f331c0 | ||
|
|
2a7c715bc6 | ||
|
|
abca0ccf4a | ||
|
|
a1788a8398 | ||
|
|
2f338c0608 | ||
|
|
c87d88be4d | ||
|
|
ee5bf03767 | ||
|
|
983026ad8b | ||
|
|
3fd8f160c3 | ||
|
|
474f7f399c | ||
|
|
61173dce5d | ||
|
|
5b8f1327d8 | ||
|
|
dd04079098 | ||
|
|
f08ffc2715 | ||
|
|
2406c04d89 | ||
|
|
156d319604 | ||
|
|
5404d6baef | ||
|
|
291ef064a7 | ||
|
|
a0a6e24788 | ||
|
|
3650d59afe | ||
|
|
53757f9705 | ||
|
|
8ec0b378bc | ||
|
|
2557bc8e6f | ||
|
|
b83e3ae556 | ||
|
|
dff4f13c19 | ||
|
|
77f66cc5e1 | ||
|
|
86815edc31 | ||
|
|
45482d612c | ||
|
|
91013d452f | ||
|
|
c4061f003c | ||
|
|
59b017381c | ||
|
|
680ebef086 | ||
|
|
7ba6456c0b | ||
|
|
a52e55ec09 | ||
|
|
d1ed98f58b | ||
|
|
91c8a9314a | ||
|
|
f6bdb6afba | ||
|
|
559ef21563 | ||
|
|
64263bbb02 | ||
|
|
8af1501328 | ||
|
|
25aaeb4f40 | ||
|
|
36d913e1b1 | ||
|
|
250a99ff1b | ||
|
|
c329a0ec8e | ||
|
|
26a823082b | ||
|
|
80e73b6210 | ||
|
|
b359830ea2 | ||
|
|
c32d085710 | ||
|
|
a14339e752 | ||
|
|
cfbb848e03 | ||
|
|
12baca1295 | ||
|
|
4edc8fc3c7 | ||
|
|
e5501d4815 | ||
|
|
46e2b6e43d | ||
|
|
9aedb620c5 | ||
|
|
7494490d6d | ||
|
|
7066164591 | ||
|
|
0e2ff9b384 | ||
|
|
376419a4f7 | ||
|
|
05b479d349 | ||
|
|
52c18ef026 | ||
|
|
d478095756 | ||
|
|
adf4acf596 | ||
|
|
3f696664d6 | ||
|
|
e4c257fb01 | ||
|
|
593bfc86a1 | ||
|
|
b4bda14f3c | ||
|
|
f42dd61b8d | ||
|
|
b2405fccce | ||
|
|
3415dcef6f | ||
|
|
7048b94034 | ||
|
|
3c190f8927 | ||
|
|
d23e81b1f0 | ||
|
|
1ac99586a6 | ||
|
|
cfb4c9bb61 | ||
|
|
78ffc4f7fe | ||
|
|
1646717b4b | ||
|
|
67054fc380 | ||
|
|
4ebecc424e | ||
|
|
a860da8914 | ||
|
|
98c8a30764 | ||
|
|
ae40fc498b | ||
|
|
0082ecf1f3 | ||
|
|
7cddcce237 | ||
|
|
adb72b60b0 | ||
|
|
bc2157eea8 | ||
|
|
f3bf301825 | ||
|
|
85f4c3ebb4 | ||
|
|
853b99954e | ||
|
|
74dc65ab2e | ||
|
|
3eb82e0470 | ||
|
|
ad7ba08ac8 | ||
|
|
876e544433 | ||
|
|
b54722cc63 | ||
|
|
94e2a39d72 | ||
|
|
f6b9604f4a | ||
|
|
0374677814 | ||
|
|
3d54b1adf0 | ||
|
|
d4c23d881f | ||
|
|
1f26101f0e | ||
|
|
80c2e26741 | ||
|
|
707d449ba0 | ||
|
|
ba13127c04 | ||
|
|
20d3a979f1 | ||
|
|
2d1c985ff4 | ||
|
|
e4818cf732 | ||
|
|
a1b53b45ca | ||
|
|
09c7304bd9 | ||
|
|
58b2c72d53 | ||
|
|
627d6c154c | ||
|
|
4fbb53e817 | ||
|
|
ab78386e02 | ||
|
|
f5638e54f5 | ||
|
|
77efa1c620 | ||
|
|
a037cedfdc | ||
|
|
df78593b1b | ||
|
|
45e71aedf0 | ||
|
|
bbad6e1ae7 | ||
|
|
efb21c00ce | ||
|
|
071eb2478f | ||
|
|
770a4ee729 | ||
|
|
ccda62616d | ||
|
|
698d0dbda8 | ||
|
|
1af31a0523 | ||
|
|
a8153774b5 | ||
|
|
10e8ed7430 | ||
|
|
cde56a7eee | ||
|
|
8551ab3daf | ||
|
|
b0bee465aa | ||
|
|
7085066f08 | ||
|
|
e4dd9e1393 | ||
|
|
9c6a7522d7 | ||
|
|
01653a5f96 | ||
|
|
5acb7e3707 | ||
|
|
6c834dea7b | ||
|
|
b3c7864990 | ||
|
|
8984f24f7c | ||
|
|
294caf1ff1 | ||
|
|
033c7af292 | ||
|
|
15e5f57952 | ||
|
|
051faf4b64 | ||
|
|
2d94e02ea1 | ||
|
|
013ac11c95 | ||
|
|
dc2ed13a1c | ||
|
|
6e463c8084 | ||
|
|
3cd7cb81d4 | ||
|
|
d5e0f21798 | ||
|
|
4b11c2b552 | ||
|
|
201c5bfa5c | ||
|
|
34f302e1a5 | ||
|
|
722c196b08 | ||
|
|
c6ebb59a8b | ||
|
|
4808b930db | ||
|
|
c74295de88 | ||
|
|
a7209533a3 | ||
|
|
3d78e6078e | ||
|
|
e676278474 | ||
|
|
730a736ef0 | ||
|
|
a8320f20f7 | ||
|
|
1290039d7e | ||
|
|
f275ffbdfc | ||
|
|
36a6e269bf | ||
|
|
e7541faadc | ||
|
|
e8efc46e74 | ||
|
|
1b08a19e3e | ||
|
|
419128bfa1 | ||
|
|
2d256f48d0 | ||
|
|
380e05ad6e | ||
|
|
de4eb79c6a | ||
|
|
be47f91bc4 | ||
|
|
8030c17d63 | ||
|
|
9c8e66dc05 | ||
|
|
3ad389de55 | ||
|
|
66040506a7 | ||
|
|
d598f01cb7 | ||
|
|
1718dfa658 | ||
|
|
1c8208ad9a | ||
|
|
583be4a5f3 | ||
|
|
24507ddca8 | ||
|
|
3152bf572b | ||
|
|
96d4ba84c2 | ||
|
|
680924777b | ||
|
|
75c8a79d0e | ||
|
|
da1a527c90 | ||
|
|
bf962821b3 | ||
|
|
ce5678b819 | ||
|
|
d9cf6c6730 | ||
|
|
b386ccc786 | ||
|
|
0ed492978a | ||
|
|
a2c6257942 | ||
|
|
a14c9a057a | ||
|
|
c9838fea12 | ||
|
|
dfe18b40aa | ||
|
|
f099142004 | ||
|
|
d98ed28e7c | ||
|
|
beb9f3ab71 | ||
|
|
77c04d148e | ||
|
|
90c74701aa | ||
|
|
ede67df6bd | ||
|
|
27bf464dc3 | ||
|
|
fb02593bd4 | ||
|
|
c0dbd81b2b | ||
|
|
385454e602 | ||
|
|
7164e8eeb5 | ||
|
|
f9521ffa21 | ||
|
|
2048df8832 | ||
|
|
99f3321e26 | ||
|
|
235da6973d | ||
|
|
5c41fa6062 | ||
|
|
99a58aa2b8 | ||
|
|
4ae87ab40a | ||
|
|
7e62705877 | ||
|
|
1604f79623 | ||
|
|
265c415f5e | ||
|
|
2b318ba01b | ||
|
|
2f3adc3e24 | ||
|
|
57581ad733 | ||
|
|
b663a5b248 | ||
|
|
f6ffa28b27 | ||
|
|
170261328e | ||
|
|
5a6737a778 | ||
|
|
a2cedf4555 | ||
|
|
397897180b | ||
|
|
36cde567ab | ||
|
|
572d3329eb | ||
|
|
c0fe8dbfb4 | ||
|
|
f0f161e572 | ||
|
|
3a7085dee4 | ||
|
|
583094aa26 | ||
|
|
f4fb0e1617 | ||
|
|
6a8c0a6468 | ||
|
|
d14573620d | ||
|
|
9ea9806d67 | ||
|
|
7874f297b3 | ||
|
|
3541f01a72 | ||
|
|
eae21eed74 | ||
|
|
e62ab7e259 | ||
|
|
0270d4d5a1 | ||
|
|
7e9ed2acbf | ||
|
|
66d4734371 | ||
|
|
6cf574396a | ||
|
|
f0a9c10b6d | ||
|
|
78954a0d3e | ||
|
|
02412156d5 | ||
|
|
e70fef03c1 | ||
|
|
7e7eb69edf | ||
|
|
f0790a722d | ||
|
|
57815dbc3b | ||
|
|
5d76b5f655 | ||
|
|
84065e1d74 | ||
|
|
90bb7db48e | ||
|
|
e54aadf24a | ||
|
|
6bcaf01c3f | ||
|
|
e7f4d56592 | ||
|
|
8416a94ad2 | ||
|
|
ecc7355321 | ||
|
|
baf6715a7e | ||
|
|
f7c8e7ff70 | ||
|
|
6776703d8f | ||
|
|
25d1901d7a | ||
|
|
71493b2f9b | ||
|
|
86ad4988fe | ||
|
|
10975bd4c0 | ||
|
|
8d8f2d09cc | ||
|
|
9ce186860e | ||
|
|
4b2d3288d0 | ||
|
|
7b0200660e | ||
|
|
57a6ea11df | ||
|
|
89e8e0d277 | ||
|
|
d7c5cf6e5b | ||
|
|
a41e6804fc | ||
|
|
da1dc28d31 | ||
|
|
b42ca9bc5f | ||
|
|
42cb78f98e | ||
|
|
dc3a8ddb6b | ||
|
|
472060d333 | ||
|
|
5b80e10b82 | ||
|
|
7f8b0906c6 | ||
|
|
fa73d43818 | ||
|
|
5a86db2259 | ||
|
|
a5337b3495 | ||
|
|
cd379c69a0 | ||
|
|
156fd4e969 |
No files matched your search
@@ -2,7 +2,7 @@
|
|||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve QMK Firmware.
|
about: Create a report to help us improve QMK Firmware.
|
||||||
title: "[Bug] "
|
title: "[Bug] "
|
||||||
labels: bug, help wanted, discussion
|
labels: bug, help wanted
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
about: Suggest a new feature or changes to existing features.
|
about: Suggest a new feature or changes to existing features.
|
||||||
title: "[Feature Request] "
|
title: "[Feature Request] "
|
||||||
labels: enhancement, help wanted, discussion
|
labels: enhancement, help wanted
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: Other issues
|
name: Other issues
|
||||||
about: Anything else that doesn't fall into the above categories.
|
about: Anything else that doesn't fall into the above categories.
|
||||||
title: ''
|
title: ''
|
||||||
labels: help wanted, question, discussion
|
labels: help wanted, question
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
File renamed without changes.
+8
-2
@@ -17,6 +17,9 @@ pulls:
|
|||||||
This pull request has been automatically marked as stale because it has not had
|
This pull request has been automatically marked as stale because it has not had
|
||||||
activity in the last 45 days. It will be closed in 30 days if no further activity occurs.
|
activity in the last 45 days. It will be closed in 30 days if no further activity occurs.
|
||||||
Please feel free to give a status update now, or re-open when it's ready.
|
Please feel free to give a status update now, or re-open when it's ready.
|
||||||
|
|
||||||
|
For maintainers: Please label with `awaiting review`, `breaking_change`, `in progress`, or `on hold` to prevent
|
||||||
|
the issue from being re-flagged.
|
||||||
# Comment to post when closing a stale Issue or Pull Request.
|
# Comment to post when closing a stale Issue or Pull Request.
|
||||||
closeComment: >
|
closeComment: >
|
||||||
Thank you for your contribution!
|
Thank you for your contribution!
|
||||||
@@ -33,14 +36,17 @@ pulls:
|
|||||||
|
|
||||||
# Issue specific configuration
|
# Issue specific configuration
|
||||||
issues:
|
issues:
|
||||||
staleLabel: solved
|
staleLabel: stale
|
||||||
limitPerRun: 10
|
limitPerRun: 10
|
||||||
daysUntilStale: 90
|
daysUntilStale: 90
|
||||||
daysUntilClose: 30
|
daysUntilClose: 30
|
||||||
markComment: >
|
markComment: >
|
||||||
This issue has been automatically marked as resolved because it has not had activity in the
|
This issue has been automatically marked as stale because it has not had activity in the
|
||||||
last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity
|
last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity
|
||||||
occurs.
|
occurs.
|
||||||
|
|
||||||
|
For maintainers: Please label with `bug`, `in progress`, `on hold`, `discussion` or `to do` to prevent
|
||||||
|
the issue from being re-flagged.
|
||||||
closeComment: >
|
closeComment: >
|
||||||
This issue has been automatically closed because it has not had activity in the last 30 days.
|
This issue has been automatically closed because it has not had activity in the last 30 days.
|
||||||
If this issue is still valid, re-open the issue and let us know.
|
If this issue is still valid, re-open the issue and let us know.
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
name: CLI CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- future
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'lib/python/**'
|
||||||
|
- 'bin/qmk'
|
||||||
|
- 'requirements.txt'
|
||||||
|
- '.github/workflows/cli.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
container: qmkfm/base_container
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pip3 install -r requirements.txt
|
||||||
|
- name: Run tests
|
||||||
|
run: bin/qmk pytest
|
||||||
+3
-3
@@ -63,9 +63,6 @@ util/Win_Check_Output.txt
|
|||||||
*.gif
|
*.gif
|
||||||
*.jpg
|
*.jpg
|
||||||
|
|
||||||
# Do not ignore MiniDox left/right hand eeprom files
|
|
||||||
!keyboards/minidox/*.eep
|
|
||||||
|
|
||||||
# things travis sees
|
# things travis sees
|
||||||
secrets.tar
|
secrets.tar
|
||||||
id_rsa_*
|
id_rsa_*
|
||||||
@@ -73,3 +70,6 @@ id_rsa_*
|
|||||||
|
|
||||||
# python things
|
# python things
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
# prerequisites for updating ChibiOS
|
||||||
|
/util/fmpp*
|
||||||
+3
-1
@@ -1,13 +1,15 @@
|
|||||||
[submodule "lib/chibios"]
|
[submodule "lib/chibios"]
|
||||||
path = lib/chibios
|
path = lib/chibios
|
||||||
url = https://github.com/qmk/ChibiOS
|
url = https://github.com/qmk/ChibiOS
|
||||||
|
branch = master
|
||||||
[submodule "lib/chibios-contrib"]
|
[submodule "lib/chibios-contrib"]
|
||||||
path = lib/chibios-contrib
|
path = lib/chibios-contrib
|
||||||
url = https://github.com/qmk/ChibiOS-Contrib
|
url = https://github.com/qmk/ChibiOS-Contrib
|
||||||
branch = k-type-fix
|
branch = master
|
||||||
[submodule "lib/ugfx"]
|
[submodule "lib/ugfx"]
|
||||||
path = lib/ugfx
|
path = lib/ugfx
|
||||||
url = https://github.com/qmk/uGFX
|
url = https://github.com/qmk/uGFX
|
||||||
|
branch = master
|
||||||
[submodule "lib/googletest"]
|
[submodule "lib/googletest"]
|
||||||
path = lib/googletest
|
path = lib/googletest
|
||||||
url = https://github.com/google/googletest
|
url = https://github.com/google/googletest
|
||||||
|
|||||||
+12
-7
@@ -12,6 +12,18 @@ env:
|
|||||||
- MAKEFLAGS="-j3 --output-sync"
|
- MAKEFLAGS="-j3 --output-sync"
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-7
|
||||||
|
packages:
|
||||||
|
- pandoc
|
||||||
|
- diffutils
|
||||||
|
- dos2unix
|
||||||
|
- doxygen
|
||||||
|
- clang-format-7
|
||||||
|
- libstdc++-7-dev
|
||||||
install:
|
install:
|
||||||
- npm install -g moxygen
|
- npm install -g moxygen
|
||||||
script:
|
script:
|
||||||
@@ -20,13 +32,6 @@ script:
|
|||||||
- bash util/travis_test.sh
|
- bash util/travis_test.sh
|
||||||
- bash util/travis_build.sh
|
- bash util/travis_build.sh
|
||||||
- bash util/travis_docs.sh
|
- bash util/travis_docs.sh
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- pandoc
|
|
||||||
- diffutils
|
|
||||||
- dos2unix
|
|
||||||
- doxygen
|
|
||||||
after_script:
|
after_script:
|
||||||
bash util/travis_compiled_push.sh
|
bash util/travis_compiled_push.sh
|
||||||
notifications:
|
notifications:
|
||||||
|
|||||||
Vendored
+2
-1
@@ -5,7 +5,8 @@
|
|||||||
// Configure glob patterns for excluding files and folders.
|
// Configure glob patterns for excluding files and folders.
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.build": true,
|
"**/.build": true,
|
||||||
"**/*.hex": true
|
"**/*.hex": true,
|
||||||
|
"**/*.bin": true
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.h": "c",
|
"*.h": "c",
|
||||||
|
|||||||
@@ -623,13 +623,19 @@ endif
|
|||||||
# Generate the version.h file
|
# Generate the version.h file
|
||||||
ifndef SKIP_GIT
|
ifndef SKIP_GIT
|
||||||
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
|
GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
|
||||||
|
CHIBIOS_VERSION := $(shell cd lib/chibios && git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
|
||||||
|
CHIBIOS_CONTRIB_VERSION := $(shell cd lib/chibios-contrib && git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")
|
||||||
else
|
else
|
||||||
GIT_VERSION := NA
|
GIT_VERSION := NA
|
||||||
|
CHIBIOS_VERSION := NA
|
||||||
|
CHIBIOS_CONTRIB_VERSION := NA
|
||||||
endif
|
endif
|
||||||
ifndef SKIP_VERSION
|
ifndef SKIP_VERSION
|
||||||
BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S")
|
BUILD_DATE := $(shell date +"%Y-%m-%d-%H:%M:%S")
|
||||||
$(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(ROOT_DIR)/quantum/version.h)
|
$(shell echo '#define QMK_VERSION "$(GIT_VERSION)"' > $(ROOT_DIR)/quantum/version.h)
|
||||||
$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(ROOT_DIR)/quantum/version.h)
|
$(shell echo '#define QMK_BUILDDATE "$(BUILD_DATE)"' >> $(ROOT_DIR)/quantum/version.h)
|
||||||
|
$(shell echo '#define CHIBIOS_VERSION "$(CHIBIOS_VERSION)"' >> $(ROOT_DIR)/quantum/version.h)
|
||||||
|
$(shell echo '#define CHIBIOS_CONTRIB_VERSION "$(CHIBIOS_CONTRIB_VERSION)"' >> $(ROOT_DIR)/quantum/version.h)
|
||||||
else
|
else
|
||||||
BUILD_DATE := NA
|
BUILD_DATE := NA
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ with open(os.path.join(qmk_dir, 'requirements.txt'), 'r') as fd:
|
|||||||
line = line.split('#')[0]
|
line = line.split('#')[0]
|
||||||
|
|
||||||
module = line.split('=')[0] if '=' in line else line
|
module = line.split('=')[0] if '=' in line else line
|
||||||
|
|
||||||
|
if module in ['pep8-naming']:
|
||||||
|
# Not every module is importable by its own name.
|
||||||
|
continue
|
||||||
|
|
||||||
if not find_spec(module):
|
if not find_spec(module):
|
||||||
print('Could not find module %s!' % module)
|
print('Could not find module %s!' % module)
|
||||||
print('Please run `pip3 install -r requirements.txt` to install the python dependencies.')
|
print('Please run `pip3 install -r requirements.txt` to install the python dependencies.')
|
||||||
|
|||||||
@@ -82,6 +82,13 @@ ifeq ($(strip $(BOOTLOADER)), USBasp)
|
|||||||
OPT_DEFS += -DBOOTLOADER_USBASP
|
OPT_DEFS += -DBOOTLOADER_USBASP
|
||||||
BOOTLOADER_SIZE = 4096
|
BOOTLOADER_SIZE = 4096
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
|
||||||
|
# DO NOT USE THIS BOOTLOADER IN NEW PROJECTS!
|
||||||
|
# It is extremely prone to bricking, and is only included to support existing boards.
|
||||||
|
OPT_DEFS += -DBOOTLOADER_MS
|
||||||
|
BOOTLOADER_SIZE = 6144
|
||||||
|
FIRMWARE_FORMAT = bin
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef BOOTLOADER_SIZE
|
ifdef BOOTLOADER_SIZE
|
||||||
OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
|
OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
|
||||||
|
|||||||
+2
-2
@@ -22,5 +22,5 @@ else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Generate the keymap.c
|
# Generate the keymap.c
|
||||||
$(KEYBOARD_OUTPUT)/src/keymap.c:
|
$(KEYBOARD_OUTPUT)/src/keymap.c: $(KEYMAP_JSON)
|
||||||
bin/qmk json-keymap --quiet --output $(KEYMAP_C) $(KEYMAP_JSON)
|
bin/qmk json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON)
|
||||||
+154
-47
@@ -61,7 +61,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(strip $(STENO_ENABLE)), yes)
|
ifeq ($(strip $(STENO_ENABLE)), yes)
|
||||||
OPT_DEFS += -DSTENO_ENABLE
|
OPT_DEFS += -DSTENO_ENABLE
|
||||||
VIRTSER_ENABLE := yes
|
VIRTSER_ENABLE ?= yes
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -82,19 +82,19 @@ endif
|
|||||||
|
|
||||||
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
||||||
OPT_DEFS += -DUCIS_ENABLE
|
OPT_DEFS += -DUCIS_ENABLE
|
||||||
UNICODE_COMMON = yes
|
UNICODE_COMMON := yes
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_ucis.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
|
ifeq ($(strip $(UNICODEMAP_ENABLE)), yes)
|
||||||
OPT_DEFS += -DUNICODEMAP_ENABLE
|
OPT_DEFS += -DUNICODEMAP_ENABLE
|
||||||
UNICODE_COMMON = yes
|
UNICODE_COMMON := yes
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_unicodemap.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(UNICODE_ENABLE)), yes)
|
ifeq ($(strip $(UNICODE_ENABLE)), yes)
|
||||||
OPT_DEFS += -DUNICODE_ENABLE
|
OPT_DEFS += -DUNICODE_ENABLE
|
||||||
UNICODE_COMMON = yes
|
UNICODE_COMMON := yes
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -102,17 +102,72 @@ ifeq ($(strip $(UNICODE_COMMON)), yes)
|
|||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c
|
||||||
|
EEPROM_DRIVER ?= vendor
|
||||||
|
ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
|
||||||
|
$(error EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
|
||||||
|
else
|
||||||
|
OPT_DEFS += -DEEPROM_ENABLE
|
||||||
|
ifeq ($(strip $(EEPROM_DRIVER)), custom)
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
SRC += eeprom_driver.c
|
||||||
|
else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
QUANTUM_LIB_SRC += i2c_master.c
|
||||||
|
SRC += eeprom_driver.c eeprom_i2c.c
|
||||||
|
else ifeq ($(strip $(EEPROM_DRIVER)), transient)
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
SRC += eeprom_driver.c eeprom_transient.c
|
||||||
|
else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
|
||||||
|
OPT_DEFS += -DEEPROM_VENDOR
|
||||||
|
ifeq ($(PLATFORM),AVR)
|
||||||
|
# Automatically provided by avr-libc, nothing required
|
||||||
|
else ifeq ($(PLATFORM),CHIBIOS)
|
||||||
|
ifeq ($(MCU_SERIES), STM32F3xx)
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||||
|
OPT_DEFS += -DEEPROM_EMU_STM32F303xC
|
||||||
|
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||||
|
else ifeq ($(MCU_SERIES), STM32F1xx)
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||||
|
OPT_DEFS += -DEEPROM_EMU_STM32F103xB
|
||||||
|
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||||
|
else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F072xB)
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
|
||||||
|
OPT_DEFS += -DEEPROM_EMU_STM32F072xB
|
||||||
|
OPT_DEFS += -DSTM32_EEPROM_ENABLE
|
||||||
|
else ifneq ($(filter $(MCU_SERIES),STM32L0xx STM32L1xx),)
|
||||||
|
OPT_DEFS += -DEEPROM_DRIVER
|
||||||
|
COMMON_VPATH += $(DRIVER_PATH)/eeprom
|
||||||
|
SRC += eeprom_driver.c eeprom_stm32_L0_L1.c
|
||||||
|
else
|
||||||
|
# This will effectively work the same as "transient" if not supported by the chip
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
|
||||||
|
endif
|
||||||
|
else ifeq ($(PLATFORM),ARM_ATSAM)
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
||||||
|
else ifeq ($(PLATFORM),TEST)
|
||||||
|
SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
|
||||||
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight_post_config.h
|
POST_CONFIG_H += $(QUANTUM_DIR)/rgblight_post_config.h
|
||||||
OPT_DEFS += -DRGBLIGHT_ENABLE
|
OPT_DEFS += -DRGBLIGHT_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/color.c
|
SRC += $(QUANTUM_DIR)/color.c
|
||||||
SRC += $(QUANTUM_DIR)/rgblight.c
|
SRC += $(QUANTUM_DIR)/rgblight.c
|
||||||
CIE1931_CURVE = yes
|
CIE1931_CURVE := yes
|
||||||
LED_BREATHING_TABLE = yes
|
RGB_KEYCODES_ENABLE := yes
|
||||||
ifeq ($(strip $(RGBLIGHT_CUSTOM_DRIVER)), yes)
|
ifeq ($(strip $(RGBLIGHT_CUSTOM_DRIVER)), yes)
|
||||||
OPT_DEFS += -DRGBLIGHT_CUSTOM_DRIVER
|
OPT_DEFS += -DRGBLIGHT_CUSTOM_DRIVER
|
||||||
else
|
else
|
||||||
WS2812_DRIVER_REQUIRED = yes
|
WS2812_DRIVER_REQUIRED := yes
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -123,7 +178,9 @@ ifneq ($(strip $(LED_MATRIX_ENABLE)), no)
|
|||||||
ifeq ($(filter $(LED_MATRIX_ENABLE),$(VALID_MATRIX_TYPES)),)
|
ifeq ($(filter $(LED_MATRIX_ENABLE),$(VALID_MATRIX_TYPES)),)
|
||||||
$(error LED_MATRIX_ENABLE="$(LED_MATRIX_ENABLE)" is not a valid matrix type)
|
$(error LED_MATRIX_ENABLE="$(LED_MATRIX_ENABLE)" is not a valid matrix type)
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DLED_MATRIX_ENABLE -DBACKLIGHT_ENABLE -DBACKLIGHT_CUSTOM_DRIVER
|
BACKLIGHT_ENABLE = yes
|
||||||
|
BACKLIGHT_DRIVER = custom
|
||||||
|
OPT_DEFS += -DLED_MATRIX_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/led_matrix.c
|
SRC += $(QUANTUM_DIR)/led_matrix.c
|
||||||
SRC += $(QUANTUM_DIR)/led_matrix_drivers.c
|
SRC += $(QUANTUM_DIR)/led_matrix_drivers.c
|
||||||
endif
|
endif
|
||||||
@@ -146,11 +203,12 @@ endif
|
|||||||
SRC += $(QUANTUM_DIR)/color.c
|
SRC += $(QUANTUM_DIR)/color.c
|
||||||
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
SRC += $(QUANTUM_DIR)/rgb_matrix.c
|
||||||
SRC += $(QUANTUM_DIR)/rgb_matrix_drivers.c
|
SRC += $(QUANTUM_DIR)/rgb_matrix_drivers.c
|
||||||
CIE1931_CURVE = yes
|
CIE1931_CURVE := yes
|
||||||
|
RGB_KEYCODES_ENABLE := yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||||
RGB_MATRIX_ENABLE = IS31FL3731
|
RGB_MATRIX_ENABLE := IS31FL3731
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731)
|
ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731)
|
||||||
@@ -176,7 +234,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), WS2812)
|
ifeq ($(strip $(RGB_MATRIX_ENABLE)), WS2812)
|
||||||
OPT_DEFS += -DWS2812
|
OPT_DEFS += -DWS2812
|
||||||
WS2812_DRIVER_REQUIRED = yes
|
WS2812_DRIVER_REQUIRED := yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes)
|
ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes)
|
||||||
@@ -187,6 +245,10 @@ ifeq ($(strip $(RGB_MATRIX_CUSTOM_USER)), yes)
|
|||||||
OPT_DEFS += -DRGB_MATRIX_CUSTOM_USER
|
OPT_DEFS += -DRGB_MATRIX_CUSTOM_USER
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(RGB_KEYCODES_ENABLE)), yes)
|
||||||
|
SRC += $(QUANTUM_DIR)/process_keycode/process_rgb.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
|
||||||
OPT_DEFS += -DTAP_DANCE_ENABLE
|
OPT_DEFS += -DTAP_DANCE_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
|
||||||
@@ -226,41 +288,40 @@ endif
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(LCD_ENABLE)), yes)
|
ifeq ($(strip $(LCD_ENABLE)), yes)
|
||||||
CIE1931_CURVE = yes
|
CIE1931_CURVE := yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# backward compat
|
# backward compat
|
||||||
ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes)
|
ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes)
|
||||||
BACKLIGHT_ENABLE = custom
|
BACKLIGHT_DRIVER := custom
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VALID_BACKLIGHT_TYPES := yes software custom
|
VALID_BACKLIGHT_TYPES := pwm software custom
|
||||||
|
|
||||||
BACKLIGHT_ENABLE ?= no
|
BACKLIGHT_ENABLE ?= no
|
||||||
ifneq ($(strip $(BACKLIGHT_ENABLE)), no)
|
BACKLIGHT_DRIVER ?= pwm
|
||||||
ifeq ($(filter $(BACKLIGHT_ENABLE),$(VALID_BACKLIGHT_TYPES)),)
|
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
|
||||||
$(error BACKLIGHT_ENABLE="$(BACKLIGHT_ENABLE)" is not a valid backlight type)
|
ifeq ($(filter $(BACKLIGHT_DRIVER),$(VALID_BACKLIGHT_TYPES)),)
|
||||||
endif
|
$(error BACKLIGHT_DRIVER="$(BACKLIGHT_DRIVER)" is not a valid backlight type)
|
||||||
|
|
||||||
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
|
|
||||||
CIE1931_CURVE = yes
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
COMMON_VPATH += $(QUANTUM_DIR)/backlight
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight.c
|
SRC += $(QUANTUM_DIR)/backlight/backlight.c
|
||||||
|
SRC += $(QUANTUM_DIR)/process_keycode/process_backlight.c
|
||||||
OPT_DEFS += -DBACKLIGHT_ENABLE
|
OPT_DEFS += -DBACKLIGHT_ENABLE
|
||||||
|
|
||||||
ifeq ($(strip $(BACKLIGHT_ENABLE)), software)
|
ifeq ($(strip $(BACKLIGHT_DRIVER)), custom)
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight_soft.c
|
OPT_DEFS += -DBACKLIGHT_CUSTOM_DRIVER
|
||||||
else
|
else
|
||||||
ifeq ($(strip $(BACKLIGHT_ENABLE)), custom)
|
SRC += $(QUANTUM_DIR)/backlight/backlight_driver_common.c
|
||||||
OPT_DEFS += -DBACKLIGHT_CUSTOM_DRIVER
|
ifeq ($(strip $(BACKLIGHT_DRIVER)), pwm)
|
||||||
endif
|
ifeq ($(PLATFORM),AVR)
|
||||||
|
SRC += $(QUANTUM_DIR)/backlight/backlight_avr.c
|
||||||
ifeq ($(PLATFORM),AVR)
|
else
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight_avr.c
|
SRC += $(QUANTUM_DIR)/backlight/backlight_arm.c
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
SRC += $(QUANTUM_DIR)/backlight/backlight_arm.c
|
SRC += $(QUANTUM_DIR)/backlight/backlight_$(strip $(BACKLIGHT_DRIVER)).c
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -273,6 +334,8 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
|||||||
$(error WS2812_DRIVER="$(WS2812_DRIVER)" is not a valid WS2812 driver)
|
$(error WS2812_DRIVER="$(WS2812_DRIVER)" is not a valid WS2812 driver)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
OPT_DEFS += -DWS2812_DRIVER_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
|
||||||
|
|
||||||
ifeq ($(strip $(WS2812_DRIVER)), bitbang)
|
ifeq ($(strip $(WS2812_DRIVER)), bitbang)
|
||||||
SRC += ws2812.c
|
SRC += ws2812.c
|
||||||
else
|
else
|
||||||
@@ -285,14 +348,13 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(CIE1931_CURVE)), yes)
|
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
|
||||||
OPT_DEFS += -DUSE_CIE1931_CURVE
|
CIE1931_CURVE := yes
|
||||||
LED_TABLES = yes
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(LED_BREATHING_TABLE)), yes)
|
ifeq ($(strip $(CIE1931_CURVE)), yes)
|
||||||
OPT_DEFS += -DUSE_LED_BREATHING_TABLE
|
OPT_DEFS += -DUSE_CIE1931_CURVE
|
||||||
LED_TABLES = yes
|
LED_TABLES := yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(LED_TABLES)), yes)
|
ifeq ($(strip $(LED_TABLES)), yes)
|
||||||
@@ -342,6 +404,14 @@ ifeq ($(strip $(VELOCIKEY_ENABLE)), yes)
|
|||||||
SRC += $(QUANTUM_DIR)/velocikey.c
|
SRC += $(QUANTUM_DIR)/velocikey.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(VIA_ENABLE)), yes)
|
||||||
|
DYNAMIC_KEYMAP_ENABLE := yes
|
||||||
|
RAW_ENABLE := yes
|
||||||
|
BOOTMAGIC_ENABLE := lite
|
||||||
|
SRC += $(QUANTUM_DIR)/via.c
|
||||||
|
OPT_DEFS += -DVIA_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
|
ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
|
||||||
OPT_DEFS += -DDYNAMIC_KEYMAP_ENABLE
|
OPT_DEFS += -DDYNAMIC_KEYMAP_ENABLE
|
||||||
SRC += $(QUANTUM_DIR)/dynamic_keymap.c
|
SRC += $(QUANTUM_DIR)/dynamic_keymap.c
|
||||||
@@ -352,6 +422,12 @@ ifeq ($(strip $(LEADER_ENABLE)), yes)
|
|||||||
OPT_DEFS += -DLEADER_ENABLE
|
OPT_DEFS += -DLEADER_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes)
|
||||||
|
SRC += $(QUANTUM_DIR)/dip_switch.c
|
||||||
|
OPT_DEFS += -DDIP_SWITCH_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
include $(DRIVER_PATH)/qwiic/qwiic.mk
|
include $(DRIVER_PATH)/qwiic/qwiic.mk
|
||||||
|
|
||||||
QUANTUM_SRC:= \
|
QUANTUM_SRC:= \
|
||||||
@@ -359,12 +435,28 @@ QUANTUM_SRC:= \
|
|||||||
$(QUANTUM_DIR)/keymap_common.c \
|
$(QUANTUM_DIR)/keymap_common.c \
|
||||||
$(QUANTUM_DIR)/keycode_config.c
|
$(QUANTUM_DIR)/keycode_config.c
|
||||||
|
|
||||||
# Include the standard or split matrix code if needed
|
|
||||||
|
|
||||||
|
VALID_CUSTOM_MATRIX_TYPES:= yes lite no
|
||||||
|
|
||||||
|
CUSTOM_MATRIX ?= no
|
||||||
|
|
||||||
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
ifneq ($(strip $(CUSTOM_MATRIX)), yes)
|
||||||
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
ifeq ($(filter $(CUSTOM_MATRIX),$(VALID_CUSTOM_MATRIX_TYPES)),)
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/matrix.c
|
$(error CUSTOM_MATRIX="$(CUSTOM_MATRIX)" is not a valid custom matrix type)
|
||||||
else
|
endif
|
||||||
QUANTUM_SRC += $(QUANTUM_DIR)/matrix.c
|
|
||||||
|
# Include common stuff for all non custom matrix users
|
||||||
|
QUANTUM_SRC += $(QUANTUM_DIR)/matrix_common.c
|
||||||
|
|
||||||
|
# if 'lite' then skip the actual matrix implementation
|
||||||
|
ifneq ($(strip $(CUSTOM_MATRIX)), lite)
|
||||||
|
# Include the standard or split matrix code if needed
|
||||||
|
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
||||||
|
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/matrix.c
|
||||||
|
else
|
||||||
|
QUANTUM_SRC += $(QUANTUM_DIR)/matrix.c
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -387,9 +479,17 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
|||||||
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c
|
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c
|
||||||
# Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called.
|
# Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called.
|
||||||
# Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
|
# Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
|
||||||
QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/serial.c \
|
ifeq ($(PLATFORM),AVR)
|
||||||
i2c_master.c \
|
QUANTUM_LIB_SRC += i2c_master.c \
|
||||||
i2c_slave.c
|
i2c_slave.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
SERIAL_DRIVER ?= bitbang
|
||||||
|
ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
|
||||||
|
QUANTUM_LIB_SRC += serial.c
|
||||||
|
else
|
||||||
|
QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
COMMON_VPATH += $(QUANTUM_PATH)/split_common
|
COMMON_VPATH += $(QUANTUM_PATH)/split_common
|
||||||
endif
|
endif
|
||||||
@@ -407,9 +507,16 @@ ifeq ($(strip $(SPACE_CADET_ENABLE)), yes)
|
|||||||
OPT_DEFS += -DSPACE_CADET_ENABLE
|
OPT_DEFS += -DSPACE_CADET_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes)
|
MAGIC_ENABLE ?= yes
|
||||||
SRC += $(QUANTUM_DIR)/dip_switch.c
|
ifeq ($(strip $(MAGIC_ENABLE)), yes)
|
||||||
OPT_DEFS += -DDIP_SWITCH_ENABLE
|
SRC += $(QUANTUM_DIR)/process_keycode/process_magic.c
|
||||||
|
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
GRAVE_ESC_ENABLE ?= yes
|
||||||
|
ifeq ($(strip $(GRAVE_ESC_ENABLE)), yes)
|
||||||
|
SRC += $(QUANTUM_DIR)/process_keycode/process_grave_esc.c
|
||||||
|
OPT_DEFS += -DGRAVE_ESC_ENABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(DYNAMIC_MACRO_ENABLE)), yes)
|
ifeq ($(strip $(DYNAMIC_MACRO_ENABLE)), yes)
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# QMK Breaking Change - 2020 Feb 29 Changelog
|
||||||
|
|
||||||
|
Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps.
|
||||||
|
|
||||||
|
|
||||||
|
## Update ChibiOS/ChibiOS-Contrib/uGFX submodules
|
||||||
|
|
||||||
|
* General Notes
|
||||||
|
* A `make git-submodule` may be required after pulling the latest QMK firmware code to update affected submodules to the upgraded revisions
|
||||||
|
* Enabling link-time-optimization (`LINK_TIME_OPTIMIZATION_ENABLE = yes`) should work on a lot more boards
|
||||||
|
* Upgrade to ChibiOS ver19.1.3
|
||||||
|
* This will allow QMK to update to upstream ChibiOS a lot easier -- the old version was ~2 years out of date. Automated update scripts have been made available to simplify future upgrades.
|
||||||
|
* Includes improved MCU support and bugfixes
|
||||||
|
* ChibiOS revision is now included in Command output
|
||||||
|
* Timers should now be more accurate
|
||||||
|
* Upgrade to newer ChibiOS-Contrib
|
||||||
|
* Also includes improved MCU support and bugfixes
|
||||||
|
* ChibiOS-Contrib revision is now included in Command output
|
||||||
|
* Upgrade to newer uGFX
|
||||||
|
* Required in order to support updated ChibiOS
|
||||||
|
|
||||||
|
|
||||||
|
## Fix ChibiOS timer overflow for 16-bit SysTick devices
|
||||||
|
|
||||||
|
* On 16-bit SysTick devices, the timer subsystem in QMK was incorrectly dealing with overflow.
|
||||||
|
* When running at a 100000 SysTick frequency (possible on 16-bit devices, but uncommon), this overflow would occur after 0.65 seconds.
|
||||||
|
* Timers are now correctly handling this overflow case and timing should now be correct on ChibiOS/ARM.
|
||||||
|
|
||||||
|
|
||||||
|
## Update LUFA submodule
|
||||||
|
|
||||||
|
* Updates the LUFA submodule to include updates from upstream (abcminiuser/lufa)
|
||||||
|
* Includes some cleanup for QMK DFU generation
|
||||||
|
|
||||||
|
|
||||||
|
## Encoder flip
|
||||||
|
|
||||||
|
* Flips the encoder direction so that `clockwise == true` is for actually turning the knob clockwise
|
||||||
|
* Adds `ENCODER_DIRECTION_FLIP` define, so that reversing the expected dirction is simple for users.
|
||||||
|
* Cleans up documentation page for encoders
|
||||||
|
|
||||||
|
|
||||||
|
## Adding support for `BACKLIGHT_ON_STATE` for hardware PWM backlight
|
||||||
|
|
||||||
|
* Previously, the define only affected software PWM, and hardware PWM always assumed an N-channel MOSFET.
|
||||||
|
* The hardware PWM backlight setup has been updated to respect this option.
|
||||||
|
* The default "on" state has been changed to `1` - **this impacts all keyboards using software PWM backlight that do not define it explicitly**. If your keyboard's backlight is acting strange, it may have a P-channel MOSFET, and will need to have `#define BACKLIGHT_ON_STATE 0` added to the keyboard-level `config.h`. Please see the PR for more detailed information.
|
||||||
|
|
||||||
|
|
||||||
|
## Migrating `ACTION_LAYER_TAP_KEY()` entries in `fn_actions` to `LT()` keycodes
|
||||||
|
|
||||||
|
* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()`
|
||||||
|
* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity
|
||||||
|
* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features
|
||||||
|
|
||||||
|
|
||||||
|
## Moving backlight keycode handling to `process_keycode/`
|
||||||
|
|
||||||
|
* This refactors the backlight keycode logic to be clearer and more modular.
|
||||||
|
* All backlight-related keycodes are now actioned in a single file.
|
||||||
|
* The `ACTION_BACKLIGHT_*` macros have also been deleted. If you are still using these in a `fn_actions[]` block, please switch to using the backlight keycodes or functions directly.
|
||||||
|
|
||||||
|
|
||||||
|
## Refactor Planck keymaps to use Layout Macros
|
||||||
|
|
||||||
|
* Refactor Planck keymaps to use layout macros instead of raw matrix assignments
|
||||||
|
* Makes keymaps revision-agnostic
|
||||||
|
* Should reduce noise and errors in Travis CI logs
|
||||||
|
|
||||||
|
|
||||||
|
## GON NerD codebase refactor
|
||||||
|
|
||||||
|
* Splits the codebase for GON NerD 60 and NerdD TKL PCBs into two separate directories.
|
||||||
|
* If your keymap is for a NerD 60 PCB, your `make` command is now `make gon/nerd60:<keymap>`.
|
||||||
|
* If your keymap is for a NerD TKL PCB, your `make` command is now `make gon/nerdtkl:<keymap>`.
|
||||||
+22
-11
@@ -9,24 +9,35 @@
|
|||||||
|
|
||||||
## What is QMK Firmware?
|
## What is QMK Firmware?
|
||||||
|
|
||||||
QMK (*Quantum Mechanical Keyboard*) is an open source community that maintains QMK Firmware, QMK Toolbox, 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.
|
QMK (*Quantum Mechanical Keyboard*) is an open source community centered around developing computer input devices. The community encompasses all sorts of input devices, such as keyboards, mice, and MIDI devices. A core group of collaborators maintains [QMK Firmware](https://github.com/qmk/qmk_firmware), [QMK Configurator](https://config.qmk.fm), [QMK Toolbox](https://github.com/qmk/qmk_toolbox), [qmk.fm](https://qmk.fm), and this documentation with the help of community members like you.
|
||||||
|
|
||||||
## How to Get It
|
## Get Started
|
||||||
|
|
||||||
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.
|
Totally new to QMK? There are two ways to get started:
|
||||||
|
|
||||||
Otherwise, you can clone it directly with `git clone https://github.com/qmk/qmk_firmware`. Do not download the zip or tar files; a git repository is required to download the submodules in order to compile.
|
* Basic: [QMK Configurator](https://config.qmk.fm)
|
||||||
|
* Just select your keyboard from the dropdown and program your keyboard.
|
||||||
|
* We have an [introductory video](https://www.youtube.com/watch?v=-imgglzDMdY) you can watch.
|
||||||
|
* There is also an overview [document you can read](newbs_building_firmware_configurator.md).
|
||||||
|
* Advanced: [Use The Source](newbs.md)
|
||||||
|
* More powerful, but harder to use
|
||||||
|
|
||||||
## How to Compile
|
## Make It Yours
|
||||||
|
|
||||||
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:
|
QMK has lots of [features](features.md) to explore, and a good deal of reference documentation to dig through. Most features are taken advantage of by modifying your [keymap](keymap.md), and changing the [keycodes](keycodes.md).
|
||||||
|
|
||||||
make planck/rev4:default
|
## Need help?
|
||||||
|
|
||||||
This would build the `rev4` revision of the `planck` with the `default` keymap. Not all keyboards have revisions (also called subprojects or folders), in which case, it can be omitted:
|
Check out the [support page](support.md) to see how you can get help using QMK.
|
||||||
|
|
||||||
make preonic:default
|
## Give Back
|
||||||
|
|
||||||
## How to Customize
|
There are a lot of ways you can contribute to the QMK Community. The easiest way to get started is to use it and spread the word to your friends.
|
||||||
|
|
||||||
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).
|
* Help people out on our forums and chat rooms:
|
||||||
|
* [/r/olkb](https://www.reddit.com/r/olkb/)
|
||||||
|
* [Discord Server](https://discord.gg/Uq7gcHh)
|
||||||
|
* Contribute to our documentation by clicking "Edit This Page" at the bottom
|
||||||
|
* [Translate our documentation into your language](translating.md)
|
||||||
|
* [Report a bug](https://github.com/qmk/qmk_firmware/issues/new/choose)
|
||||||
|
* [Open a Pull Request](contributing.md)
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
- [:es: Español](/es/)
|
- [:es: Español](/es/)
|
||||||
- [:fr: Français](/fr-fr/)
|
- [:fr: Français](/fr-fr/)
|
||||||
- [:he: עברית](/he-il/)
|
- [:he: עברית](/he-il/)
|
||||||
|
- [:brazil: Português](/pt-br/)
|
||||||
- [:ru: Русский](/ru-ru/)
|
- [:ru: Русский](/ru-ru/)
|
||||||
- [:jp: 日本語](/ja/)
|
- [:jp: 日本語](/ja/)
|
||||||
+147
-110
@@ -1,123 +1,160 @@
|
|||||||
* [Complete Newbs Guide](newbs.md)
|
* Tutorial
|
||||||
* [Getting Started](newbs_getting_started.md)
|
* [Introduction](newbs.md)
|
||||||
|
* [Setup](newbs_getting_started.md)
|
||||||
* [Building Your First Firmware](newbs_building_firmware.md)
|
* [Building Your First Firmware](newbs_building_firmware.md)
|
||||||
* [Flashing Firmware](newbs_flashing.md)
|
* [Flashing Firmware](newbs_flashing.md)
|
||||||
* [Testing and Debugging](newbs_testing_debugging.md)
|
* [Testing and Debugging](newbs_testing_debugging.md)
|
||||||
* [Git Best Practices](newbs_best_practices.md)
|
* [Getting Help/Support](support.md)
|
||||||
* [Learning Resources](newbs_learn_more_resources.md)
|
* [Other Resources](newbs_learn_more_resources.md)
|
||||||
|
|
||||||
* [QMK Basics](README.md)
|
* FAQs
|
||||||
* [QMK Introduction](getting_started_introduction.md)
|
|
||||||
* [QMK CLI](cli.md)
|
|
||||||
* [QMK CLI Config](cli_configuration.md)
|
|
||||||
* [Contributing to QMK](contributing.md)
|
|
||||||
* [How to Use Github](getting_started_github.md)
|
|
||||||
* [Getting Help](getting_started_getting_help.md)
|
|
||||||
|
|
||||||
* [Breaking Changes](breaking_changes.md)
|
|
||||||
* [2019 Aug 30](ChangeLog/20190830.md)
|
|
||||||
|
|
||||||
* [FAQ](faq.md)
|
|
||||||
* [General FAQ](faq_general.md)
|
* [General FAQ](faq_general.md)
|
||||||
* [Build/Compile QMK](faq_build.md)
|
* [Build/Compile QMK](faq_build.md)
|
||||||
* [Debugging/Troubleshooting QMK](faq_debug.md)
|
* [Debugging/Troubleshooting QMK](faq_debug.md)
|
||||||
* [Keymap](faq_keymap.md)
|
* [Keymap FAQ](faq_keymap.md)
|
||||||
* [Driver Installation with Zadig](driver_installation_zadig.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)
|
|
||||||
* [Compatible Microcontrollers](compatible_microcontrollers.md)
|
|
||||||
* [AVR Processors](hardware_avr.md)
|
|
||||||
* [Drivers](hardware_drivers.md)
|
|
||||||
|
|
||||||
* Reference
|
|
||||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
|
||||||
* [Config Options](config_options.md)
|
|
||||||
* [Keycodes](keycodes.md)
|
|
||||||
* [Coding Conventions - C](coding_conventions_c.md)
|
|
||||||
* [Coding Conventions - Python](coding_conventions_python.md)
|
|
||||||
* [Documentation Best Practices](documentation_best_practices.md)
|
|
||||||
* [Documentation Templates](documentation_templates.md)
|
|
||||||
* [Glossary](reference_glossary.md)
|
* [Glossary](reference_glossary.md)
|
||||||
* [Unit Testing](unit_testing.md)
|
|
||||||
* [Useful Functions](ref_functions.md)
|
|
||||||
* [Configurator Support](reference_configurator_support.md)
|
|
||||||
* [info.json Format](reference_info_json.md)
|
|
||||||
* [Python CLI Development](cli_development.md)
|
|
||||||
|
|
||||||
* [Features](features.md)
|
* Configurator
|
||||||
* [Basic Keycodes](keycodes_basic.md)
|
* [Overview](newbs_building_firmware_configurator.md)
|
||||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
* [Step by Step](configurator_step_by_step.md)
|
||||||
* [Quantum Keycodes](quantum_keycodes.md)
|
* [Troubleshooting](configurator_troubleshooting.md)
|
||||||
* [Advanced Keycodes](feature_advanced_keycodes.md)
|
* QMK API
|
||||||
* [Audio](feature_audio.md)
|
* [Overview](api_overview.md)
|
||||||
* [Auto Shift](feature_auto_shift.md)
|
* [API Documentation](api_docs.md)
|
||||||
* [Backlight](feature_backlight.md)
|
* [Keyboard Support](reference_configurator_support.md)
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
|
||||||
* [Bootmagic](feature_bootmagic.md)
|
|
||||||
* [Combos](feature_combo.md)
|
|
||||||
* [Command](feature_command.md)
|
|
||||||
* [Debounce API](feature_debounce_type.md)
|
|
||||||
* [DIP Switch](feature_dip_switch.md)
|
|
||||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
|
||||||
* [Encoders](feature_encoders.md)
|
|
||||||
* [Grave Escape](feature_grave_esc.md)
|
|
||||||
* [Haptic Feedback](feature_haptic_feedback.md)
|
|
||||||
* [HD44780 LCD Controller](feature_hd44780.md)
|
|
||||||
* [Key Lock](feature_key_lock.md)
|
|
||||||
* [Layouts](feature_layouts.md)
|
|
||||||
* [Leader Key](feature_leader_key.md)
|
|
||||||
* [LED Matrix](feature_led_matrix.md)
|
|
||||||
* [Macros](feature_macros.md)
|
|
||||||
* [Mouse Keys](feature_mouse_keys.md)
|
|
||||||
* [OLED Driver](feature_oled_driver.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](feature_space_cadet.md)
|
|
||||||
* [Split Keyboard](feature_split_keyboard.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)
|
|
||||||
* [Velocikey](feature_velocikey.md)
|
|
||||||
|
|
||||||
* For Makers and Modders
|
* CLI
|
||||||
* [Hand Wiring Guide](hand_wire.md)
|
* [Overview](cli.md)
|
||||||
* [ISP Flashing Guide](isp_flashing_guide.md)
|
* [Configuration](cli_configuration.md)
|
||||||
* [ARM Debugging Guide](arm_debugging.md)
|
* [Commands](cli_commands.md)
|
||||||
* [I2C Driver](i2c_driver.md)
|
|
||||||
* [WS2812 Driver](ws2812_driver.md)
|
|
||||||
* [GPIO Controls](internals_gpio_control.md)
|
|
||||||
* [Proton C Conversion](proton_c_conversion.md)
|
|
||||||
|
|
||||||
* For a Deeper Understanding
|
* Using QMK
|
||||||
* [How Keyboards Work](how_keyboards_work.md)
|
* Guides
|
||||||
* [Understanding QMK](understanding_qmk.md)
|
* [Customizing Functionality](custom_quantum_functions.md)
|
||||||
|
* [Driver Installation with Zadig](driver_installation_zadig.md)
|
||||||
|
* [Keymap Overview](keymap.md)
|
||||||
|
* [Vagrant Guide](getting_started_vagrant.md)
|
||||||
|
* Flashing
|
||||||
|
* [Flashing](flashing.md)
|
||||||
|
* [Flashing ATmega32A (ps2avrgb)](flashing_bootloadhid.md)
|
||||||
|
* IDEs
|
||||||
|
* [Using Eclipse with QMK](other_eclipse.md)
|
||||||
|
* [Using VSCode with QMK](other_vscode.md)
|
||||||
|
* Git Best Practices
|
||||||
|
* [Introduction](newbs_git_best_practices.md)
|
||||||
|
* [Your Fork](newbs_git_using_your_master_branch.md)
|
||||||
|
* [Merge Conflicts](newbs_git_resolving_merge_conflicts.md)
|
||||||
|
* [Fixing Your Branch](newbs_git_resynchronize_a_branch.md)
|
||||||
|
* Keyboard Building
|
||||||
|
* [Hand Wiring Guide](hand_wire.md)
|
||||||
|
* [ISP Flashing Guide](isp_flashing_guide.md)
|
||||||
|
|
||||||
* Other Topics
|
* Simple Keycodes
|
||||||
* [Using Eclipse with QMK](other_eclipse.md)
|
* [Full List](keycodes.md)
|
||||||
* [Using VSCode with QMK](other_vscode.md)
|
* [Basic Keycodes](keycodes_basic.md)
|
||||||
* [Support](support.md)
|
* [Layer Switching](feature_advanced_keycodes.md)
|
||||||
* [How to add translations](translating.md)
|
* [Quantum Keycodes](quantum_keycodes.md)
|
||||||
|
|
||||||
* QMK Internals (In Progress)
|
* Advanced Keycodes
|
||||||
* [Defines](internals_defines.md)
|
* [Command](feature_command.md)
|
||||||
* [Input Callback Reg](internals_input_callback_reg.md)
|
* [Dynamic Macros](feature_dynamic_macros.md)
|
||||||
* [Midi Device](internals_midi_device.md)
|
* [Grave Escape](feature_grave_esc.md)
|
||||||
* [Midi Device Setup Process](internals_midi_device_setup_process.md)
|
* [Leader Key](feature_leader_key.md)
|
||||||
* [Midi Util](internals_midi_util.md)
|
* [Mod-Tap](mod_tap.md)
|
||||||
* [Send Functions](internals_send_functions.md)
|
* [Macros](feature_macros.md)
|
||||||
* [Sysex Tools](internals_sysex_tools.md)
|
* [Mouse Keys](feature_mouse_keys.md)
|
||||||
|
* [Space Cadet Shift](feature_space_cadet.md)
|
||||||
|
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
||||||
|
|
||||||
|
* Software Features
|
||||||
|
* [Auto Shift](feature_auto_shift.md)
|
||||||
|
* [Combos](feature_combo.md)
|
||||||
|
* [Debounce API](feature_debounce_type.md)
|
||||||
|
* [Key Lock](feature_key_lock.md)
|
||||||
|
* [One Shot Keys](one_shot_keys.md)
|
||||||
|
* [Pointing Device](feature_pointing_device.md)
|
||||||
|
* [Swap Hands](feature_swap_hands.md)
|
||||||
|
* [Tap Dance](feature_tap_dance.md)
|
||||||
|
* [Tap-Hold Configuration](tap_hold.md)
|
||||||
|
* [Terminal](feature_terminal.md)
|
||||||
|
* [Unicode](feature_unicode.md)
|
||||||
|
* [Userspace](feature_userspace.md)
|
||||||
|
|
||||||
|
* Hardware Features
|
||||||
|
* Displays
|
||||||
|
* [HD44780 LCD Controller](feature_hd44780.md)
|
||||||
|
* [OLED Driver](feature_oled_driver.md)
|
||||||
|
* Lighting
|
||||||
|
* [Backlight](feature_backlight.md)
|
||||||
|
* [LED Matrix](feature_led_matrix.md)
|
||||||
|
* [RGB Lighting](feature_rgblight.md)
|
||||||
|
* [RGB Matrix](feature_rgb_matrix.md)
|
||||||
|
* [Audio](feature_audio.md)
|
||||||
|
* [Bluetooth](feature_bluetooth.md)
|
||||||
|
* [Bootmagic](feature_bootmagic.md)
|
||||||
|
* [Custom Matrix](custom_matrix.md)
|
||||||
|
* [DIP Switch](feature_dip_switch.md)
|
||||||
|
* [Encoders](feature_encoders.md)
|
||||||
|
* [Haptic Feedback](feature_haptic_feedback.md)
|
||||||
|
* [Proton C Conversion](proton_c_conversion.md)
|
||||||
|
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||||
|
* [Split Keyboard](feature_split_keyboard.md)
|
||||||
|
* [Stenography](feature_stenography.md)
|
||||||
|
* [Thermal Printer](feature_thermal_printer.md)
|
||||||
|
* [Velocikey](feature_velocikey.md)
|
||||||
|
|
||||||
|
* Developing QMK
|
||||||
|
* Breaking Changes
|
||||||
|
* [Overview](breaking_changes.md)
|
||||||
|
* [My Pull Request Was Flagged](breaking_changes_instructions.md)
|
||||||
|
* History
|
||||||
|
* [2020 Feb 29](ChangeLog/20200229.md)
|
||||||
|
* [2019 Aug 30](ChangeLog/20190830.md)
|
||||||
|
|
||||||
|
* C Development
|
||||||
|
* [ARM Debugging Guide](arm_debugging.md)
|
||||||
|
* [AVR Processors](hardware_avr.md)
|
||||||
|
* [Coding Conventions](coding_conventions_c.md)
|
||||||
|
* [Compatible Microcontrollers](compatible_microcontrollers.md)
|
||||||
|
* [Drivers](hardware_drivers.md)
|
||||||
|
* [ADC Driver](adc_driver.md)
|
||||||
|
* [I2C Driver](i2c_driver.md)
|
||||||
|
* [WS2812 Driver](ws2812_driver.md)
|
||||||
|
* [EEPROM Driver](eeprom_driver.md)
|
||||||
|
* [GPIO Controls](internals_gpio_control.md)
|
||||||
|
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
||||||
|
|
||||||
|
* Python Development
|
||||||
|
* [Coding Conventions](coding_conventions_python.md)
|
||||||
|
* [QMK CLI Development](cli_development.md)
|
||||||
|
|
||||||
|
* Configurator Development
|
||||||
|
* QMK API
|
||||||
|
* [Development Environment](api_development_environment.md)
|
||||||
|
* [Architecture Overview](api_development_overview.md)
|
||||||
|
|
||||||
|
* QMK Reference
|
||||||
|
* [Contributing to QMK](contributing.md)
|
||||||
|
* [Translating the QMK Docs](translating.md)
|
||||||
|
* [Config Options](config_options.md)
|
||||||
|
* [Make Documentation](getting_started_make_guide.md)
|
||||||
|
* [Documentation Best Practices](documentation_best_practices.md)
|
||||||
|
* [Documentation Templates](documentation_templates.md)
|
||||||
|
* [Community Layouts](feature_layouts.md)
|
||||||
|
* [Unit Testing](unit_testing.md)
|
||||||
|
* [Useful Functions](ref_functions.md)
|
||||||
|
* [info.json Format](reference_info_json.md)
|
||||||
|
|
||||||
|
* For a Deeper Understanding
|
||||||
|
* [How Keyboards Work](how_keyboards_work.md)
|
||||||
|
* [How a Matrix Works](how_a_matrix_works.md)
|
||||||
|
* [Understanding QMK](understanding_qmk.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)
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
# ADC Driver
|
||||||
|
|
||||||
|
QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders.md).
|
||||||
|
|
||||||
|
This driver currently supports both AVR and a limited selection of ARM devices. On AVR devices, the values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V). On supported ARM devices, there is more flexibility in control of operation through `#define`s, but by default the values returned are 12-bit integers (0-4095) mapped between 0V and VCC (usually 3.3V).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To use this driver, add the following to your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
SRC += analog.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Then place this include at the top of your code:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "analog.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
### AVR
|
||||||
|
|
||||||
|
|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328P|
|
||||||
|
|-------|-------------|-------------|---------|----------|
|
||||||
|
|0 |`F0` |`F0` |`A0` |`C0` |
|
||||||
|
|1 |`F1` |`F1` |`A1` |`C1` |
|
||||||
|
|2 |`F2` | |`A2` |`C2` |
|
||||||
|
|3 |`F3` | |`A3` |`C3` |
|
||||||
|
|4 |`F4` |`F4` |`A4` |`C4` |
|
||||||
|
|5 |`F5` |`F5` |`A5` |`C5` |
|
||||||
|
|6 |`F6` |`F6` |`A6` |* |
|
||||||
|
|7 |`F7` |`F7` |`A7` |* |
|
||||||
|
|8 | |`D4` | | |
|
||||||
|
|9 | |`D6` | | |
|
||||||
|
|10 | |`D7` | | |
|
||||||
|
|11 | |`B4` | | |
|
||||||
|
|12 | |`B5` | | |
|
||||||
|
|13 | |`B6` | | |
|
||||||
|
|
||||||
|
<sup>\* The ATmega328P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these.</sup>
|
||||||
|
|
||||||
|
### ARM
|
||||||
|
|
||||||
|
Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC.
|
||||||
|
|
||||||
|
Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-based, whereas the F3 has 4 ADCs and the channels are 1 based. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation.
|
||||||
|
|
||||||
|
|ADC|Channel|STM32F0XX|STM32F3XX|
|
||||||
|
|---|-------|---------|---------|
|
||||||
|
|1 |0 |`A0` | |
|
||||||
|
|1 |1 |`A1` |`A0` |
|
||||||
|
|1 |2 |`A2` |`A1` |
|
||||||
|
|1 |3 |`A3` |`A2` |
|
||||||
|
|1 |4 |`A4` |`A3` |
|
||||||
|
|1 |5 |`A5` |`F4` |
|
||||||
|
|1 |6 |`A6` |`C0` |
|
||||||
|
|1 |7 |`A7` |`C1` |
|
||||||
|
|1 |8 |`B0` |`C2` |
|
||||||
|
|1 |9 |`B1` |`C3` |
|
||||||
|
|1 |10 |`C0` |`F2` |
|
||||||
|
|1 |11 |`C1` | |
|
||||||
|
|1 |12 |`C2` | |
|
||||||
|
|1 |13 |`C3` | |
|
||||||
|
|1 |14 |`C4` | |
|
||||||
|
|1 |15 |`C5` | |
|
||||||
|
|1 |16 | | |
|
||||||
|
|2 |1 | |`A4` |
|
||||||
|
|2 |2 | |`A5` |
|
||||||
|
|2 |3 | |`A6` |
|
||||||
|
|2 |4 | |`A7` |
|
||||||
|
|2 |5 | |`C4` |
|
||||||
|
|2 |6 | |`C0` |
|
||||||
|
|2 |7 | |`C1` |
|
||||||
|
|2 |8 | |`C2` |
|
||||||
|
|2 |9 | |`C3` |
|
||||||
|
|2 |10 | |`F2` |
|
||||||
|
|2 |11 | |`C5` |
|
||||||
|
|2 |12 | |`B2` |
|
||||||
|
|2 |13 | | |
|
||||||
|
|2 |14 | | |
|
||||||
|
|2 |15 | | |
|
||||||
|
|2 |16 | | |
|
||||||
|
|3 |1 | |`B1` |
|
||||||
|
|3 |2 | |`E9` |
|
||||||
|
|3 |3 | |`E13` |
|
||||||
|
|3 |4 | | |
|
||||||
|
|3 |5 | | |
|
||||||
|
|3 |6 | |`E8` |
|
||||||
|
|3 |7 | |`D10` |
|
||||||
|
|3 |8 | |`D11` |
|
||||||
|
|3 |9 | |`D12` |
|
||||||
|
|3 |10 | |`D13` |
|
||||||
|
|3 |11 | |`D14` |
|
||||||
|
|3 |12 | |`B0` |
|
||||||
|
|3 |13 | |`E7` |
|
||||||
|
|3 |14 | |`E10` |
|
||||||
|
|3 |15 | |`E11` |
|
||||||
|
|3 |16 | |`E12` |
|
||||||
|
|4 |1 | |`E14` |
|
||||||
|
|4 |2 | |`B12` |
|
||||||
|
|4 |3 | |`B13` |
|
||||||
|
|4 |4 | |`B14` |
|
||||||
|
|4 |5 | |`B15` |
|
||||||
|
|4 |6 | |`E8` |
|
||||||
|
|4 |7 | |`D10` |
|
||||||
|
|4 |8 | |`D11` |
|
||||||
|
|4 |9 | |`D12` |
|
||||||
|
|4 |10 | |`D13` |
|
||||||
|
|4 |11 | |`D14` |
|
||||||
|
|4 |12 | |`D8` |
|
||||||
|
|4 |13 | |`D9` |
|
||||||
|
|4 |14 | | |
|
||||||
|
|4 |15 | | |
|
||||||
|
|4 |16 | | |
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### AVR
|
||||||
|
|
||||||
|
|Function |Description |
|
||||||
|
|----------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||||
|
|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.|
|
||||||
|
|`analogRead(pin)` |Reads the value from the specified Arduino pin, eg. `4` for ADC6 on the ATmega32U4. |
|
||||||
|
|`analogReadPin(pin)` |Reads the value from the specified QMK pin, eg. `F6` for ADC6 on the ATmega32U4. |
|
||||||
|
|`pinToMux(pin)` |Translates a given QMK pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". |
|
||||||
|
|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. |
|
||||||
|
|
||||||
|
### ARM
|
||||||
|
|
||||||
|
Note that care was taken to match all of the functions used for AVR devices, however complications in the ARM platform prevent that from always being possible. For example, the `STM32` chips do not have assigned Arduino pins. We could use the default pin numbers, but those numbers change based on the package type of the device. For this reason, please specify your target pins with their identifiers (`A0`, `F3`, etc.). Also note that there are some variants of functions that accept the target ADC for the pin. Some pins can be used for multiple ADCs, and this specified can help you pick which ADC will be used to interact with that pin.
|
||||||
|
|
||||||
|
|Function |Description |
|
||||||
|
|----------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||||
|
|`analogReadPin(pin)` |Reads the value from the specified QMK pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.|
|
||||||
|
|`analogReadPinAdc(pin, adc)`|Reads the value from the specified QMK pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function.|
|
||||||
|
|`pinToMux(pin)` |Translates a given QMK pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)".|
|
||||||
|
|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and adc combination. See your MCU's datasheet for more information.|
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
## ARM
|
||||||
|
|
||||||
|
The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates.
|
||||||
|
|
||||||
|
|`#define` |Type |Default |Description|
|
||||||
|
|-------------------|------|---------------------|-----------|
|
||||||
|
|ADC_CIRCULAR_BUFFER|`bool`|`false` |If `TRUE`, then the implementation will use a circular buffer.|
|
||||||
|
|ADC_NUM_CHANNELS |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`.|
|
||||||
|
|ADC_BUFFER_DEPTH |`int` |`2` |Sets the depth of each result. Since we are only getting a 12-bit result by default, we set this to `2` bytes so we can contain our one value. This could be set to 1 if you opt for a 8-bit or lower result.|
|
||||||
|
|ADC_SAMPLING_RATE |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options.|
|
||||||
|
|ADC_RESOLUTION |`int` |`ADC_CFGR1_RES_12BIT`|The resolution of your result. We choose 12 bit by default, but you can opt for 12, 10, 8, or 6 bit. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options.|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Development Environment Setup
|
||||||
|
|
||||||
|
To setup a development stack head over to the [qmk_web_stack](https://github.com/qmk/qmk_web_stack).
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# QMK Compiler Development Guide
|
||||||
|
|
||||||
|
This page attempts to introduce developers to the QMK Compiler. It does not go into nitty gritty details- for that you should read code. What this will give you is a framework to hang your understanding on as you read the code.
|
||||||
|
|
||||||
|
# Overview
|
||||||
|
|
||||||
|
The QMK Compile API consists of a few movings parts:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
API Clients interact exclusively with the API service. This is where they submit jobs, check status, and download results. The API service inserts compile jobs into [Redis Queue](https://python-rq.org) and checks both RQ and S3 for the results of those jobs.
|
||||||
|
|
||||||
|
Workers fetch new compile jobs from RQ, compile them, and then upload the source and the binary to an S3 compatible storage engine.
|
||||||
|
|
||||||
|
# Workers
|
||||||
|
|
||||||
|
QMK Compiler Workers are responsible for doing the actual building. When a worker pulls a job from RQ it does several things to complete that job:
|
||||||
|
|
||||||
|
* Make a fresh qmk_firmware checkout
|
||||||
|
* Use the supplied layers and keyboard metadata to build a `keymap.c`
|
||||||
|
* Build the firmware
|
||||||
|
* Zip a copy of the source
|
||||||
|
* Upload the firmware, source zip, and a metadata file to S3.
|
||||||
|
* Report the status of the job to RQ
|
||||||
|
|
||||||
|
# API Service
|
||||||
|
|
||||||
|
The API service is a relatively simple Flask application. There are a few main views you should understand.
|
||||||
|
|
||||||
|
## @app.route('/v1/compile', methods=['POST'])
|
||||||
|
|
||||||
|
This is the main entrypoint for the API. A client's interaction starts here. The client POST's a JSON document describing their keyboard, and the API does some (very) basic validation of that JSON before submitting the compile job.
|
||||||
|
|
||||||
|
## @app.route('/v1/compile/<string:job_id>', methods=['GET'])
|
||||||
|
|
||||||
|
This is the most frequently called endpoint. It pulls the job details from redis, if they're still available, or the cached job details on S3 if they're not.
|
||||||
|
|
||||||
|
## @app.route('/v1/compile/<string:job_id>/download', methods=['GET'])
|
||||||
|
|
||||||
|
This method allows users to download the compiled firmware file.
|
||||||
|
|
||||||
|
## @app.route('/v1/compile/<string:job_id>/source', methods=['GET'])
|
||||||
|
|
||||||
|
This method allows users to download the source for their firmware.
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# QMK API
|
||||||
|
|
||||||
|
This page describes using the QMK API. If you are an application developer you can use this API to compile firmware for any [QMK](https://qmk.fm) Keyboard.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This service is an asynchronous API for compiling custom keymaps. You POST some JSON to the API, periodically check the status, and when your firmware has finished compiling you can download the resulting firmware and (if desired) source code for that firmware.
|
||||||
|
|
||||||
|
#### Example JSON Payload:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"keyboard": "clueboard/66/rev2",
|
||||||
|
"keymap": "my_awesome_keymap",
|
||||||
|
"layout": "LAYOUT_all",
|
||||||
|
"layers": [
|
||||||
|
["KC_GRV","KC_1","KC_2","KC_3","KC_4","KC_5","KC_6","KC_7","KC_8","KC_9","KC_0","KC_MINS","KC_EQL","KC_GRV","KC_BSPC","KC_PGUP","KC_TAB","KC_Q","KC_W","KC_E","KC_R","KC_T","KC_Y","KC_U","KC_I","KC_O","KC_P","KC_LBRC","KC_RBRC","KC_BSLS","KC_PGDN","KC_CAPS","KC_A","KC_S","KC_D","KC_F","KC_G","KC_H","KC_J","KC_K","KC_L","KC_SCLN","KC_QUOT","KC_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"],
|
||||||
|
["KC_ESC","KC_F1","KC_F2","KC_F3","KC_F4","KC_F5","KC_F6","KC_F7","KC_F8","KC_F9","KC_F10","KC_F11","KC_F12","KC_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SLCK","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"],
|
||||||
|
["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","RESET","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see the payload describes all aspects of a keyboard necessary to create and generate a firmware. Each layer is a single list of QMK keycodes the same length as the keyboard's `LAYOUT` macro. If a keyboard supports mulitple `LAYOUT` macros you can specify which macro to use.
|
||||||
|
|
||||||
|
## Submitting a Compile Job
|
||||||
|
|
||||||
|
To compile your keymap into a firmware simply POST your JSON to the `/v1/compile` endpoint. In the following example we've placed the JSON payload into a file named `json_data`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" http://api.qmk.fm/v1/compile
|
||||||
|
{
|
||||||
|
"enqueued": true,
|
||||||
|
"job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Checking The Status
|
||||||
|
|
||||||
|
After submitting your keymap you can check the status using a simple HTTP GET call:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl http://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6
|
||||||
|
{
|
||||||
|
"created_at": "Sat, 19 Aug 2017 21:39:12 GMT",
|
||||||
|
"enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT",
|
||||||
|
"id": "f5f9b992-73b4-479b-8236-df1deb37c163",
|
||||||
|
"status": "running",
|
||||||
|
"result": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This shows us that the job has made it through the queue and is currently running. There are 5 possible statuses:
|
||||||
|
|
||||||
|
* **failed**: Something about the compiling service has broken.
|
||||||
|
* **finished**: The compilation is complete and you should check `result` to see the results.
|
||||||
|
* **queued**: The keymap is waiting for a compilation server to become available.
|
||||||
|
* **running**: The compilation is in progress and should be complete soon.
|
||||||
|
* **unknown**: A serious error has occurred and you should [file a bug](https://github.com/qmk/qmk_compiler/issues).
|
||||||
|
|
||||||
|
## Examining Finished Results
|
||||||
|
|
||||||
|
Once your compile job has finished you'll check the `result` key. The value of this key is a hash containing several key bits of information:
|
||||||
|
|
||||||
|
* `firmware_binary_url`: A list of URLs for the the flashable firmware
|
||||||
|
* `firmware_keymap_url`: A list of URLs for the the `keymap.c`
|
||||||
|
* `firmware_source_url`: A list of URLs for the full firmware source code
|
||||||
|
* `output`: The stdout and stderr for this compile job. Errors will be found here.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# QMK API
|
||||||
|
|
||||||
|
The QMK API provides an asynchronous API that Web and GUI tools can use to compile arbitrary keymaps for any keyboard supported by [QMK](http://qmk.fm/). The stock keymap template supports all QMK keycodes that do not require supporting C code. Keyboard maintainers can supply their own custom templates to enable more functionality.
|
||||||
|
|
||||||
|
## App Developers
|
||||||
|
|
||||||
|
If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs.md).
|
||||||
|
|
||||||
|
## Keyboard Maintainers
|
||||||
|
|
||||||
|
If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support.md) section.
|
||||||
|
|
||||||
|
## Backend Developers
|
||||||
|
|
||||||
|
If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment.md), then check out [Hacking On The API](api_development_overview.md).
|
||||||
+11
-11
@@ -1,4 +1,4 @@
|
|||||||
# ARM Debugging usign Eclipse
|
# ARM Debugging using Eclipse
|
||||||
|
|
||||||
This page describes how to setup debugging for ARM MCUs using an SWD adapter and open-source/free tools. In this guide we will install GNU MCU Eclipse IDE for C/C++ Developers and OpenOCD together with all the necessary dependencies.
|
This page describes how to setup debugging for ARM MCUs using an SWD adapter and open-source/free tools. In this guide we will install GNU MCU Eclipse IDE for C/C++ Developers and OpenOCD together with all the necessary dependencies.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ XPM installation instructions can be found [here](https://www.npmjs.com/package/
|
|||||||
|
|
||||||
### The ARM Toolchain
|
### The ARM Toolchain
|
||||||
|
|
||||||
Using XPM it is very easy to install the ARM toolchain. Enter the command `xpm install --global @gnu-mcu-eclipse/arm-none-eabi-gcc`.
|
Using XPM it is very easy to install the ARM toolchain. Enter the command `xpm install --global @xpack-dev-tools/arm-none-eabi-gcc`.
|
||||||
|
|
||||||
### Windows build tools
|
### Windows build tools
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ If you have an ST-Link the drivers can be found [here](https://www.st.com/en/dev
|
|||||||
|
|
||||||
### OpenOCD
|
### OpenOCD
|
||||||
|
|
||||||
This dependency allows SWD access from GDB and it is essential for debugging. Run `xpm install --global @gnu-mcu-eclipse/openocd`.
|
This dependency allows SWD access from GDB and it is essential for debugging. Run `xpm install --global @xpack-dev-tools/openocd`.
|
||||||
|
|
||||||
### Java
|
### Java
|
||||||
|
|
||||||
@@ -45,17 +45,17 @@ Now its finally time to install the IDE. Use the Release page [here](https://git
|
|||||||
|
|
||||||
## Configuring Eclipse
|
## Configuring Eclipse
|
||||||
|
|
||||||
Open up the Eclipse IDE we just downloaded. To import our QMK directory select File -> Import -> C/C++ -> Existing code as Makefile Project. Select next and use Browse to select your QMK folder. In the tool-chain list select ARM Cross GCC and select Finish.
|
Open up the Eclipse IDE we just downloaded. To import our QMK directory select File -> Import -> C/C++ -> Existing Code as Makefile Project. Select Next and use Browse to select your QMK folder. In the tool-chain list select ARM Cross GCC and select Finish.
|
||||||
|
|
||||||
Now you can see the QMK folder on the left hand side. Right click it and select Properties. On the left hand side, expand MCU and select ARM Toolchain Paths. Press xPack and OK. Repeat for OpenOCD Path and if you are on windows for Build Tool Path. Select Apply and Close.
|
Now you can see the QMK folder on the left hand side. Right click it and select Properties. On the left hand side, expand MCU and select ARM Toolchains Paths. Press xPack and OK. Repeat for OpenOCD Path and if you are on Windows for Build Tools Path. Select Apply and Close.
|
||||||
|
|
||||||
Now its time to install the necessary MCU packages. Go to Packs perspective by selecting Window -> Open Perspective -> Others -> Packs. Now select the yellow refresh symbol next to the Packs tab. This will take a long time as it is requesting the MCU definitions from various places. If some of the links fail you can probably select Ignore.
|
Now its time to install the necessary MCU packages. Go to Packs perspective by selecting Window -> Perspective -> Open Perspective -> Other... -> Packs. Now select the yellow refresh symbol next to the Packs tab. This will take a long time as it is requesting the MCU definitions from various places. If some of the links fail you can probably select Ignore.
|
||||||
|
|
||||||
When this finishes you must find the MCU which we will be building/debugging for. In this example I will be using the STM32F3 series MCUs. On the left, select STMicroelectonics -> STM32F3 Series. On the middle window we can see the pack. Right click and select Install. Once that is done we can go back to the default perspective, Window -> Open Perspective -> Others -> C/C++.
|
When this finishes you must find the MCU which we will be building/debugging for. In this example I will be using the STM32F3 series MCUs. On the left, select STMicroelectronics -> STM32F3 Series. On the middle window we can see the pack. Right click and select Install. Once that is done we can go back to the default perspective, Window -> Perspective -> Open Perspective -> Other... -> C/C++.
|
||||||
|
|
||||||
We need to let eclipse know the device we intent to build QMK on. Right click on the QMK folder -> Properties -> C/C++ Build -> Settings. Select the Devices tab and under devices select the appropriate variant of your MCU. For my example it is STM32F303CC
|
We need to let eclipse know the device we intent to build QMK on. Right click on the QMK folder -> Properties -> C/C++ Build -> Settings. Select the Devices tab and under Devices select the appropriate variant of your MCU. For my example it is STM32F303CC
|
||||||
|
|
||||||
While we are here let's setup the build command as well. Select C/C++ Build and then the Behavior tab. On the build command, replace `all` with your necessary make command. For example for a rev6 Planck with the default keymap this would be `planck/rev6:default`. Select Apply and Close.
|
While we are here let's setup the build command as well. Select C/C++ Build and then the Behavior tab. On the Build command, replace `all` with your necessary make command. For example for a rev6 Planck with the default keymap this would be `planck/rev6:default`. Select Apply and Close.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ NOTE: Make sure the SWCLK and SWDIO pins are not used in the matrix of your keyb
|
|||||||
|
|
||||||
### Configuring the Debugger
|
### Configuring the Debugger
|
||||||
|
|
||||||
Right click on your QMK folder, select Debug As -> Debug Configuration. Here double click on GDB OpenOCD Debugging. Select the debugger tab and enter the configuration necessary for your MCU. This might take some fiddling and googleing to find out. The default script for the STM32F3 is called stm32f3discovery.cfg. To let OpenOCD know, in the Config options enter `-f board/stm32f3discovery.cfg`.
|
Right click on your QMK folder, select Debug As -> Debug Configurations... . Here double click on GDB OpenOCD Debugging. Select the Debugger tab and enter the configuration necessary for your MCU. This might take some fiddling and Googling to find out. The default script for the STM32F3 is called `stm32f3discovery.cfg`. To let OpenOCD know, in the Config options enter `-f board/stm32f3discovery.cfg`.
|
||||||
|
|
||||||
NOTE: In my case this configuration script requires editing to disable the reset assertion. The locations of the scripts can be found in the actual executable field usually under the path `openocd/version/.content/scripts/board`. Here I edited `reset_config srst_only` to `reset_config none`.
|
NOTE: In my case this configuration script requires editing to disable the reset assertion. The locations of the scripts can be found in the actual executable field usually under the path `openocd/version/.content/scripts/board`. Here I edited `reset_config srst_only` to `reset_config none`.
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ Select Apply and Close.
|
|||||||
|
|
||||||
Reset your keyboard.
|
Reset your keyboard.
|
||||||
|
|
||||||
Press the bug icon and if all goes well you should soon find yourself in the debug perspective. Here the program counter will pause at the beginning of the main function and way for you to press Play. Most of the features of all debuggers work on ARM MCUs but for exact details google is your friend!
|
Press the bug icon and if all goes well you should soon find yourself in the Debug perspective. Here the program counter will pause at the beginning of the main function and wait for you to press Play. Most of the features of all debuggers work on Arm MCUs but for exact details Google is your friend!
|
||||||
|
|
||||||
|
|
||||||
Happy debugging!
|
Happy debugging!
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# Becoming a QMK Collaborator
|
|
||||||
|
|
||||||
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!
|
|
||||||
@@ -6,20 +6,21 @@ The breaking change period is when we will merge PR's that change QMK in dangero
|
|||||||
|
|
||||||
## What has been included in past Breaking Changes?
|
## What has been included in past Breaking Changes?
|
||||||
|
|
||||||
|
* [2020 Feb 29](ChangeLog/20200229.md)
|
||||||
* [2019 Aug 30](ChangeLog/20190830.md)
|
* [2019 Aug 30](ChangeLog/20190830.md)
|
||||||
|
|
||||||
## When is the next Breaking Change?
|
## When is the next Breaking Change?
|
||||||
|
|
||||||
The next Breaking Change is scheduled for Nov 29.
|
The next Breaking Change is scheduled for May 30, 2020.
|
||||||
|
|
||||||
### Important Dates
|
### Important Dates
|
||||||
|
|
||||||
* [x] 2019 Sep 21 - `future` is created. It will be rebased weekly.
|
* [x] 2020 Feb 29 - `future` is created. It will be rebased weekly.
|
||||||
* [ ] 2019 Nov 01 - `future` closed to new PR's.
|
* [ ] 2020 May 2 - `future` closed to new PR's.
|
||||||
* [ ] 2019 Nov 01 - Call for testers.
|
* [ ] 2020 May 2 - Call for testers.
|
||||||
* [ ] 2019 Nov 27 - `master` is locked, no PR's merged.
|
* [ ] 2020 May 28 - `master` is locked, no PR's merged.
|
||||||
* [ ] 2019 Nov 29 - Merge `future` to `master`.
|
* [ ] 2020 May 30 - Merge `future` to `master`.
|
||||||
* [ ] 2019 Nov 30 - `master` is unlocked. PR's can be merged again.
|
* [ ] 2020 May 30 - `master` is unlocked. PR's can be merged again.
|
||||||
|
|
||||||
## What changes will be included?
|
## What changes will be included?
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Breaking Changes: My Pull Request Was Flagged
|
||||||
|
|
||||||
|
A QMK member may have replied to your pull request stating that your submission is a breaking change. In their judgment, the changes you have proposed have greater implications for either QMK, or its users.
|
||||||
|
|
||||||
|
Some things that may cause a pull request to be flagged are:
|
||||||
|
|
||||||
|
- **Edits to User Keymaps**
|
||||||
|
A user may submit their keymap to QMK, then some time later open a pull request with further updates, only to find it can't be merged because it was edited in the `qmk/qmk_firmware` repository. As not all users are proficient at using Git or GitHub, the user may find themself unable to fix the issue on their own.
|
||||||
|
- **Changes to Expected Behavior**
|
||||||
|
Changes to QMK behavior may cause users to believe their hardware or QMK is broken if they flash new firmware that incorporates changes to existing QMK features, and find themselves without a means to restore the desired behavior.
|
||||||
|
- **Changes Requiring User Action**
|
||||||
|
Changes may also require action to be taken by users, such as updating a toolchain or taking some action in Git.
|
||||||
|
- **Changes Necessitating Increased Scrutiny**
|
||||||
|
On occasion, a submission may have implications for QMK as a project. This could be copyright/licensing issues, coding conventions, large feature overhauls, "high-risk" changes that need wider testing by our community, or something else entirely.
|
||||||
|
- **Changes Requiring Communication to End Users**
|
||||||
|
This includes warnings about future deprecations, outdated practices, and anything else that needs to be communicated but doesn't fit into one of the above categories.
|
||||||
|
|
||||||
|
## What Do I Do?
|
||||||
|
|
||||||
|
If it is determined that your submission is a breaking change, there are a few things you can do to smooth the process:
|
||||||
|
|
||||||
|
### Consider Splitting Up Your PR
|
||||||
|
|
||||||
|
If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code.
|
||||||
|
|
||||||
|
### Contribute a ChangeLog Entry
|
||||||
|
|
||||||
|
We require submissions that go through the Breaking Change process to include a changelog entry. The entry should be a short summary of the changes your pull request makes – [each section here started as a changelog](ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft").
|
||||||
|
|
||||||
|
Your changelog should be located at `docs/ChangeLog/YYYYMMDD/PR####.md`, where `YYYYMMDD` is the date on which QMK's breaking change branch – usually named `future` – will be merged into the `master` branch, and `####` is the number of your pull request.
|
||||||
|
|
||||||
|
If your submission requires action on the part of users, your changelog should instruct users what action(s) must be taken, or link to a location that does so.
|
||||||
|
|
||||||
|
### Document Your Changes
|
||||||
|
|
||||||
|
Understanding the purpose for your submission, and possible implications or actions it will require can make the review process more straightforward. A changelog may suffice for this purpose, but more extensive changes may require a level of detail that is ill-suited for a changelog.
|
||||||
|
|
||||||
|
Commenting on your pull request and being responsive to questions, comments, and change requests is much appreciated.
|
||||||
|
|
||||||
|
### Ask for Help
|
||||||
|
|
||||||
|
Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/Uq7gcHh).
|
||||||
+7
-190
@@ -1,24 +1,14 @@
|
|||||||
# QMK CLI
|
# QMK CLI :id=qmk-cli
|
||||||
|
|
||||||
This page describes how to setup and use the QMK CLI.
|
## Overview :id=overview
|
||||||
|
|
||||||
# Overview
|
|
||||||
|
|
||||||
The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
|
The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more.
|
||||||
|
|
||||||
* [Global CLI](#global-cli)
|
### Requirements :id=requirements
|
||||||
* [Local CLI](#local-cli)
|
|
||||||
* [CLI Commands](#cli-commands)
|
|
||||||
|
|
||||||
# Requirements
|
The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI.
|
||||||
|
|
||||||
The CLI requires Python 3.5 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt).
|
### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew
|
||||||
|
|
||||||
# Global CLI
|
|
||||||
|
|
||||||
QMK provides an installable CLI that can be used to setup your QMK build environment, work with QMK, and which makes working with multiple copies of `qmk_firmware` easier. We recommend installing and updating this periodically.
|
|
||||||
|
|
||||||
## Install Using Homebrew (macOS, some Linux)
|
|
||||||
|
|
||||||
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
|
If you have installed [Homebrew](https://brew.sh) you can tap and install QMK:
|
||||||
|
|
||||||
@@ -29,7 +19,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
|
|||||||
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
||||||
```
|
```
|
||||||
|
|
||||||
## Install Using easy_install or pip
|
### Install Using easy_install or pip :id=install-using-easy_install-or-pip
|
||||||
|
|
||||||
If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command:
|
If your system is not listed above you can install QMK manually. First ensure that you have python 3.5 (or later) installed and have installed pip. Then install QMK with this command:
|
||||||
|
|
||||||
@@ -39,7 +29,7 @@ export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware`
|
|||||||
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment
|
||||||
```
|
```
|
||||||
|
|
||||||
## Packaging For Other Operating Systems
|
### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems
|
||||||
|
|
||||||
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
|
We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines:
|
||||||
|
|
||||||
@@ -47,176 +37,3 @@ We are looking for people to create and maintain a `qmk` package for more operat
|
|||||||
* Document why in a comment when you do deviate
|
* Document why in a comment when you do deviate
|
||||||
* Install using a virtualenv
|
* Install using a virtualenv
|
||||||
* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`.
|
* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`.
|
||||||
|
|
||||||
# Local CLI
|
|
||||||
|
|
||||||
If you do not want to use the global CLI there is a local CLI bundled with `qmk_firmware`. You can find it in `qmk_firmware/bin/qmk`. You can run the `qmk` command from any directory and it will always operate on that copy of `qmk_firmware`.
|
|
||||||
|
|
||||||
**Example**:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ~/qmk_firmware/bin/qmk hello
|
|
||||||
Ψ Hello, World!
|
|
||||||
```
|
|
||||||
|
|
||||||
## Local CLI Limitations
|
|
||||||
|
|
||||||
There are some limitations to the local CLI compared to the global CLI:
|
|
||||||
|
|
||||||
* The local CLI does not support `qmk setup` or `qmk clone`
|
|
||||||
* The local CLI always operates on the same `qmk_firmware` tree, even if you have multiple repositories cloned.
|
|
||||||
* The local CLI does not run in a virtualenv, so it's possible that dependencies will conflict
|
|
||||||
|
|
||||||
# CLI Commands
|
|
||||||
|
|
||||||
## `qmk cformat`
|
|
||||||
|
|
||||||
This command formats C code using clang-format. Run it with no arguments to format all core code, or pass filenames on the command line to run it on specific files.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk cformat [file1] [file2] [...] [fileN]
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk compile`
|
|
||||||
|
|
||||||
This command allows you to compile firmware from any directory. You can compile JSON exports from <https://config.qmk.fm> or compile keymaps in the repo.
|
|
||||||
|
|
||||||
**Usage for Configurator Exports**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk compile <configuratorExport.json>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage for Keymaps**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk compile -kb <keyboard_name> -km <keymap_name>
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk flash`
|
|
||||||
|
|
||||||
This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default.
|
|
||||||
To specify a different bootloader, use `-bl <bootloader>`. Visit <https://docs.qmk.fm/#/flashing>
|
|
||||||
for more details of the available bootloaders.
|
|
||||||
|
|
||||||
**Usage for Configurator Exports**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk flash <configuratorExport.json> -bl <bootloader>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Usage for Keymaps**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk flash -kb <keyboard_name> -km <keymap_name> -bl <bootloader>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Listing the Bootloaders**
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk flash -b
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk config`
|
|
||||||
|
|
||||||
This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk docs`
|
|
||||||
|
|
||||||
This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk docs [-p PORT]
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk doctor`
|
|
||||||
|
|
||||||
This command examines your environment and alerts you to potential build or flash problems.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk doctor
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk json-keymap`
|
|
||||||
|
|
||||||
Creates a keymap.c from a QMK Configurator export.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk json-keymap [-o OUTPUT] filename
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk kle2json`
|
|
||||||
|
|
||||||
This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk kle2json [-f] <filename>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Examples**:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qmk kle2json kle.txt
|
|
||||||
☒ File info.json already exists, use -f or --force to overwrite.
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qmk kle2json -f kle.txt -f
|
|
||||||
Ψ Wrote out to info.json
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk list-keyboards`
|
|
||||||
|
|
||||||
This command lists all the keyboards currently defined in `qmk_firmware`
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk list-keyboards
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk new-keymap`
|
|
||||||
|
|
||||||
This command creates a new keymap based on a keyboard's existing default keymap.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk pyformat`
|
|
||||||
|
|
||||||
This command formats python code in `qmk_firmware`.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk pyformat
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qmk pytest`
|
|
||||||
|
|
||||||
This command runs the python test suite. If you make changes to python code you should ensure this runs successfully.
|
|
||||||
|
|
||||||
**Usage**:
|
|
||||||
|
|
||||||
```
|
|
||||||
qmk pytest
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
# QMK CLI Commands
|
||||||
|
|
||||||
|
# CLI Commands
|
||||||
|
|
||||||
|
## `qmk cformat`
|
||||||
|
|
||||||
|
This command formats C code using clang-format.
|
||||||
|
|
||||||
|
Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b <branch_name>`
|
||||||
|
|
||||||
|
Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files.
|
||||||
|
|
||||||
|
**Usage for specified files**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk cformat [file1] [file2] [...] [fileN]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for all core files**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk cformat -a
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for only changed files against origin/master**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk cformat
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for only changed files against branch_name**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk cformat -b branch_name
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk compile`
|
||||||
|
|
||||||
|
This command allows you to compile firmware from any directory. You can compile JSON exports from <https://config.qmk.fm>, compile keymaps in the repo, or compile the keyboard in the current working directory.
|
||||||
|
|
||||||
|
**Usage for Configurator Exports**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk compile <configuratorExport.json>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for Keymaps**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk compile -kb <keyboard_name> -km <keymap_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage in Keyboard Directory**:
|
||||||
|
|
||||||
|
Must be in keyboard directory with a default keymap, or in keymap directory for keyboard, or supply one with `--keymap <keymap_name>`
|
||||||
|
```
|
||||||
|
qmk compile
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for building all keyboards that support a specific keymap**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk compile -kb all -km <keymap_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```
|
||||||
|
$ qmk config compile.keymap=default
|
||||||
|
$ cd ~/qmk_firmware/keyboards/planck/rev6
|
||||||
|
$ qmk compile
|
||||||
|
Ψ Compiling keymap with make planck/rev6:default
|
||||||
|
...
|
||||||
|
```
|
||||||
|
or with optional keymap argument
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4
|
||||||
|
$ qmk compile -km 66_iso
|
||||||
|
Ψ Compiling keymap with make clueboard/66/rev4:66_iso
|
||||||
|
...
|
||||||
|
```
|
||||||
|
or in keymap directory
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
|
||||||
|
$ qmk compile
|
||||||
|
Ψ Compiling keymap with make make gh60/satan:colemak
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage in Layout Directory**:
|
||||||
|
|
||||||
|
Must be under `qmk_firmware/layouts/`, and in a keymap folder.
|
||||||
|
```
|
||||||
|
qmk compile -kb <keyboard_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**:
|
||||||
|
```
|
||||||
|
$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi
|
||||||
|
$ qmk compile -kb dz60
|
||||||
|
Ψ Compiling keymap with make dz60:mechmerlin-ansi
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk flash`
|
||||||
|
|
||||||
|
This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default.
|
||||||
|
To specify a different bootloader, use `-bl <bootloader>`. Visit the [Flashing Firmware](flashing.md) guide for more details of the available bootloaders.
|
||||||
|
|
||||||
|
**Usage for Configurator Exports**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk flash <configuratorExport.json> -bl <bootloader>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage for Keymaps**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk flash -kb <keyboard_name> -km <keymap_name> -bl <bootloader>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Listing the Bootloaders**
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk flash -b
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk config`
|
||||||
|
|
||||||
|
This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md).
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk docs`
|
||||||
|
|
||||||
|
This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk docs [-p PORT]
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk doctor`
|
||||||
|
|
||||||
|
This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk doctor [-y] [-n]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**:
|
||||||
|
|
||||||
|
Check your environment for problems and prompt to fix them:
|
||||||
|
|
||||||
|
qmk doctor
|
||||||
|
|
||||||
|
Check your environment and automatically fix any problems found:
|
||||||
|
|
||||||
|
qmk doctor -y
|
||||||
|
|
||||||
|
Check your environment and report problems only:
|
||||||
|
|
||||||
|
qmk doctor -n
|
||||||
|
|
||||||
|
## `qmk json2c`
|
||||||
|
|
||||||
|
Creates a keymap.c from a QMK Configurator export.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk json2c [-o OUTPUT] filename
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk kle2json`
|
||||||
|
|
||||||
|
This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk kle2json [-f] <filename>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk kle2json kle.txt
|
||||||
|
☒ File info.json already exists, use -f or --force to overwrite.
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ qmk kle2json -f kle.txt -f
|
||||||
|
Ψ Wrote out to info.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk list-keyboards`
|
||||||
|
|
||||||
|
This command lists all the keyboards currently defined in `qmk_firmware`
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk list-keyboards
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk list-keymaps`
|
||||||
|
|
||||||
|
This command lists all the keymaps for a specified keyboard (and revision).
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk list-keymaps -kb planck/ez
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk new-keymap`
|
||||||
|
|
||||||
|
This command creates a new keymap based on a keyboard's existing default keymap.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk pyformat`
|
||||||
|
|
||||||
|
This command formats python code in `qmk_firmware`.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk pyformat
|
||||||
|
```
|
||||||
|
|
||||||
|
## `qmk pytest`
|
||||||
|
|
||||||
|
This command runs the python test suite. If you make changes to python code you should ensure this runs successfully.
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
qmk pytest
|
||||||
|
```
|
||||||
@@ -4,7 +4,7 @@ This document explains how `qmk config` works.
|
|||||||
|
|
||||||
# Introduction
|
# Introduction
|
||||||
|
|
||||||
Configuration for QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set.
|
Configuration for the QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set.
|
||||||
|
|
||||||
## Simple Example
|
## Simple Example
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Most of our style is pretty easy to pick up on, but right now it's not entirely
|
|||||||
* Think of them as a story describing the feature
|
* Think of them as a story describing the feature
|
||||||
* Use them liberally to explain why particular decisions were made.
|
* Use them liberally to explain why particular decisions were made.
|
||||||
* Do not write obvious comments
|
* Do not write obvious comments
|
||||||
* If you not sure if a comment is obvious, go ahead and include it.
|
* If you're 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.
|
* 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`)
|
* 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`)
|
||||||
* We accept both forms of preprocessor if's: `#ifdef DEFINED` and `#if defined(DEFINED)`
|
* We accept both forms of preprocessor if's: `#ifdef DEFINED` and `#if defined(DEFINED)`
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Most of our style follows PEP8 with some local modifications to make things less
|
|||||||
* Think of them as a story describing the feature
|
* Think of them as a story describing the feature
|
||||||
* Use them liberally to explain why particular decisions were made.
|
* Use them liberally to explain why particular decisions were made.
|
||||||
* Do not write obvious comments
|
* Do not write obvious comments
|
||||||
* If you not sure if a comment is obvious, go ahead and include it.
|
* If you're not sure if a comment is obvious, go ahead and include it.
|
||||||
* We require useful docstrings for all functions.
|
* We require useful docstrings for all functions.
|
||||||
* 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.
|
* 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.
|
||||||
* Some of our practices conflict with the wider python community to make our codebase more approachable to non-pythonistas.
|
* Some of our practices conflict with the wider python community to make our codebase more approachable to non-pythonistas.
|
||||||
@@ -309,6 +309,18 @@ FIXME(username): Revisit this code when the frob feature is done.
|
|||||||
|
|
||||||
...where username is your GitHub username.
|
...where username is your GitHub username.
|
||||||
|
|
||||||
# Unit Tests
|
# Testing
|
||||||
|
|
||||||
These are good. We should have some one day.
|
We use a combination of Integration and Unit testing to ensure that the our code is as bug-free as possible. All the tests can be found in `lib/python/qmk/tests/`. You can run all the tests with `qmk pytest`.
|
||||||
|
|
||||||
|
At the time of this writing our tests are not very comprehensive. Looking at the current tests and writing new test cases for untested situations is a great way to both familiarize yourself with the codebase and contribute to QMK.
|
||||||
|
|
||||||
|
## Integration Tests
|
||||||
|
|
||||||
|
Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.5/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened.
|
||||||
|
|
||||||
|
## Unit Tests
|
||||||
|
|
||||||
|
The other `test_*.py` files in `lib/python/qmk/tests/` contain unit tests. You can write tests for individual functions inside `lib/python/qmk/` here. Generally these files are named after the module, with dots replaced by underscores.
|
||||||
|
|
||||||
|
At the time of this writing we do not do any mocking for our tests. If you would like to help us change this please [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and start a conversation there.
|
||||||
+39
-10
@@ -53,6 +53,8 @@ This is a C header file that is one of the first things included, and will persi
|
|||||||
* pins of the rows, from top to bottom
|
* pins of the rows, from top to bottom
|
||||||
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
|
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
|
||||||
* pins of the columns, from left to right
|
* pins of the columns, from left to right
|
||||||
|
* `#define MATRIX_IO_DELAY 30`
|
||||||
|
* the delay in microseconds when between changing matrix pin state and reading values
|
||||||
* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }`
|
* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }`
|
||||||
* pins unused by the keyboard for reference
|
* pins unused by the keyboard for reference
|
||||||
* `#define MATRIX_HAS_GHOST`
|
* `#define MATRIX_HAS_GHOST`
|
||||||
@@ -78,7 +80,7 @@ This is a C header file that is one of the first things included, and will persi
|
|||||||
* `#define BACKLIGHT_PIN B7`
|
* `#define BACKLIGHT_PIN B7`
|
||||||
* pin of the backlight
|
* pin of the backlight
|
||||||
* `#define BACKLIGHT_LEVELS 3`
|
* `#define BACKLIGHT_LEVELS 3`
|
||||||
* number of levels your backlight will have (maximum 15 excluding off)
|
* number of levels your backlight will have (maximum 31 excluding off)
|
||||||
* `#define BACKLIGHT_BREATHING`
|
* `#define BACKLIGHT_BREATHING`
|
||||||
* enables backlight breathing
|
* enables backlight breathing
|
||||||
* `#define BREATHING_PERIOD 6`
|
* `#define BREATHING_PERIOD 6`
|
||||||
@@ -134,19 +136,25 @@ If you define these options you will enable the associated feature, which may in
|
|||||||
* enables handling for per key `TAPPING_TERM` settings
|
* enables handling for per key `TAPPING_TERM` settings
|
||||||
* `#define RETRO_TAPPING`
|
* `#define RETRO_TAPPING`
|
||||||
* tap anyway, even after TAPPING_TERM, if there was no other key interruption between press and release
|
* tap anyway, even after TAPPING_TERM, if there was no other key interruption between press and release
|
||||||
* See [Retro Tapping](feature_advanced_keycodes.md#retro-tapping) for details
|
* See [Retro Tapping](tap_hold.md#retro-tapping) for details
|
||||||
* `#define TAPPING_TOGGLE 2`
|
* `#define TAPPING_TOGGLE 2`
|
||||||
* how many taps before triggering the toggle
|
* how many taps before triggering the toggle
|
||||||
* `#define PERMISSIVE_HOLD`
|
* `#define PERMISSIVE_HOLD`
|
||||||
* makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM`
|
* 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
|
* See [Permissive Hold](tap_hold.md#permissive-hold) for details
|
||||||
|
* `#define PERMISSIVE_HOLD_PER_KEY`
|
||||||
|
* enabled handling for per key `PERMISSIVE_HOLD` settings
|
||||||
* `#define IGNORE_MOD_TAP_INTERRUPT`
|
* `#define IGNORE_MOD_TAP_INTERRUPT`
|
||||||
* 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.
|
* 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
|
* See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details
|
||||||
|
* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
|
||||||
|
* enables handling for per key `IGNORE_MOD_TAP_INTERRUPT` settings
|
||||||
* `#define TAPPING_FORCE_HOLD`
|
* `#define TAPPING_FORCE_HOLD`
|
||||||
* makes it possible to use a dual role key as modifier shortly after having been tapped
|
* makes it possible to use a dual role key as modifier shortly after having been tapped
|
||||||
* See [Hold after tap](feature_advanced_keycodes.md#tapping-force-hold)
|
* See [Tapping Force Hold](tap_hold.md#tapping-force-hold)
|
||||||
* Breaks any Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
|
* Breaks any Tap Toggle functionality (`TT` or the One Shot Tap Toggle)
|
||||||
|
* `#define TAPPING_FORCE_HOLD_PER_KEY`
|
||||||
|
* enables handling for per key `TAPPING_FORCE_HOLD` settings
|
||||||
* `#define LEADER_TIMEOUT 300`
|
* `#define LEADER_TIMEOUT 300`
|
||||||
* how long before the leader key times out
|
* how long before the leader key times out
|
||||||
* If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped.
|
* If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped.
|
||||||
@@ -182,6 +190,8 @@ If you define these options you will enable the associated feature, which may in
|
|||||||
* pin the DI on the WS2812 is hooked-up to
|
* pin the DI on the WS2812 is hooked-up to
|
||||||
* `#define RGBLIGHT_ANIMATIONS`
|
* `#define RGBLIGHT_ANIMATIONS`
|
||||||
* run RGB animations
|
* run RGB animations
|
||||||
|
* `#define RGBLIGHT_LAYERS`
|
||||||
|
* Lets you define [lighting layers](feature_rgblight.md) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
||||||
* `#define RGBLED_NUM 12`
|
* `#define RGBLED_NUM 12`
|
||||||
* number of LEDs
|
* number of LEDs
|
||||||
* `#define RGBLIGHT_SPLIT`
|
* `#define RGBLIGHT_SPLIT`
|
||||||
@@ -272,9 +282,12 @@ There are a few different ways to set handedness for split keyboards (listed in
|
|||||||
* Default behavior for ARM
|
* Default behavior for ARM
|
||||||
* Required for AVR Teensy
|
* Required for AVR Teensy
|
||||||
|
|
||||||
* `#define SPLIT_USB_TIMEOUT 2500`
|
* `#define SPLIT_USB_TIMEOUT 2000`
|
||||||
* Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
|
* Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
|
||||||
|
|
||||||
|
* `#define SPLIT_USB_TIMEOUT_POLL 10`
|
||||||
|
* Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT`
|
||||||
|
|
||||||
# The `rules.mk` File
|
# 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.
|
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.
|
||||||
@@ -287,8 +300,27 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
|||||||
* Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building.
|
* Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building.
|
||||||
* `SRC`
|
* `SRC`
|
||||||
* Used to add files to the compilation/linking list.
|
* Used to add files to the compilation/linking list.
|
||||||
|
* `LIB_SRC`
|
||||||
|
* Used to add files as a library to the compilation/linking list.
|
||||||
|
The files specified by `LIB_SRC` is linked after the files specified by `SRC`.
|
||||||
|
For example, if you specify:
|
||||||
|
```
|
||||||
|
SRC += a.c
|
||||||
|
LIB_SRC += lib_b.c
|
||||||
|
SRC += c.c
|
||||||
|
LIB_SRC += lib_d.c
|
||||||
|
```
|
||||||
|
The link order is as follows.
|
||||||
|
```
|
||||||
|
... a.o c.o ... lib_b.a lib_d.a ...
|
||||||
|
```
|
||||||
* `LAYOUTS`
|
* `LAYOUTS`
|
||||||
* A list of [layouts](feature_layouts.md) this keyboard supports.
|
* A list of [layouts](feature_layouts.md) this keyboard supports.
|
||||||
|
* `LINK_TIME_OPTIMIZATION_ENABLE`
|
||||||
|
* Enables Link Time Optimization (`LTO`) when compiling the keyboard. This makes the process take longer, but can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). However, this will automatically disable the old Macros and Functions features automatically, as these break when `LTO` is enabled.
|
||||||
|
It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`
|
||||||
|
* `LTO_ENABLE`
|
||||||
|
* It has the same meaning as LINK_TIME_OPTIMIZATION_ENABLE. You can use `LTO_ENABLE` instead of `LINK_TIME_OPTIMIZATION_ENABLE`.
|
||||||
|
|
||||||
## AVR MCU Options
|
## AVR MCU Options
|
||||||
* `MCU = atmega32u4`
|
* `MCU = atmega32u4`
|
||||||
@@ -305,7 +337,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
|
|||||||
* `bootloadHID`
|
* `bootloadHID`
|
||||||
* `USBasp`
|
* `USBasp`
|
||||||
|
|
||||||
## Feature Options
|
## Feature Options :id=feature-options
|
||||||
|
|
||||||
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
|
Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU.
|
||||||
|
|
||||||
@@ -347,9 +379,6 @@ Use these to enable or disable building certain features. The more you have enab
|
|||||||
* Forces the keyboard to wait for a USB connection to be established before it starts up
|
* Forces the keyboard to wait for a USB connection to be established before it starts up
|
||||||
* `NO_USB_STARTUP_CHECK`
|
* `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.
|
* 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.
|
||||||
* `LINK_TIME_OPTIMIZATION_ENABLE`
|
|
||||||
* Enables Link Time Optimization (`LTO`) when compiling the keyboard. This makes the process take longer, but can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). However, this will automatically disable the old Macros and Functions features automatically, as these break when `LTO` is enabled. It does this by automatically defining `NO_ACTION_MACRO` and `NO_ACTION_FUNCTION`
|
|
||||||
* Alternatively, you can use `LTO_ENABLE` instead of `LINK_TIME_OPTIMIZATION_ENABLE`.
|
|
||||||
|
|
||||||
## USB Endpoint Limitations
|
## USB Endpoint Limitations
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# QMK Configurator: Step by Step
|
||||||
|
|
||||||
|
This page describes the steps for building your firmware in QMK Configurator.
|
||||||
|
|
||||||
|
## Step 1: Select Your Keyboard
|
||||||
|
|
||||||
|
Click the drop down box and select the keyboard you want to create a keymap for.
|
||||||
|
|
||||||
|
?> If your keyboard has several versions, make sure you select the correct one.
|
||||||
|
|
||||||
|
I'll say that again because it's important:
|
||||||
|
|
||||||
|
!> **MAKE SURE YOU SELECT THE RIGHT VERSION!**
|
||||||
|
|
||||||
|
If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own github accounts. Double check for that as well. <!-- FIXME(skullydazed): This feels too wordy and I'm not sure we want to encourage these kinds of issues. Also, should we prompt them to bug the manufacutrer? -->
|
||||||
|
|
||||||
|
## Step 2: Select Your Keyboard Layout
|
||||||
|
|
||||||
|
Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future.
|
||||||
|
|
||||||
|
!> Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`.
|
||||||
|
|
||||||
|
## Step 3: Name Your Keymap
|
||||||
|
|
||||||
|
Call this keymap what you want.
|
||||||
|
|
||||||
|
?> If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo.
|
||||||
|
|
||||||
|
## Step 4: Define Your Keymap
|
||||||
|
|
||||||
|
Keycode Entry is accomplished in one of 3 ways:
|
||||||
|
|
||||||
|
1. Drag and drop
|
||||||
|
2. Clicking on an empty spot on the layout, then clicking the keycode you desire
|
||||||
|
3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard
|
||||||
|
|
||||||
|
?> Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see:
|
||||||
|
|
||||||
|
* [Basic Keycode Reference](keycodes_basic.md)
|
||||||
|
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
|
||||||
|
|
||||||
|
!> If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations.
|
||||||
|
|
||||||
|
## Step 5: Save Your Keymap for Future Changes
|
||||||
|
|
||||||
|
When you're satisfied with your keymap or just want to work on it later, press the `Export Keymap` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Import Keymap` button.
|
||||||
|
|
||||||
|
!> **CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems.
|
||||||
|
|
||||||
|
## Step 6: Compile Your Firmware File
|
||||||
|
|
||||||
|
Press the green `Compile` button.
|
||||||
|
|
||||||
|
When the compilation is done, you will be able to press the green `Download Firmware` button.
|
||||||
|
|
||||||
|
## Next steps: Flashing Your Keyboard
|
||||||
|
|
||||||
|
Please refer to [Flashing Firmware](newbs_flashing.md).
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# Configurator Troubleshooting
|
||||||
|
|
||||||
|
## My .json file is not working
|
||||||
|
|
||||||
|
If the .json file was generated with QMK Configurator, congratulations you have stumbled upon a bug. File an issue at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues).
|
||||||
|
|
||||||
|
If not... how did you miss the big bold message at the top saying not to use other .json files?
|
||||||
|
|
||||||
|
## There are extra spaces in my layout? What do I do?
|
||||||
|
|
||||||
|
If you're referring to having three spots for space bar, the best course of action is to just fill them all with Space. The same can be done for Backspace and Shift keys.
|
||||||
|
|
||||||
|
## What is the keycode for...
|
||||||
|
|
||||||
|
Please see:
|
||||||
|
|
||||||
|
* [Basic Keycode Reference](keycodes_basic.md)
|
||||||
|
* [Advanced Keycode Reference](feature_advanced_keycodes.md)
|
||||||
|
|
||||||
|
## It won't compile
|
||||||
|
|
||||||
|
Please double check the other layers of your keymap to make sure there are no random keys present.
|
||||||
|
|
||||||
|
## Problems and Bugs
|
||||||
|
|
||||||
|
We are always accepting customer requests and bug reports. Please file them at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues).
|
||||||
+13
-1
@@ -85,7 +85,7 @@ Limited experimentation on the devices I have available shows that 7 is high eno
|
|||||||
|
|
||||||
Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)!
|
Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)!
|
||||||
|
|
||||||
You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click "Suggest An Edit" at the top of each page on http://docs.qmk.fm/.
|
You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click the "Edit this page" link at the bottom of each page on https://docs.qmk.fm/.
|
||||||
|
|
||||||
When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency:
|
When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency:
|
||||||
|
|
||||||
@@ -101,6 +101,18 @@ enum my_keycodes {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Previewing the Documentation :id=previewing-the-documentation
|
||||||
|
|
||||||
|
Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder:
|
||||||
|
|
||||||
|
./bin/qmk docs
|
||||||
|
|
||||||
|
or if you only have Python 3 installed:
|
||||||
|
|
||||||
|
python3 -m http.server 8936
|
||||||
|
|
||||||
|
and navigating to `http://localhost:8936/`.
|
||||||
|
|
||||||
## Keymaps
|
## Keymaps
|
||||||
|
|
||||||
Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap.
|
Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap.
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# Custom Matrix
|
||||||
|
|
||||||
|
QMK provides a mechanism to supplement or replace the default matrix scanning routine with your own code.
|
||||||
|
|
||||||
|
The reasons to use this feature include:
|
||||||
|
|
||||||
|
* Extra hardware between the keyboard's switches and MCU pins
|
||||||
|
* I/O multiplexer
|
||||||
|
* Line decoder
|
||||||
|
* Irregular switch matrix
|
||||||
|
* Simultaneous use of `COL2ROW` and `ROW2COL`
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Implementing custom matrix usually involves compilation of an additional source file. It is recommended that for consistency, this file is called `matrix.c`.
|
||||||
|
|
||||||
|
Add a new file to your keyboard directory:
|
||||||
|
```text
|
||||||
|
keyboards/<keyboard>/matrix.c
|
||||||
|
```
|
||||||
|
|
||||||
|
And to configure compilation for the new file, add this to your `rules.mk`:
|
||||||
|
```make
|
||||||
|
SRC += matrix.c
|
||||||
|
```
|
||||||
|
|
||||||
|
## 'lite'
|
||||||
|
|
||||||
|
Provides a default implementation for various scanning functions, reducing the boilerplate code when implementing custom matrix.
|
||||||
|
To configure it, add this to your `rules.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
CUSTOM_MATRIX = lite
|
||||||
|
```
|
||||||
|
|
||||||
|
And implement the following functions in a `matrix.c` file in your keyboard folder:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void matrix_init_custom(void) {
|
||||||
|
// TODO: initialize hardware here
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
|
||||||
|
bool matrix_has_changed = false;
|
||||||
|
|
||||||
|
// TODO: add matrix scanning routine here
|
||||||
|
|
||||||
|
return matrix_has_changed;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Full Replacement
|
||||||
|
|
||||||
|
When more control over the scanning routine is required, you can choose to implement the full scanning routine.
|
||||||
|
To configure it, add this to your rules.mk:
|
||||||
|
|
||||||
|
```make
|
||||||
|
CUSTOM_MATRIX = yes
|
||||||
|
```
|
||||||
|
|
||||||
|
And implement the following functions in a `matrix.c` file in your keyboard folder:
|
||||||
|
|
||||||
|
```c
|
||||||
|
matrix_row_t matrix_get_row(uint8_t row) {
|
||||||
|
// TODO: return the requested row data
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_print(void) {
|
||||||
|
// TODO: use print() to dump the current matrix state to console
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_init(void) {
|
||||||
|
// TODO: initialize hardware and global matrix state here
|
||||||
|
|
||||||
|
// Unless hardware debouncing - Init the configured debounce routine
|
||||||
|
debounce_init(MATRIX_ROWS);
|
||||||
|
|
||||||
|
// This *must* be called for correct keyboard behavior
|
||||||
|
matrix_init_quantum();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_scan(void) {
|
||||||
|
bool matrix_has_changed = false;
|
||||||
|
|
||||||
|
// TODO: add matrix scanning routine here
|
||||||
|
|
||||||
|
// Unless hardware debouncing - use the configured debounce routine
|
||||||
|
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
|
||||||
|
|
||||||
|
// This *must* be called for correct keyboard behavior
|
||||||
|
matrix_scan_quantum();
|
||||||
|
|
||||||
|
return matrix_has_changed;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And also provide defaults for the following callbacks:
|
||||||
|
|
||||||
|
```c
|
||||||
|
__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_init_user(void) {}
|
||||||
|
|
||||||
|
__attribute__((weak)) void matrix_scan_user(void) {}
|
||||||
|
```
|
||||||
@@ -4,7 +4,7 @@ For a lot of people a custom keyboard is about more than sending button presses
|
|||||||
|
|
||||||
This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level.
|
This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level.
|
||||||
|
|
||||||
## A Word on Core vs Keyboards vs Keymap
|
## A Word on Core vs Keyboards vs Keymap :id=a-word-on-core-vs-keyboards-vs-keymap
|
||||||
|
|
||||||
We have structured QMK as a hierarchy:
|
We have structured QMK as a hierarchy:
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ enum my_keycodes {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Programming the Behavior of Any Keycode
|
## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode
|
||||||
|
|
||||||
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.
|
When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required.
|
||||||
|
|
||||||
@@ -114,7 +114,15 @@ Two more deprecated functions exist that provide the LED state as a `uint8_t`:
|
|||||||
|
|
||||||
This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
|
This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
|
||||||
|
|
||||||
You must return either `true` or `false` from this function, depending on whether you want to override the keyboard-level implementation.
|
By convention, return `true` from `led_update_user()` to get the `led_update_kb()` hook to run its code, and
|
||||||
|
return `false` when you would prefer not to run the code in `led_update_kb()`.
|
||||||
|
|
||||||
|
Some examples include:
|
||||||
|
|
||||||
|
- overriding the LEDs to use them for something else like layer indication
|
||||||
|
- return `false` because you do not want the `_kb()` function to run, as it would override your layer behavior.
|
||||||
|
- play a sound when an LED turns on or off.
|
||||||
|
- return `true` because you want the `_kb` function to run, and this is in addition to the default LED behavior.
|
||||||
|
|
||||||
?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead.
|
?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead.
|
||||||
|
|
||||||
@@ -122,66 +130,41 @@ You must return either `true` or `false` from this function, depending on whethe
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
bool led_update_kb(led_t led_state) {
|
bool led_update_kb(led_t led_state) {
|
||||||
if(led_update_user(led_state)) {
|
bool res = led_update_user(led_state);
|
||||||
if (led_state.num_lock) {
|
if(res) {
|
||||||
writePinLow(B0);
|
// writePin sets the pin high for 1 and low for 0.
|
||||||
} else {
|
// In this example the pins are inverted, setting
|
||||||
writePinHigh(B0);
|
// it low/0 turns it on, and high/1 turns the LED off.
|
||||||
}
|
// This behavior depends on whether the LED is between the pin
|
||||||
if (led_state.caps_lock) {
|
// and VCC or the pin and GND.
|
||||||
writePinLow(B1);
|
writePin(B0, !led_state.num_lock);
|
||||||
} else {
|
writePin(B1, !led_state.caps_lock);
|
||||||
writePinHigh(B1);
|
writePin(B2, !led_state.scroll_lock);
|
||||||
}
|
writePin(B3, !led_state.compose);
|
||||||
if (led_state.scroll_lock) {
|
writePin(B4, !led_state.kana);
|
||||||
writePinLow(B2);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B2);
|
|
||||||
}
|
|
||||||
if (led_state.compose) {
|
|
||||||
writePinLow(B3);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B3);
|
|
||||||
}
|
|
||||||
if (led_state.kana) {
|
|
||||||
writePinLow(B4);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B4);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example `led_update_user()` Implementation
|
### Example `led_update_user()` Implementation
|
||||||
|
|
||||||
|
This incomplete example would play a sound if Caps Lock is turned on or off. It returns `true`, because you also want the LEDs to maintain their state.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
#ifdef AUDIO_ENABLE
|
||||||
|
float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
|
||||||
|
float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool led_update_user(led_t led_state) {
|
bool led_update_user(led_t led_state) {
|
||||||
if (led_state.num_lock) {
|
#ifdef AUDIO_ENABLE
|
||||||
writePinLow(B0);
|
static uint8_t caps_state = 0;
|
||||||
} else {
|
if (caps_state != led_state.caps_lock) {
|
||||||
writePinHigh(B0);
|
led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off);
|
||||||
}
|
caps_state = led_state.caps_lock;
|
||||||
if (led_state.caps_lock) {
|
|
||||||
writePinLow(B1);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B1);
|
|
||||||
}
|
|
||||||
if (led_state.scroll_lock) {
|
|
||||||
writePinLow(B2);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B2);
|
|
||||||
}
|
|
||||||
if (led_state.compose) {
|
|
||||||
writePinLow(B3);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B3);
|
|
||||||
}
|
|
||||||
if (led_state.kana) {
|
|
||||||
writePinLow(B4);
|
|
||||||
} else {
|
|
||||||
writePinHigh(B4);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -330,7 +313,7 @@ void suspend_wakeup_init_user(void) {
|
|||||||
* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)`
|
||||||
|
|
||||||
# Layer Change Code
|
# Layer Change Code :id=layer-change-code
|
||||||
|
|
||||||
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling.
|
||||||
|
|
||||||
@@ -411,7 +394,7 @@ void keyboard_post_init_user(void) {
|
|||||||
// Set default layer, if enabled
|
// Set default layer, if enabled
|
||||||
if (user_config.rgb_layer_change) {
|
if (user_config.rgb_layer_change) {
|
||||||
rgblight_enable_noeeprom();
|
rgblight_enable_noeeprom();
|
||||||
rgblight_sethsv_noeeprom_cyan();
|
rgblight_sethsv_noeeprom_cyan();
|
||||||
rgblight_mode_noeeprom(1);
|
rgblight_mode_noeeprom(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,18 +442,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
}
|
}
|
||||||
return true; // Let QMK send the enter press/release events
|
return true; // Let QMK send the enter press/release events
|
||||||
case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
|
case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
user_config.rgb_layer_change ^= 1; // Toggles the status
|
user_config.rgb_layer_change ^= 1; // Toggles the status
|
||||||
eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
|
eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
|
||||||
if (user_config.rgb_layer_change) { // if layer state indication is enabled,
|
if (user_config.rgb_layer_change) { // if layer state indication is enabled,
|
||||||
layer_state_set(layer_state); // then immediately update the layer color
|
layer_state_set(layer_state); // then immediately update the layer color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false; break;
|
return false; break;
|
||||||
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
|
case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
|
||||||
if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
|
if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
|
||||||
if (user_config.rgb_layer_change) { // only if this is enabled
|
if (user_config.rgb_layer_change) { // only if this is enabled
|
||||||
user_config.rgb_layer_change = false; // disable it, and
|
user_config.rgb_layer_change = false; // disable it, and
|
||||||
eeconfig_update_user(user_config.raw); // write the setings to EEPROM
|
eeconfig_update_user(user_config.raw); // write the setings to EEPROM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +466,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EEP_RST` keycode or [Bootmagic](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
void eeconfig_init_user(void) { // EEPROM is getting reset!
|
||||||
user_config.raw = 0;
|
user_config.raw = 0;
|
||||||
user_config.rgb_layer_change = true; // We want this enabled by default
|
user_config.rgb_layer_change = true; // We want this enabled by default
|
||||||
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
|
eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
|
||||||
@@ -506,14 +489,24 @@ The `val` is the value of the data that you want to write to EEPROM. And the `e
|
|||||||
|
|
||||||
# Custom Tapping Term
|
# Custom Tapping Term
|
||||||
|
|
||||||
By default, the tapping term is defined globally, and is not configurable by key. For most users, this is perfectly fine. But in come cases, dual function keys would be greatly improved by different timeouts than `LT` keys, or because some keys may be easier to hold than others. Instead of using custom key codes for each, this allows for per key configurable `TAPPING_TERM`.
|
By default, the tapping term and related options (such as `IGNORE_MOD_TAP_INTERRUPT`) are defined globally, and are not configurable by key. For most users, this is perfectly fine. But in some cases, dual function keys would be greatly improved by different timeout behaviors than `LT` keys, or because some keys may be easier to hold than others. Instead of using custom key codes for each, this allows for per key configurable timeout behaviors.
|
||||||
|
|
||||||
To enable this functionality, you need to add `#define TAPPING_TERM_PER_KEY` to your `config.h`, first.
|
There are two configurable options to control per-key timeout behaviors:
|
||||||
|
|
||||||
|
- `TAPPING_TERM_PER_KEY`
|
||||||
|
- `IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
|
||||||
|
|
||||||
|
You need to add `#define` lines to your `config.h` for each feature you want.
|
||||||
|
|
||||||
|
```
|
||||||
|
#define TAPPING_TERM_PER_KEY
|
||||||
|
#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Example `get_tapping_term` Implementation
|
## Example `get_tapping_term` Implementation
|
||||||
|
|
||||||
To change the `TAPPING TERM` based on the keycode, you'd want to add something like the following to your `keymap.c` file:
|
To change the `TAPPING_TERM` based on the keycode, you'd want to add something like the following to your `keymap.c` file:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
uint16_t get_tapping_term(uint16_t keycode) {
|
uint16_t get_tapping_term(uint16_t keycode) {
|
||||||
@@ -528,6 +521,21 @@ uint16_t get_tapping_term(uint16_t keycode) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get_tapping_term` Function Documentation
|
## Example `get_ignore_mod_tap_interrupt` Implementation
|
||||||
|
|
||||||
Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard level function. Only a user level function is useful here, so no need to mark it as such.
|
To change the `IGNORE_MOD_TAP_INTERRUPT` value based on the keycode, you'd want to add something like the following to your `keymap.c` file:
|
||||||
|
|
||||||
|
```c
|
||||||
|
bool get_ignore_mod_tap_interrupt(uint16_t keycode) {
|
||||||
|
switch (keycode) {
|
||||||
|
case SFT_T(KC_SPC):
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## `get_tapping_term` / `get_ignore_mod_tap_interrupt` Function Documentation
|
||||||
|
|
||||||
|
Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard level function. Only user level functions are useful here, so no need to mark them as such.
|
||||||
+3
-3
@@ -77,7 +77,7 @@
|
|||||||
* [Macros](de/feature_macros.md)
|
* [Macros](de/feature_macros.md)
|
||||||
* [Mouse Keys](de/feature_mouse_keys.md)
|
* [Mouse Keys](de/feature_mouse_keys.md)
|
||||||
* [OLED Driver](de/feature_oled_driver.md)
|
* [OLED Driver](de/feature_oled_driver.md)
|
||||||
* [One Shot Keys](de/feature_advanced_keycodes.md#one-shot-keys)
|
* [One Shot Keys](de/one_shot_keys.md)
|
||||||
* [Pointing Device](de/feature_pointing_device.md)
|
* [Pointing Device](de/feature_pointing_device.md)
|
||||||
* [PS/2 Mouse](de/feature_ps2_mouse.md)
|
* [PS/2 Mouse](de/feature_ps2_mouse.md)
|
||||||
* [RGB Lighting](de/feature_rgblight.md)
|
* [RGB Lighting](de/feature_rgblight.md)
|
||||||
@@ -108,10 +108,10 @@
|
|||||||
* Andere Themen
|
* Andere Themen
|
||||||
* [Eclipse mit QMK](de/other_eclipse.md)
|
* [Eclipse mit QMK](de/other_eclipse.md)
|
||||||
* [VSCode mit QMK](de/other_vscode.md)
|
* [VSCode mit QMK](de/other_vscode.md)
|
||||||
* [Support](de/support.md)
|
* [Support](de/getting_started_getting_help.md)
|
||||||
* [Übersetzungen](de/translating.md)
|
* [Übersetzungen](de/translating.md)
|
||||||
|
|
||||||
* QMK Internals (de/In Progress)
|
* QMK Internals (In Progress)
|
||||||
* [Defines](de/internals_defines.md)
|
* [Defines](de/internals_defines.md)
|
||||||
* [Input Callback Reg](de/internals_input_callback_reg.md)
|
* [Input Callback Reg](de/internals_input_callback_reg.md)
|
||||||
* [Midi Device](de/internals_midi_device.md)
|
* [Midi Device](de/internals_midi_device.md)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK.
|
This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK.
|
||||||
|
|
||||||
## Keymap `readme.md` Template
|
## Keymap `readme.md` Template :id=keyboard-readmemd-template
|
||||||
|
|
||||||
Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](http://imgur.com) or another hosting service, please do not include images in your Pull Request.
|
Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](http://imgur.com) or another hosting service, please do not include images in your Pull Request.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# EEPROM Driver Configuration
|
||||||
|
|
||||||
|
The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
|
||||||
|
|
||||||
|
Driver | Description
|
||||||
|
-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below.
|
||||||
|
`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
|
||||||
|
`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
|
||||||
|
|
||||||
|
## Vendor Driver Configuration
|
||||||
|
|
||||||
|
!> Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used.
|
||||||
|
|
||||||
|
No configurable options are available.
|
||||||
|
|
||||||
|
## I2C Driver Configuration
|
||||||
|
|
||||||
|
Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
|
||||||
|
|
||||||
|
`config.h` override | Description | Default Value
|
||||||
|
------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------
|
||||||
|
`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000
|
||||||
|
`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)`
|
||||||
|
`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
|
||||||
|
`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
|
||||||
|
`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
|
||||||
|
`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
|
||||||
|
|
||||||
|
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
|
||||||
|
|
||||||
|
Alternatively, there are pre-defined hardware configurations for available chips/modules:
|
||||||
|
|
||||||
|
Module | Equivalent `#define` | Source
|
||||||
|
-----------------|---------------------------------|------------------------------------------
|
||||||
|
CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
|
||||||
|
RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
|
||||||
|
24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/wwwproducts/en/24LC128>
|
||||||
|
24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
|
||||||
|
MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
|
||||||
|
|
||||||
|
?> If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
|
||||||
|
|
||||||
|
## Transient Driver configuration
|
||||||
|
|
||||||
|
The only configurable item for the transient EEPROM driver is its size:
|
||||||
|
|
||||||
|
`config.h` override | Description | Default Value
|
||||||
|
------------------------------- | ----------------------------------------- | -------------
|
||||||
|
`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
|
||||||
|
|
||||||
|
Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
|
||||||
+2
-2
@@ -19,7 +19,7 @@ De cualquier manera, también puedes descargarlo directamente en formatos ([zip]
|
|||||||
|
|
||||||
## Cómo compilar
|
## Cómo compilar
|
||||||
|
|
||||||
Antes de poder compilar, necesitarás [instalar un entorno](getting_started_build_tools.md) para el desarrollo de AVR y/o ARM. Una vez hayas completado este paso, usarás el comando `make` para compilar un teclado y keymap con la siguiente notación:
|
Antes de poder compilar, necesitarás [instalar un entorno](es/getting_started_build_tools.md) para el desarrollo de AVR y/o ARM. Una vez hayas completado este paso, usarás el comando `make` para compilar un teclado y keymap con la siguiente notación:
|
||||||
|
|
||||||
make planck/rev4:default
|
make planck/rev4:default
|
||||||
|
|
||||||
@@ -29,4 +29,4 @@ Este ejemplo compilaría la revisión `rev4` del teclado `planck` con el keymap
|
|||||||
|
|
||||||
## Cómo personalizar
|
## Cómo personalizar
|
||||||
|
|
||||||
QMK tiene montones de [características](features.md) para explorar, y una buena cantidad de [documentación de referencia](http://docs.qmk.fm) en la que sumergirse. Se pueden sacar provecho de la mayoría de las características modificando tu [keymap](keymap.md), y cambiando los [keycodes](keycodes.md).
|
QMK tiene montones de [características](es/features.md) para explorar, y una buena cantidad de [documentación de referencia](http://docs.qmk.fm) en la que sumergirse. Se pueden sacar provecho de la mayoría de las características modificando tu [keymap](es/keymap.md), y cambiando los [keycodes](es/keycodes.md).
|
||||||
+104
-104
@@ -1,121 +1,121 @@
|
|||||||
* [Guía completa para novatos](newbs.md)
|
* [Guía completa para novatos](es/newbs.md)
|
||||||
* [Empezando](newbs_getting_started.md)
|
* [Empezando](es/newbs_getting_started.md)
|
||||||
* [Construyendo tu primer firmare](newbs_building_firmware.md)
|
* [Construyendo tu primer firmare](es/newbs_building_firmware.md)
|
||||||
* [Flasheando el firmware](newbs_flashing.md)
|
* [Flasheando el firmware](es/newbs_flashing.md)
|
||||||
* [Testeando y depurando ](newbs_testing_debugging.md)
|
* [Testeando y depurando ](es/newbs_testing_debugging.md)
|
||||||
* [Mejores práticas](newbs_best_practices.md)
|
* [Mejores práticas](es/newbs_best_practices.md)
|
||||||
* [Recursos de aprendizaje](newbs_learn_more_resources.md)
|
* [Recursos de aprendizaje](es/newbs_learn_more_resources.md)
|
||||||
|
|
||||||
* [QMK Basics](README.md)
|
* [QMK Basics](es/README.md)
|
||||||
* [Introducción a QMK](getting_started_introduction.md)
|
* [Introducción a QMK](es/getting_started_introduction.md)
|
||||||
* [QMK CLI](cli.md)
|
* [QMK CLI](es/cli.md)
|
||||||
* [Configuración de QMK CLI](cli_configuration.md)
|
* [Configuración de QMK CLI](es/cli_configuration.md)
|
||||||
* [Contribuyendo a QMK](contributing.md)
|
* [Contribuyendo a QMK](es/contributing.md)
|
||||||
* [Cómo usar Github](getting_started_github.md)
|
* [Cómo usar Github](es/getting_started_github.md)
|
||||||
* [Obtener ayuda](getting_started_getting_help.md)
|
* [Obtener ayuda](es/getting_started_getting_help.md)
|
||||||
|
|
||||||
* [Cambios incompatibles](breaking_changes.md)
|
* [Cambios incompatibles](es/breaking_changes.md)
|
||||||
* [30 Ago 2019](ChangeLog/20190830.md)
|
* [30 Ago 2019](es/ChangeLog/20190830.md)
|
||||||
|
|
||||||
* [Preguntas frecuentes](faq.md)
|
* [Preguntas frecuentes](es/faq.md)
|
||||||
* [General](faq_general.md)
|
* [General](es/faq_general.md)
|
||||||
* [Construir/Compilar QMK](faq_build.md)
|
* [Construir/Compilar QMK](es/faq_build.md)
|
||||||
* [Depurando/Encontrando problemas en QMK](faq_debug.md)
|
* [Depurando/Encontrando problemas en QMK](es/faq_debug.md)
|
||||||
* [Keymap](faq_keymap.md)
|
* [Keymap](es/faq_keymap.md)
|
||||||
* [Instalación de drivers con Zadig](driver_installation_zadig.md)
|
* [Instalación de drivers con Zadig](es/driver_installation_zadig.md)
|
||||||
|
|
||||||
* Guías detalladas
|
* Guías detalladas
|
||||||
* [Instalar herramientas construcción](getting_started_build_tools.md)
|
* [Instalar herramientas construcción](es/getting_started_build_tools.md)
|
||||||
* [Guía Vagrant](getting_started_vagrant.md)
|
* [Guía Vagrant](es/getting_started_vagrant.md)
|
||||||
* [Instrucciones de Construcción/Compilado](getting_started_make_guide.md)
|
* [Instrucciones de Construcción/Compilado](es/getting_started_make_guide.md)
|
||||||
* [Flasheando Firmware](flashing.md)
|
* [Flasheando Firmware](es/flashing.md)
|
||||||
* [Personalizando funcionalidad](custom_quantum_functions.md)
|
* [Personalizando funcionalidad](es/custom_quantum_functions.md)
|
||||||
* [Visión general del Keymap](keymap.md)
|
* [Visión general del Keymap](es/keymap.md)
|
||||||
|
|
||||||
* [Hardware](hardware.md)
|
* [Hardware](es/hardware.md)
|
||||||
* [Procesadores AVR](hardware_avr.md)
|
* [Procesadores AVR](es/hardware_avr.md)
|
||||||
* [Drivers](hardware_drivers.md)
|
* [Drivers](es/hardware_drivers.md)
|
||||||
|
|
||||||
* Referencia
|
* Referencia
|
||||||
* [Pautas de teclados](hardware_keyboard_guidelines.md)
|
* [Pautas de teclados](es/hardware_keyboard_guidelines.md)
|
||||||
* [Opciones de configuración](config_options.md)
|
* [Opciones de configuración](es/config_options.md)
|
||||||
* [Keycodes](keycodes.md)
|
* [Keycodes](es/keycodes.md)
|
||||||
* [Convenciones de código - C](coding_conventions_c.md)
|
* [Convenciones de código - C](es/coding_conventions_c.md)
|
||||||
* [Convenciones de código - Python](coding_conventions_python.md)
|
* [Convenciones de código - Python](es/coding_conventions_python.md)
|
||||||
* [Mejores prácticas de documentación](documentation_best_practices.md)
|
* [Mejores prácticas de documentación](es/documentation_best_practices.md)
|
||||||
* [Plantillas de documentación](documentation_templates.md)
|
* [Plantillas de documentación](es/documentation_templates.md)
|
||||||
* [Glosario](reference_glossary.md)
|
* [Glosario](es/reference_glossary.md)
|
||||||
* [Tests unitarios](unit_testing.md)
|
* [Tests unitarios](es/unit_testing.md)
|
||||||
* [Funciones útiles](ref_functions.md)
|
* [Funciones útiles](es/ref_functions.md)
|
||||||
* [Sporte configurador](reference_configurator_support.md)
|
* [Sporte configurador](es/reference_configurator_support.md)
|
||||||
* [Formato info.json](reference_info_json.md)
|
* [Formato info.json](es/reference_info_json.md)
|
||||||
* [Desarrollo Python CLI](cli_development.md)
|
* [Desarrollo Python CLI](es/cli_development.md)
|
||||||
|
|
||||||
* [Características](features.md)
|
* [Características](es/features.md)
|
||||||
* [Keycodes Básicos](keycodes_basic.md)
|
* [Keycodes Básicos](es/keycodes_basic.md)
|
||||||
* [Teclas US ANSI Shifted](keycodes_us_ansi_shifted.md)
|
* [Teclas US ANSI Shifted](es/keycodes_us_ansi_shifted.md)
|
||||||
* [Keycodes Quantum](quantum_keycodes.md)
|
* [Keycodes Quantum](es/quantum_keycodes.md)
|
||||||
* [Keycodes Avanzados](feature_advanced_keycodes.md)
|
* [Keycodes Avanzados](es/feature_advanced_keycodes.md)
|
||||||
* [Audio](feature_audio.md)
|
* [Audio](es/feature_audio.md)
|
||||||
* [Auto Shift](feature_auto_shift.md)
|
* [Auto Shift](es/feature_auto_shift.md)
|
||||||
* [Retroiluminación](feature_backlight.md)
|
* [Retroiluminación](es/feature_backlight.md)
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
* [Bluetooth](es/feature_bluetooth.md)
|
||||||
* [Bootmagic](feature_bootmagic.md)
|
* [Bootmagic](es/feature_bootmagic.md)
|
||||||
* [Combos](feature_combo.md)
|
* [Combos](es/feature_combo.md)
|
||||||
* [Comando](feature_command.md)
|
* [Comando](es/feature_command.md)
|
||||||
* [API Debounce](feature_debounce_type.md)
|
* [API Debounce](es/feature_debounce_type.md)
|
||||||
* [Switch DIP](feature_dip_switch.md)
|
* [Switch DIP](es/feature_dip_switch.md)
|
||||||
* [Macros Dinámicas](feature_dynamic_macros.md)
|
* [Macros Dinámicas](es/feature_dynamic_macros.md)
|
||||||
* [Encoders](feature_encoders.md)
|
* [Encoders](es/feature_encoders.md)
|
||||||
* [Grave Escape](feature_grave_esc.md)
|
* [Grave Escape](es/feature_grave_esc.md)
|
||||||
* [Feedback Háptico](feature_haptic_feedback.md)
|
* [Feedback Háptico](es/feature_haptic_feedback.md)
|
||||||
* [Controlador LCD HD44780](feature_hd44780.md)
|
* [Controlador LCD HD44780](es/feature_hd44780.md)
|
||||||
* [Key Lock](feature_key_lock.md)
|
* [Key Lock](es/feature_key_lock.md)
|
||||||
* [Layouts](feature_layouts.md)
|
* [Layouts](es/feature_layouts.md)
|
||||||
* [Tecla Leader](feature_leader_key.md)
|
* [Tecla Leader](es/feature_leader_key.md)
|
||||||
* [Matriz LED](feature_led_matrix.md)
|
* [Matriz LED](es/feature_led_matrix.md)
|
||||||
* [Macros](feature_macros.md)
|
* [Macros](es/feature_macros.md)
|
||||||
* [Teclas del ratón](feature_mouse_keys.md)
|
* [Teclas del ratón](es/feature_mouse_keys.md)
|
||||||
* [Driver OLED](feature_oled_driver.md)
|
* [Driver OLED](es/feature_oled_driver.md)
|
||||||
* [Teclas One Shot](feature_advanced_keycodes.md#one-shot-keys)
|
* [Teclas One Shot](es/one_shot_keys.md)
|
||||||
* [Dispositivo de apuntado](feature_pointing_device.md)
|
* [Dispositivo de apuntado](es/feature_pointing_device.md)
|
||||||
* [Ratón PS/2](feature_ps2_mouse.md)
|
* [Ratón PS/2](es/feature_ps2_mouse.md)
|
||||||
* [Iluminación RGB](feature_rgblight.md)
|
* [Iluminación RGB](es/feature_rgblight.md)
|
||||||
* [Matriz RGB](feature_rgb_matrix.md)
|
* [Matriz RGB](es/feature_rgb_matrix.md)
|
||||||
* [Cadete espacial](feature_space_cadet.md)
|
* [Cadete espacial](es/feature_space_cadet.md)
|
||||||
* [Teclado dividido](feature_split_keyboard.md)
|
* [Teclado dividido](es/feature_split_keyboard.md)
|
||||||
* [Stenografía](feature_stenography.md)
|
* [Stenografía](es/feature_stenography.md)
|
||||||
* [Swap Hands](feature_swap_hands.md)
|
* [Swap Hands](es/feature_swap_hands.md)
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
* [Tap Dance](es/feature_tap_dance.md)
|
||||||
* [Terminal](feature_terminal.md)
|
* [Terminal](es/feature_terminal.md)
|
||||||
* [Impresora Térmica](feature_thermal_printer.md)
|
* [Impresora Térmica](es/feature_thermal_printer.md)
|
||||||
* [Unicode](feature_unicode.md)
|
* [Unicode](es/feature_unicode.md)
|
||||||
* [Userspace](feature_userspace.md)
|
* [Userspace](es/feature_userspace.md)
|
||||||
* [Velocikey](feature_velocikey.md)
|
* [Velocikey](es/feature_velocikey.md)
|
||||||
|
|
||||||
* Para Makers y Modders
|
* Para Makers y Modders
|
||||||
* [Guía de cableado a mano](hand_wire.md)
|
* [Guía de cableado a mano](es/hand_wire.md)
|
||||||
* [Guía de flasheado de ISP](isp_flashing_guide.md)
|
* [Guía de flasheado de ISP](es/isp_flashing_guide.md)
|
||||||
* [Guía de depuración de ARM](arm_debugging.md)
|
* [Guía de depuración de ARM](es/arm_debugging.md)
|
||||||
* [Driver I2C](i2c_driver.md)
|
* [Driver I2C](es/i2c_driver.md)
|
||||||
* [Controles GPIO](internals_gpio_control.md)
|
* [Controles GPIO](es/internals_gpio_control.md)
|
||||||
* [Conversión Proton C](proton_c_conversion.md)
|
* [Conversión Proton C](es/proton_c_conversion.md)
|
||||||
|
|
||||||
* Para entender en profundidad
|
* Para entender en profundidad
|
||||||
* [Cómo funcionan los teclados](how_keyboards_work.md)
|
* [Cómo funcionan los teclados](es/how_keyboards_work.md)
|
||||||
* [Entendiendo QMK](understanding_qmk.md)
|
* [Entendiendo QMK](es/understanding_qmk.md)
|
||||||
|
|
||||||
* Otros temas
|
* Otros temas
|
||||||
* [Usando Eclipse con QMK](other_eclipse.md)
|
* [Usando Eclipse con QMK](es/other_eclipse.md)
|
||||||
* [Usando VSCode con QMK](other_vscode.md)
|
* [Usando VSCode con QMK](es/other_vscode.md)
|
||||||
* [Soporte](support.md)
|
* [Soporte](es/getting_started_getting_help.md)
|
||||||
* [Cómo añadir traducciones](translating.md)
|
* [Cómo añadir traducciones](es/translating.md)
|
||||||
|
|
||||||
* QMK Internals (En progreso)
|
* QMK Internals (En progreso)
|
||||||
* [Defines](internals_defines.md)
|
* [Defines](es/internals_defines.md)
|
||||||
* [Input Callback Reg](internals_input_callback_reg.md)
|
* [Input Callback Reg](es/internals_input_callback_reg.md)
|
||||||
* [Dispositivo Midi](internals_midi_device.md)
|
* [Dispositivo Midi](es/internals_midi_device.md)
|
||||||
* [Proceso de configuración de un dispositivo Midi](internals_midi_device_setup_process.md)
|
* [Proceso de configuración de un dispositivo Midi](es/internals_midi_device_setup_process.md)
|
||||||
* [Utilidad Midi](internals_midi_util.md)
|
* [Utilidad Midi](es/internals_midi_util.md)
|
||||||
* [Funciones Send](internals_send_functions.md)
|
* [Funciones Send](es/internals_send_functions.md)
|
||||||
* [Herramientas Sysex](internals_sysex_tools.md)
|
* [Herramientas Sysex](es/internals_sysex_tools.md)
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# Llegar a ser un colaborador QMK
|
|
||||||
|
|
||||||
Un colaborador QMK es un maker o diseñador de teclados que tiene interés en ayudar a QMK a crecer y mantener sus teclado(s), y alentar a los usuarios y clientes a presentar herramientas, ideas, y keymaps. Siempre procuramos agregar más teclados y colaboradores, pero pedimos que cumplan los siguientes requisitos:
|
|
||||||
|
|
||||||
* **Tener un PCB disponible a la venta.** Desafortunadamente, hay demasiada variación y complicaciones con teclados cableados a mano.
|
|
||||||
* **Realizar el mantenimiento de tu teclado en QMK.** Este podría requirir un setup inicial para hacer que tu teclado funcione, pero también podría incluir adaptarse a cambios hecho al base de QMK que podrían descomponer o rendir código superfluo.
|
|
||||||
* **Aprobar e incorporar pull requests de keymaps para tu teclado.** Nos gusta alentar a los usuarios a contribuir sus keymaps para que otros los vean y los puedan usar para crear sus propios.
|
|
||||||
|
|
||||||
Si sientes que cumples los requisitos, ¡mándanos un email a hello@qmk.fm con una introducción y algunos enlaces para tu teclado!
|
|
||||||
@@ -4,7 +4,7 @@ El [Configurador QMK](https://config.qmk.fm) es un entorno gráfico online que g
|
|||||||
|
|
||||||
?> **Por favor sigue estos pasos en orden.**
|
?> **Por favor sigue estos pasos en orden.**
|
||||||
|
|
||||||
Ve el [Video tutorial](https://youtu.be/tx54jkRC9ZY)
|
Ve el [Video tutorial](https://www.youtube.com/watch?v=-imgglzDMdY)
|
||||||
|
|
||||||
El Configurador QMK functiona mejor con Chrome/Firefox.
|
El Configurador QMK functiona mejor con Chrome/Firefox.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
# Frequently Asked Questions
|
|
||||||
|
|
||||||
* [General](faq_general.md)
|
|
||||||
* [Building or Compiling QMK](faq_build.md)
|
|
||||||
* [Debugging and Troubleshooting QMK](faq_debug.md)
|
|
||||||
* [Keymap](faq_keymap.md)
|
|
||||||
+17
-33
@@ -47,7 +47,7 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="feed", MODE:="0666"
|
|||||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", MODE:="0666"
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1c11", MODE:="0666"
|
||||||
```
|
```
|
||||||
|
|
||||||
**/etc/udev/rules.d/55-catalina.rules:**
|
**/etc/udev/rules.d/55-caterina.rules:**
|
||||||
```
|
```
|
||||||
# ModemManager should ignore the following devices
|
# ModemManager should ignore the following devices
|
||||||
ATTRS{idVendor}=="2a03", ENV{ID_MM_DEVICE_IGNORE}="1"
|
ATTRS{idVendor}=="2a03", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||||
@@ -69,6 +69,12 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="1eaf", ATTRS{idProduct}=="0003", MODE:="066
|
|||||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666"
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**/etc/udev/rules.d/57-bootloadhid.rules:**
|
||||||
|
```
|
||||||
|
# bootloadHID
|
||||||
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df", MODE:="0666"
|
||||||
|
```
|
||||||
|
|
||||||
### Serial device is not detected in bootloader mode on Linux
|
### Serial device is not detected in bootloader mode on Linux
|
||||||
Make sure your kernel has appropriate support for your device. If your device uses USB ACM, such as
|
Make sure your kernel has appropriate support for your device. If your device uses USB ACM, such as
|
||||||
Pro Micro (Atmega32u4), make sure to include `CONFIG_USB_ACM=y`. Other devices may require `USB_SERIAL` and any of its sub options.
|
Pro Micro (Atmega32u4), make sure to include `CONFIG_USB_ACM=y`. Other devices may require `USB_SERIAL` and any of its sub options.
|
||||||
@@ -81,10 +87,6 @@ Re-running the QMK installation script (`./util/qmk_install.sh` from the `qmk_fi
|
|||||||
|
|
||||||
If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig.md) for more detailed information.
|
If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig.md) for more detailed information.
|
||||||
|
|
||||||
## 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).
|
|
||||||
|
|
||||||
## USB VID and PID
|
## USB VID and PID
|
||||||
You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product.
|
You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product.
|
||||||
|
|
||||||
@@ -97,29 +99,6 @@ You can buy a really unique VID:PID here. I don't think you need this for person
|
|||||||
- http://www.obdev.at/products/vusb/license.html
|
- http://www.obdev.at/products/vusb/license.html
|
||||||
- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1
|
- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1
|
||||||
|
|
||||||
## Cortex: `cstddef: No such file or directory`
|
|
||||||
GCC 4.8 of Ubuntu 14.04 had this problem and had to update to 4.9 with this PPA.
|
|
||||||
https://launchpad.net/~terry.guo/+archive/ubuntu/gcc-arm-embedded
|
|
||||||
|
|
||||||
https://github.com/tmk/tmk_keyboard/issues/212
|
|
||||||
https://github.com/tmk/tmk_keyboard/wiki/mbed-cortex-porting#compile-error-cstddef
|
|
||||||
https://developer.mbed.org/forum/mbed/topic/5205/
|
|
||||||
|
|
||||||
## `clock_prescale_set` and `clock_div_1` Not Available
|
|
||||||
Your toolchain is too old to support the MCU. For example WinAVR 20100110 doesn't support ATMega32u2.
|
|
||||||
|
|
||||||
```
|
|
||||||
Compiling C: ../../tmk_core/protocol/lufa/lufa.c
|
|
||||||
avr-gcc -c -mmcu=atmega32u2 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -DF_USB=16000000UL -DARCH=ARCH_AVR8 -DUSB_DEVICE_ONLY -DUSE_FLASH_DESCRIPTORS -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DFIXED_NUM_CONFIGURATIONS=1 -DPROTOCOL_LUFA -DEXTRAKEY_ENABLE -DCONSOLE_ENABLE -DCOMMAND_ENABLE -DVERSION=unknown -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fdata-sections -fno-inline-small-functions -fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Wstrict-prototypes -Wa,-adhlns=obj_alps64/protocol/lufa/lufa.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_alps64_protocol_lufa_lufa.o.d ../../tmk_core/protocol/lufa/lufa.c -o obj_alps64/protocol/lufa/lufa.o
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c: In function 'setup_mcu':
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: warning: implicit declaration of function 'clock_prescale_set'
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: 'clock_div_1' undeclared (first use in this function)
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: (Each undeclared identifier is reported only once
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: for each function it appears in.)
|
|
||||||
make: *** [obj_alps64/protocol/lufa/lufa.o] Error 1
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## BOOTLOADER_SIZE for AVR
|
## BOOTLOADER_SIZE for AVR
|
||||||
Note that Teensy2.0++ bootloader size is 2048byte. Some Makefiles may have wrong comment.
|
Note that Teensy2.0++ bootloader size is 2048byte. Some Makefiles may have wrong comment.
|
||||||
|
|
||||||
@@ -140,24 +119,29 @@ The solution is to remove and reinstall all affected modules.
|
|||||||
|
|
||||||
```
|
```
|
||||||
brew rm avr-gcc
|
brew rm avr-gcc
|
||||||
|
brew rm avr-gcc@8
|
||||||
brew rm dfu-programmer
|
brew rm dfu-programmer
|
||||||
brew rm dfu-util
|
brew rm dfu-util
|
||||||
brew rm gcc-arm-none-eabi
|
brew rm gcc-arm-none-eabi
|
||||||
|
brew rm arm-gcc-bin@8
|
||||||
brew rm avrdude
|
brew rm avrdude
|
||||||
brew install avr-gcc
|
brew install avr-gcc@8
|
||||||
brew install dfu-programmer
|
brew install dfu-programmer
|
||||||
brew install dfu-util
|
brew install dfu-util
|
||||||
brew install gcc-arm-none-eabi
|
brew install arm-gcc-bin@8
|
||||||
brew install avrdude
|
brew install avrdude
|
||||||
|
brew link --force avr-gcc@8
|
||||||
|
brew link --force arm-gcc-bin@8
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### avr-gcc 8.1 and LUFA
|
### `avr-gcc` and LUFA
|
||||||
|
|
||||||
If you updated your avr-gcc to above 7 you may see errors involving LUFA. For example:
|
If you updated your `avr-gcc` and you see errors involving LUFA, for example:
|
||||||
|
|
||||||
`lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h:380:5: error: 'const' attribute on function returning 'void'`
|
`lib/lufa/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h:380:5: error: 'const' attribute on function returning 'void'`
|
||||||
|
|
||||||
For now, you need to rollback avr-gcc to 7 in brew.
|
For now, you need to rollback `avr-gcc` to 8 in Homebrew.
|
||||||
|
|
||||||
```
|
```
|
||||||
brew uninstall --force avr-gcc
|
brew uninstall --force avr-gcc
|
||||||
|
|||||||
@@ -112,56 +112,6 @@ In C `1` means one of [int] type which is [16 bit] in case of AVR so you can't s
|
|||||||
|
|
||||||
http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279
|
http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279
|
||||||
|
|
||||||
|
|
||||||
## Bootloader Jump Doesn't Work
|
|
||||||
Properly configure bootloader size in **Makefile**. With wrong section size bootloader won't probably start with **Magic command** and **Boot Magic**.
|
|
||||||
```
|
|
||||||
# Size of Bootloaders in bytes:
|
|
||||||
# Atmel DFU loader(ATmega32U4) 4096
|
|
||||||
# Atmel DFU loader(AT90USB128) 8192
|
|
||||||
# LUFA bootloader(ATmega32U4) 4096
|
|
||||||
# Arduino Caterina(ATmega32U4) 4096
|
|
||||||
# USBaspLoader(ATmega***) 2048
|
|
||||||
# Teensy halfKay(ATmega32U4) 512
|
|
||||||
# Teensy++ halfKay(AT90USB128) 2048
|
|
||||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
|
||||||
```
|
|
||||||
AVR Boot section size are defined by setting **BOOTSZ** fuse in fact. Consult with your MCU datasheet.
|
|
||||||
Note that **Word**(2 bytes) size and address are used in datasheet while TMK uses **Byte**.
|
|
||||||
|
|
||||||
AVR Boot section is located at end of Flash memory like the followings.
|
|
||||||
```
|
|
||||||
byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB1286)
|
|
||||||
0x0000 +---------------+ 0x00000 +---------------+
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| Application | | Application |
|
|
||||||
| | | |
|
|
||||||
= = = =
|
|
||||||
| | 32KB-4KB | | 128KB-8KB
|
|
||||||
0x6000 +---------------+ 0x1E000 +---------------+
|
|
||||||
| Bootloader | 4KB | Bootloader | 8KB
|
|
||||||
0x7FFF +---------------+ 0x1FFFF +---------------+
|
|
||||||
|
|
||||||
|
|
||||||
byte Teensy(ATMega32u4) byte Teensy++(AT90SUB1286)
|
|
||||||
0x0000 +---------------+ 0x00000 +---------------+
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| Application | | Application |
|
|
||||||
| | | |
|
|
||||||
= = = =
|
|
||||||
| | 32KB-512B | | 128KB-2KB
|
|
||||||
0x7E00 +---------------+ 0x1FC00 +---------------+
|
|
||||||
| Bootloader | 512B | Bootloader | 2KB
|
|
||||||
0x7FFF +---------------+ 0x1FFFF +---------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
And see this discussion for further reference.
|
|
||||||
https://github.com/tmk/tmk_keyboard/issues/179
|
|
||||||
|
|
||||||
If you are using a TeensyUSB, there is a [known bug](https://github.com/qmk/qmk_firmware/issues/164) in which the hardware reset button prevents the RESET key from working. Unplugging the keyboard and plugging it back in should resolve the problem.
|
|
||||||
|
|
||||||
## Special Extra Key Doesn't Work (System, Audio Control Keys)
|
## Special Extra Key Doesn't Work (System, Audio Control Keys)
|
||||||
You need to define `EXTRAKEY_ENABLE` in `rules.mk` to use them in QMK.
|
You need to define `EXTRAKEY_ENABLE` in `rules.mk` to use them in QMK.
|
||||||
|
|
||||||
@@ -194,24 +144,6 @@ If you would like to keep JTAG enabled, just add the following to your `config.h
|
|||||||
#define NO_JTAG_DISABLE
|
#define NO_JTAG_DISABLE
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding LED Indicators of Lock Keys
|
|
||||||
You need your own LED indicators for CapsLock, ScrollLock and NumLock? See this post.
|
|
||||||
|
|
||||||
http://deskthority.net/workshop-f7/tmk-keyboard-firmware-collection-t4478-120.html#p191560
|
|
||||||
|
|
||||||
## Program Arduino Micro/Leonardo
|
|
||||||
Push reset button and then run command like this within 8 seconds.
|
|
||||||
|
|
||||||
```
|
|
||||||
avrdude -patmega32u4 -cavr109 -b57600 -Uflash:w:adb_usb.hex -P/dev/ttyACM0
|
|
||||||
```
|
|
||||||
|
|
||||||
Device name will vary depending on your system.
|
|
||||||
|
|
||||||
http://arduino.cc/en/Main/ArduinoBoardMicro
|
|
||||||
https://geekhack.org/index.php?topic=14290.msg1563867#msg1563867
|
|
||||||
|
|
||||||
|
|
||||||
## USB 3 Compatibility
|
## USB 3 Compatibility
|
||||||
I heard some people have a problem with USB 3 port, try USB 2 port.
|
I heard some people have a problem with USB 3 port, try USB 2 port.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,44 @@
|
|||||||
|
|
||||||
[QMK](https://github.com/qmk), short for Quantum Mechanical Keyboard, is a group of people building tools for custom keyboards. We started with the [QMK firmware](https://github.com/qmk/qmk_firmware), a heavily modified fork of [TMK](https://github.com/tmk/tmk_keyboard).
|
[QMK](https://github.com/qmk), short for Quantum Mechanical Keyboard, is a group of people building tools for custom keyboards. We started with the [QMK firmware](https://github.com/qmk/qmk_firmware), a heavily modified fork of [TMK](https://github.com/tmk/tmk_keyboard).
|
||||||
|
|
||||||
|
## I don't know where to start!
|
||||||
|
|
||||||
|
If this is the case, then you should start with our [Newbs Guide](newbs.md). There is a lot of great info there, and that should cover everything you need to get started.
|
||||||
|
|
||||||
|
If that's an issue, hop onto the [QMK Configurator](https://config.qmk.fm), as that will handle a majority of what you need there.
|
||||||
|
|
||||||
|
## How can I flash the firmware I built?
|
||||||
|
|
||||||
|
First, head to the [Compiling/Flashing FAQ Page](faq_build.md). There is a good deal of info there, and you'll find a bunch of solutions to common issues there.
|
||||||
|
|
||||||
|
## What if I have an issue that isn't covered here?
|
||||||
|
|
||||||
|
Okay, that's fine. Then please check the [open issues in our GitHub](https://github.com/qmk/qmk_firmware/issues) to see if somebody is experiencing the same thing (make sure it's not just similar, but actually the same).
|
||||||
|
|
||||||
|
If you can't find anything, then please open a [new issue](https://github.com/qmk/qmk_firmware/issues/new)!
|
||||||
|
|
||||||
|
## What if I found a bug?
|
||||||
|
|
||||||
|
Then please open an [issue](https://github.com/qmk/qmk_firmware/issues/new), and if you know how to fix it, open up a Pull Request on GitHub with the fix.
|
||||||
|
|
||||||
|
## But `git` and `GitHub` are intimidating!
|
||||||
|
|
||||||
|
Don't worry, we have some pretty nice [Guidelines](newbs_git_best_practices.md) on how to start using `git` and GitHub to make things easier to develop.
|
||||||
|
|
||||||
|
Additionally, you can find additional `git` and GitHub related links [here](newbs_learn_more_resources.md).
|
||||||
|
|
||||||
|
## I have a Keyboard that I want to add support for
|
||||||
|
|
||||||
|
Awesome! Open up a Pull Request for it. We'll review the code, and merge it!
|
||||||
|
|
||||||
|
### What if I want to do brand it with `QMK`?
|
||||||
|
|
||||||
|
That's amazing! We would love to assist you with that!
|
||||||
|
|
||||||
|
In fact, we have a [whole page](https://qmk.fm/powered/) dedicated to adding QMK Branding to your page and keyboard. This covers pretty much everything you need (knowledge and images) to officially support QMK.
|
||||||
|
|
||||||
|
If you have any questions about this, open an issue or head to [Discord](https://discord.gg/Uq7gcHh).
|
||||||
|
|
||||||
## What Differences Are There Between QMK and TMK?
|
## What Differences Are There Between QMK and TMK?
|
||||||
|
|
||||||
TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK.
|
TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK.
|
||||||
|
|||||||
+12
-62
@@ -14,6 +14,17 @@ There are 3 standard keyboard layouts in use around the world- ANSI, ISO, and JI
|
|||||||
<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/bf431647d1001cff5eff20ae55621e9a -->
|
<!-- Source for this image: http://www.keyboard-layout-editor.com/#/gists/bf431647d1001cff5eff20ae55621e9a -->
|
||||||

|

|
||||||
|
|
||||||
|
## How Can I Make Custom Names For Complex Keycodes?
|
||||||
|
|
||||||
|
Sometimes, for readability's sake, it's useful to define custom names for some keycodes. People often define custom names using `#define`. For example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define FN_CAPS LT(_FL, KC_CAPSLOCK)
|
||||||
|
#define ALT_TAB LALT(KC_TAB)
|
||||||
|
```
|
||||||
|
|
||||||
|
This will allow you to use `FN_CAPS` and `ALT_TAB` in your keymap, keeping it more readable.
|
||||||
|
|
||||||
## Some Of My Keys Are Swapped Or Not Working
|
## Some Of My Keys Are Swapped Or Not Working
|
||||||
|
|
||||||
QMK has two features, Bootmagic and Command, which allow you to change the behavior of your keyboard on the fly. This includes, but is not limited to, swapping Ctrl/Caps, disabling Gui, swapping Alt/Gui, swapping Backspace/Backslash, disabling all keys, and other behavioral modifications.
|
QMK has two features, Bootmagic and Command, which allow you to change the behavior of your keyboard on the fly. This includes, but is not limited to, swapping Ctrl/Caps, disabling Gui, swapping Alt/Gui, swapping Backspace/Backslash, disabling all keys, and other behavioral modifications.
|
||||||
@@ -67,24 +78,8 @@ After enabling this feature use keycodes `KC_LCAP`, `KC_LNUM` and `KC_LSCR` in y
|
|||||||
Old vintage mechanical keyboards occasionally have lock switches but modern ones don't have. ***You don't need this feature in most case and just use keycodes `KC_CAPS`, `KC_NLCK` and `KC_SLCK`.***
|
Old vintage mechanical keyboards occasionally have lock switches but modern ones don't have. ***You don't need this feature in most case and just use keycodes `KC_CAPS`, `KC_NLCK` and `KC_SLCK`.***
|
||||||
|
|
||||||
## Input Special Characters Other Than ASCII like Cédille 'Ç'
|
## Input Special Characters Other Than ASCII like Cédille 'Ç'
|
||||||
NO UNIVERSAL METHOD TO INPUT THOSE WORKS OVER ALL SYSTEMS. You have to define **MACRO** in way specific to your OS or layout.
|
|
||||||
|
|
||||||
See this post for example **MACRO** code.
|
See the [Unicode](feature_unicode.md) feature.
|
||||||
|
|
||||||
http://deskthority.net/workshop-f7/tmk-keyboard-firmware-collection-t4478-120.html#p195620
|
|
||||||
|
|
||||||
On **Windows** you can use `AltGr` key or **Alt code**.
|
|
||||||
* http://en.wikipedia.org/wiki/AltGr_key
|
|
||||||
* http://en.wikipedia.org/wiki/Alt_code
|
|
||||||
|
|
||||||
On **Mac** OS defines `Option` key combinations.
|
|
||||||
* http://en.wikipedia.org/wiki/Option_key#Alternative_keyboard_input
|
|
||||||
|
|
||||||
On **Xorg** you can use `compose` key, instead.
|
|
||||||
* http://en.wikipedia.org/wiki/Compose_key
|
|
||||||
|
|
||||||
And see this for **Unicode** input.
|
|
||||||
* http://en.wikipedia.org/wiki/Unicode_input
|
|
||||||
|
|
||||||
## `Fn` Key on macOS
|
## `Fn` Key on macOS
|
||||||
|
|
||||||
@@ -130,51 +125,6 @@ https://github.com/tekezo/Karabiner/issues/403
|
|||||||
|
|
||||||
See the [Grave Escape](feature_grave_esc.md) feature.
|
See the [Grave Escape](feature_grave_esc.md) feature.
|
||||||
|
|
||||||
## Arrow on Right Modifier Keys with Dual-Role
|
|
||||||
This turns right modifier keys into arrow keys when the keys are tapped while still modifiers when the keys are hold. In TMK the dual-role function is dubbed **TAP**.
|
|
||||||
```
|
|
||||||
|
|
||||||
#include "keymap_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Arrow keys on right modifier keys with TMK dual role feature
|
|
||||||
*
|
|
||||||
* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#213-modifier-with-tap-keydual-role
|
|
||||||
* https://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
|
|
||||||
*/
|
|
||||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
||||||
/* 0: qwerty */
|
|
||||||
[0] = LAYOUT( \
|
|
||||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, NUHS,BSPC, \
|
|
||||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, \
|
|
||||||
LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, \
|
|
||||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH,FN0, ESC, \
|
|
||||||
FN4, LGUI,LALT, SPC, APP, FN2, FN1, FN3),
|
|
||||||
[1] = LAYOUT( \
|
|
||||||
GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS,TRNS, \
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,\
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,FN5, TRNS, \
|
|
||||||
TRNS,TRNS,TRNS, TRNS, TRNS,FN7, FN6, FN8),
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint16_t PROGMEM fn_actions[] = {
|
|
||||||
[0] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_UP),
|
|
||||||
[1] = ACTION_MODS_TAP_KEY(MOD_RGUI, KC_DOWN),
|
|
||||||
[2] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_LEFT),
|
|
||||||
[3] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_RIGHT),
|
|
||||||
[4] = ACTION_LAYER_MOMENTARY(1),
|
|
||||||
[5] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_PGUP),
|
|
||||||
[6] = ACTION_MODS_TAP_KEY(MOD_RGUI, KC_PGDN),
|
|
||||||
[7] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_HOME),
|
|
||||||
[8] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_END),
|
|
||||||
};
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Dual-role key: https://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
|
|
||||||
|
|
||||||
|
|
||||||
## Eject on Mac OSX
|
## Eject on Mac OSX
|
||||||
`KC_EJCT` keycode works on OSX. https://github.com/tmk/tmk_keyboard/issues/250
|
`KC_EJCT` keycode works on OSX. https://github.com/tmk/tmk_keyboard/issues/250
|
||||||
It seems Windows 10 ignores the code and Linux/Xorg recognizes but has no mapping by default.
|
It seems Windows 10 ignores the code and Linux/Xorg recognizes but has no mapping by default.
|
||||||
|
|||||||
@@ -1,25 +1,4 @@
|
|||||||
# Advanced Keycodes
|
# Switching and Toggling Layers :id=switching-and-toggling-layers
|
||||||
|
|
||||||
Your keymap can include keycodes that are more advanced than normal, for example keys that switch layers or send modifiers when held, but send regular keycodes when tapped. This page documents the functions that are available to you.
|
|
||||||
|
|
||||||
## Assigning Custom Names
|
|
||||||
|
|
||||||
People often define custom names using `#define`. For example:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define FN_CAPS LT(_FL, KC_CAPSLOCK)
|
|
||||||
#define ALT_TAB LALT(KC_TAB)
|
|
||||||
```
|
|
||||||
|
|
||||||
This will allow you to use `FN_CAPS` and `ALT_TAB` in your keymap, keeping it more readable.
|
|
||||||
|
|
||||||
## Caveats
|
|
||||||
|
|
||||||
Currently, `LT()` and `MT()` are limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. Modifiers specified as part of a Layer Tap or Mod Tap's keycode will be ignored. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this.
|
|
||||||
|
|
||||||
Additionally, if at least one right-handed modifier is specified in a Mod Tap or Layer Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two.
|
|
||||||
|
|
||||||
# Switching and Toggling Layers
|
|
||||||
|
|
||||||
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). When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
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). When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended.
|
||||||
|
|
||||||
@@ -27,11 +6,17 @@ These functions allow you to activate layers in various ways. Note that layers a
|
|||||||
* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated.
|
* `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: `MOD_LCTL`, `MOD_LSFT`, `MOD_LALT`, `MOD_LGUI` (note the use of `MOD_` constants instead of `KC_`). These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15 and the left modifiers: `MOD_LCTL`, `MOD_LSFT`, `MOD_LALT`, `MOD_LGUI` (note the use of `MOD_` constants instead of `KC_`). These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`.
|
||||||
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15.
|
||||||
* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](#one-shot-keys) for details and additional functionality.
|
* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys.md) for details and additional functionality.
|
||||||
* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa
|
* `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).
|
* `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.
|
* `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.
|
||||||
|
|
||||||
|
## Caveats
|
||||||
|
|
||||||
|
Currently, `LT()` and `MT()` are limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. Modifiers specified as part of a Layer Tap or Mod Tap's keycode will be ignored. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this.
|
||||||
|
|
||||||
|
Additionally, if at least one right-handed modifier is specified in a Mod Tap or Layer Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two.
|
||||||
|
|
||||||
# Working with Layers
|
# Working with Layers
|
||||||
|
|
||||||
Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems.
|
Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems.
|
||||||
@@ -56,7 +41,7 @@ Layers stack on top of each other in numerical order. When determining what a ke
|
|||||||
|
|
||||||
Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_layer.h).
|
Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/tmk_core/common/action_layer.h).
|
||||||
|
|
||||||
# Modifier Keys
|
# Modifier Keys :id=modifier-keys
|
||||||
|
|
||||||
These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent.
|
These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent.
|
||||||
|
|
||||||
@@ -78,251 +63,18 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|
|||||||
|
|
||||||
You can also chain them, for example `LCTL(LALT(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
|
You can also chain them, for example `LCTL(LALT(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress.
|
||||||
|
|
||||||
# Mod-Tap
|
# Legacy Content
|
||||||
|
|
||||||
The Mod-Tap key `MT(mod, kc)` acts like a modifier when held, and a regular keycode when tapped. In other words, you can have a key that sends Escape when you tap it, but functions as a Control or Shift key when you hold it down.
|
This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
||||||
|
|
||||||
The modifiers this keycode and `OSM()` accept are prefixed with `MOD_`, not `KC_`:
|
## Mod-Tap :id=mod-tap
|
||||||
|
|
||||||
|Modifier |Description |
|
* [Mod-Tap](mod_tap.md)
|
||||||
|----------|----------------------------------------|
|
|
||||||
|`MOD_LCTL`|Left Control |
|
|
||||||
|`MOD_LSFT`|Left Shift |
|
|
||||||
|`MOD_LALT`|Left Alt |
|
|
||||||
|`MOD_LGUI`|Left GUI (Windows/Command/Meta key) |
|
|
||||||
|`MOD_RCTL`|Right Control |
|
|
||||||
|`MOD_RSFT`|Right Shift |
|
|
||||||
|`MOD_RALT`|Right Alt (AltGr) |
|
|
||||||
|`MOD_RGUI`|Right GUI (Windows/Command/Meta key) |
|
|
||||||
|`MOD_HYPR`|Hyper (Left Control, Shift, Alt and GUI)|
|
|
||||||
|`MOD_MEH` |Meh (Left Control, Shift, and Alt) |
|
|
||||||
|
|
||||||
You can combine these by ORing them together like so:
|
## One Shot Keys :id=one-shot-keys
|
||||||
|
|
||||||
```c
|
* [One Shot Keys](one_shot_keys.md)
|
||||||
MT(MOD_LCTL | MOD_LSFT, KC_ESC)
|
|
||||||
```
|
|
||||||
|
|
||||||
This key would activate Left Control and Left Shift when held, and send Escape when tapped.
|
## Tap-Hold Configuration Options :id=tap-hold-configuration-options
|
||||||
|
|
||||||
For convenience, QMK includes some Mod-Tap shortcuts to make common combinations more compact in your keymap:
|
* [Tap-Hold Configuration Options](tap_hold.md)
|
||||||
|
|
||||||
|Key |Aliases |Description |
|
|
||||||
|------------|-----------------------------------------------------------------|-------------------------------------------------------|
|
|
||||||
|`LCTL_T(kc)`|`CTL_T(kc)` |Left Control when held, `kc` when tapped |
|
|
||||||
|`LSFT_T(kc)`|`SFT_T(kc)` |Left Shift when held, `kc` when tapped |
|
|
||||||
|`LALT_T(kc)`|`ALT_T(kc)` |Left Alt when held, `kc` when tapped |
|
|
||||||
|`LGUI_T(kc)`|`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped |
|
|
||||||
|`RCTL_T(kc)`| |Right Control when held, `kc` when tapped |
|
|
||||||
|`RSFT_T(kc)`| |Right Shift when held, `kc` when tapped |
|
|
||||||
|`RALT_T(kc)`|`ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
|
|
||||||
|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped |
|
|
||||||
|`SGUI_T(kc)`|`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|
|
||||||
|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped |
|
|
||||||
|`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 |
|
|
||||||
|`C_S_T(kc)` | |Left Control and Shift when held, `kc` when tapped |
|
|
||||||
|`MEH_T(kc)` | |Left Control, Shift and Alt when held, `kc` when tapped|
|
|
||||||
|`HYPR_T(kc)`|`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/)|
|
|
||||||
|
|
||||||
## Caveats
|
|
||||||
|
|
||||||
Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
# One Shot Keys
|
|
||||||
|
|
||||||
One shot keys are keys that remain active until the next key is pressed, and then are released. This allows you to type keyboard combinations without pressing more than one key at a time. These keys are usually called "Sticky keys" or "Dead keys".
|
|
||||||
|
|
||||||
For example, if you define a key as `OSM(MOD_LSFT)`, you can type a capital A character by first pressing and releasing shift, and then pressing and releasing A. Your computer will see the shift key being held the moment shift is pressed, and it will see the shift key being released immediately after A is released.
|
|
||||||
|
|
||||||
One shot keys also work as normal modifiers. If you hold down a one shot key and type other keys, your one shot will be released immediately after you let go of the key.
|
|
||||||
|
|
||||||
Additionally, hitting keys five times in a short period will lock that key. This applies for both One Shot Modifiers and One Shot Layers, and is controlled by the `ONESHOT_TAP_TOGGLE` define.
|
|
||||||
|
|
||||||
You can control the behavior of one shot keys by defining these in `config.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */
|
|
||||||
#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */
|
|
||||||
```
|
|
||||||
|
|
||||||
* `OSM(mod)` - Momentarily hold down *mod*. You must use the `MOD_*` keycodes as shown in [Mod Tap](#mod-tap), not the `KC_*` codes.
|
|
||||||
* `OSL(layer)` - momentary switch to *layer*.
|
|
||||||
|
|
||||||
Sometimes, you want to activate a one-shot key as part of a macro or tap dance routine.
|
|
||||||
|
|
||||||
For one shot layers, you need to call `set_oneshot_layer(LAYER, ONESHOT_START)` on key down, and `set_oneshot_layer(ONESHOT_PRESSED)` on key up. If you want to cancel the oneshot, call `reset_oneshot_layer()`.
|
|
||||||
|
|
||||||
For one shot mods, you need to call `set_oneshot_mods(MOD)` to set it, or `clear_oneshot_mods()` to cancel it.
|
|
||||||
|
|
||||||
!> If you're having issues with OSM translating over Remote Desktop Connection, this can be fixed by opening the settings, going to the "Local Resources" tap, and in the keyboard section, change the drop down to "On this Computer". This will fix the issue and allow OSM to function properly over Remote Desktop.
|
|
||||||
|
|
||||||
## Callbacks
|
|
||||||
|
|
||||||
When you'd like to perform custom logic when pressing a one shot key, there are several callbacks you can choose to implement. You could indicate changes in one shot keys by flashing an LED or making a sound, for example.
|
|
||||||
|
|
||||||
There is a callback for `OSM(mod)`. It is called whenever the state of any one shot modifier key is changed: when it toggles on, but also when it is toggled off. You can use it like this:
|
|
||||||
|
|
||||||
```c
|
|
||||||
void oneshot_mods_changed_user(uint8_t mods) {
|
|
||||||
if (mods & MOD_MASK_SHIFT) {
|
|
||||||
println("Oneshot mods SHIFT");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_CTRL) {
|
|
||||||
println("Oneshot mods CTRL");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_ALT) {
|
|
||||||
println("Oneshot mods ALT");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_GUI) {
|
|
||||||
println("Oneshot mods GUI");
|
|
||||||
}
|
|
||||||
if (!mods) {
|
|
||||||
println("Oneshot mods off");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `mods` argument contains the active mods after the change, so it reflects the current state.
|
|
||||||
|
|
||||||
When you use One Shot Tap Toggle (by adding `#define ONESHOT_TAP_TOGGLE 2` in your `config.h` file), you may lock a modifier key by pressing it the specified amount of times. There's a callback for that, too:
|
|
||||||
|
|
||||||
```c
|
|
||||||
void oneshot_locked_mods_changed_user(uint8_t mods) {
|
|
||||||
if (mods & MOD_MASK_SHIFT) {
|
|
||||||
println("Oneshot locked mods SHIFT");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_CTRL) {
|
|
||||||
println("Oneshot locked mods CTRL");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_ALT) {
|
|
||||||
println("Oneshot locked mods ALT");
|
|
||||||
}
|
|
||||||
if (mods & MOD_MASK_GUI) {
|
|
||||||
println("Oneshot locked mods GUI");
|
|
||||||
}
|
|
||||||
if (!mods) {
|
|
||||||
println("Oneshot locked mods off");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Last, there is also a callback for the `OSL(layer)` one shot key:
|
|
||||||
|
|
||||||
```c
|
|
||||||
void oneshot_layer_changed_user(uint8_t layer) {
|
|
||||||
if (layer == 1) {
|
|
||||||
println("Oneshot layer 1 on");
|
|
||||||
}
|
|
||||||
if (!layer) {
|
|
||||||
println("Oneshot layer off");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If any one shot layer is switched off, `layer` will be zero. When you're looking to do something on any layer change instead of one shot layer changes, `layer_state_set_user` is a better callback to use.
|
|
||||||
|
|
||||||
If you are making your own keyboard, there are also `_kb` equivalent functions:
|
|
||||||
|
|
||||||
```c
|
|
||||||
void oneshot_locked_mods_changed_kb(uint8_t mods);
|
|
||||||
void oneshot_mods_changed_kb(uint8_t mods);
|
|
||||||
void oneshot_layer_changed_kb(uint8_t layer);
|
|
||||||
```
|
|
||||||
|
|
||||||
As with any callback, be sure to call the `_user` variant to allow for further customizability.
|
|
||||||
|
|
||||||
# Tap-Hold Configuration Options
|
|
||||||
|
|
||||||
While Tap-Hold options are fantastic, they are not without their issues. We have tried to configure them with reasonal defaults, but that may still cause issues for some people.
|
|
||||||
|
|
||||||
These options let you modify the behavior of the Tap-Hold keys.
|
|
||||||
|
|
||||||
## Permissive Hold
|
|
||||||
|
|
||||||
As of [PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/), there is a new `config.h` option:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define PERMISSIVE_HOLD
|
|
||||||
```
|
|
||||||
|
|
||||||
This makes tap and hold keys (like Mod Tap) work better for fast typist, or for high `TAPPING_TERM` settings.
|
|
||||||
|
|
||||||
If you press a Mod Tap key, tap another key (press and release) and then release the Mod Tap key, all within the tapping term, it will output the "tapping" function for both keys.
|
|
||||||
|
|
||||||
For Instance:
|
|
||||||
|
|
||||||
- `SFT_T(KC_A)` Down
|
|
||||||
- `KC_X` Down
|
|
||||||
- `KC_X` Up
|
|
||||||
- `SFT_T(KC_A)` Up
|
|
||||||
|
|
||||||
Normally, if you do all this within the `TAPPING_TERM` (default: 200ms) this will be registered as `ax` by the firmware and host system. With permissive hold enabled, this modifies how this is handled by considering the Mod Tap keys as a Mod if another key is tapped, and would registered as `X` (`SHIFT`+`x`).
|
|
||||||
|
|
||||||
?> If you have `Ignore Mod Tap Interrupt` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`.
|
|
||||||
|
|
||||||
## Ignore Mod Tap Interrupt
|
|
||||||
|
|
||||||
To enable this setting, add this to your `config.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define IGNORE_MOD_TAP_INTERRUPT
|
|
||||||
```
|
|
||||||
|
|
||||||
Similar to Permissive Hold, this alters how the firmware processes input for fast typist. If you press a Mod Tap key, press another key, release the Mod Tap key, and then release the normal key, it would normally output the "tapping" function for both keys. This may not be desirable for rolling combo keys.
|
|
||||||
|
|
||||||
Setting `Ignore Mod Tap Interrupt` requires holding both keys for the `TAPPING_TERM` to trigger the hold function (the mod).
|
|
||||||
|
|
||||||
For Instance:
|
|
||||||
|
|
||||||
- `SFT_T(KC_A)` Down
|
|
||||||
- `KC_X` Down
|
|
||||||
- `SFT_T(KC_A)` Up
|
|
||||||
- `KC_X` Up
|
|
||||||
|
|
||||||
Normally, this would send `X` (`SHIFT`+`x`). With `Ignore Mod Tap Interrupt` enabled, holding both keys are required for the `TAPPING_TERM` to register the hold action. A quick tap will output `ax` in this case, while a hold on both will still output `X` (`SHIFT`+`x`).
|
|
||||||
|
|
||||||
|
|
||||||
?> __Note__: This only concerns modifiers and not layer switching keys.
|
|
||||||
|
|
||||||
?> If you have `Permissive Hold` enabled, as well, this will modify how both work. The regular key has the modifier added if the first key is released first or if both keys are held longer than the `TAPPING_TERM`.
|
|
||||||
|
|
||||||
## Tapping Force Hold
|
|
||||||
|
|
||||||
To enable `tapping force hold`, add the following to your `config.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define TAPPING_FORCE_HOLD
|
|
||||||
```
|
|
||||||
|
|
||||||
When the user holds a key after tap, this repeats the tapped key rather to hold a modifier key. This allows to use auto repeat for the tapped key.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- SFT_T(KC_A) Down
|
|
||||||
- SFT_T(KC_A) Up
|
|
||||||
- SFT_T(KC_A) Down
|
|
||||||
- wait more than tapping term...
|
|
||||||
- SFT_T(KC_A) Up
|
|
||||||
|
|
||||||
With default settings, `a` will be sent on the first release, then `a` will be sent on the second press allowing the computer to trigger its auto repeat function.
|
|
||||||
|
|
||||||
With `TAPPING_FORCE_HOLD`, the second press will be interpreted as a Shift, allowing to use it as a modifier shortly after having used it as a tap.
|
|
||||||
|
|
||||||
!> `TAPPING_FORCE_HOLD` will break anything that uses tapping toggles (Such as the `TT` layer keycode, and the One Shot Tapping Toggle).
|
|
||||||
|
|
||||||
## Retro Tapping
|
|
||||||
|
|
||||||
To enable `retro tapping`, add the following to your `config.h`:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#define RETRO_TAPPING
|
|
||||||
```
|
|
||||||
|
|
||||||
Holding and releasing a dual function key without pressing another key will result in nothing happening. With retro tapping enabled, releasing the key without pressing another will send the original keycode even if it is outside the tapping term.
|
|
||||||
|
|
||||||
For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead.
|
|
||||||
+61
-15
@@ -6,16 +6,14 @@ QMK is able to control the brightness of these LEDs by switching them on and off
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Driver configuration
|
## Feature Configuration
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|
||||||
```makefile
|
```makefile
|
||||||
BACKLIGHT_ENABLE = software # Valid driver values are 'yes,software,no'
|
BACKLIGHT_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
See below for help on individual drivers.
|
|
||||||
|
|
||||||
## Keycodes
|
## Keycodes
|
||||||
Once enabled the following keycodes below can be used to change the backlight level.
|
Once enabled the following keycodes below can be used to change the backlight level.
|
||||||
|
|
||||||
@@ -51,6 +49,16 @@ Once enabled the following keycodes below can be used to change the backlight le
|
|||||||
|`breathing_enable()` |Turns on backlight breathing |
|
|`breathing_enable()` |Turns on backlight breathing |
|
||||||
|`breathing_disable()` |Turns off backlight breathing |
|
|`breathing_disable()` |Turns off backlight breathing |
|
||||||
|
|
||||||
|
## Driver Configuration
|
||||||
|
|
||||||
|
To select which driver to use, configure your `rules.mk` with the following:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
BACKLIGHT_DRIVER = software # Valid driver values are 'pwm,software,no'
|
||||||
|
```
|
||||||
|
|
||||||
|
See below for help on individual drivers.
|
||||||
|
|
||||||
## Common Driver Configuration
|
## Common Driver Configuration
|
||||||
|
|
||||||
To change the behavior of the backlighting, `#define` these in your `config.h`:
|
To change the behavior of the backlighting, `#define` these in your `config.h`:
|
||||||
@@ -72,9 +80,9 @@ This functionality is configured at the keyboard level with the `BACKLIGHT_ON_ST
|
|||||||
|
|
||||||
## AVR driver
|
## AVR driver
|
||||||
|
|
||||||
On AVR boards, the default driver currently sniffs the configuration to pick the best scenario. To enable it, add this to your rules.mk:
|
On AVR boards, the default driver currently sniffs the configuration to pick the best scenario. The driver is configured by default, however the equivalent setting within rules.mk would be:
|
||||||
```makefile
|
```makefile
|
||||||
BACKLIGHT_ENABLE = yes
|
BACKLIGHT_DRIVER = pwm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Caveats
|
### Caveats
|
||||||
@@ -111,10 +119,22 @@ When both timers are in use for Audio, the backlight PWM will not use a hardware
|
|||||||
|
|
||||||
To change the behavior of the backlighting, `#define` these in your `config.h`:
|
To change the behavior of the backlighting, `#define` these in your `config.h`:
|
||||||
|
|
||||||
|Define |Default |Description |
|
|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_PIN` |`B7` |The pin that controls the LEDs. Unless you are designing your own keyboard, you shouldn't need to change this|
|
||||||
|`BACKLIGHT_PINS` |*Not defined*|experimental: see below for more information |
|
|`BACKLIGHT_PINS` |*Not defined*|experimental: see below for more information |
|
||||||
|
|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) |
|
||||||
|
|`BACKLIGHT_CAPS_LOCK`|*Not defined*|Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) |
|
||||||
|
|`BACKLIGHT_BREATHING`|*Not defined*|Enable backlight breathing, if supported |
|
||||||
|
|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds |
|
||||||
|
|`BACKLIGHT_ON_STATE` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low |
|
||||||
|
|
||||||
|
### Backlight On State
|
||||||
|
|
||||||
|
Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*.
|
||||||
|
Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead.
|
||||||
|
|
||||||
|
This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define.
|
||||||
|
|
||||||
### Multiple backlight pins
|
### Multiple backlight pins
|
||||||
|
|
||||||
@@ -150,16 +170,16 @@ The breathing effect is the same as in the hardware PWM implementation.
|
|||||||
|
|
||||||
## ARM Driver
|
## ARM Driver
|
||||||
|
|
||||||
While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. To enable it, add this to your rules.mk:
|
While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The driver is configured by default, however the equivalent setting within rules.mk would be:
|
||||||
```makefile
|
```makefile
|
||||||
BACKLIGHT_ENABLE = yes
|
BACKLIGHT_DRIVER = pwm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Caveats
|
### Caveats
|
||||||
|
|
||||||
Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
|
Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration.
|
||||||
|
|
||||||
?> STMF072 support is being investigated.
|
?> Backlight support for STMF072 has had limited testing, YMMV. If unsure, set `BACKLIGHT_ENABLE = no` in your rules.mk.
|
||||||
|
|
||||||
### ARM Configuration
|
### ARM Configuration
|
||||||
|
|
||||||
@@ -172,11 +192,11 @@ To change the behavior of the backlighting, `#define` these in your `config.h`:
|
|||||||
|`BACKLIGHT_PWM_CHANNEL` |`3` |The PWM channel to use, see ST datasheets for pin to PWM channel mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
|
|`BACKLIGHT_PWM_CHANNEL` |`3` |The PWM channel to use, see ST datasheets for pin to PWM channel mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
|
||||||
|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use, see ST datasheets for pin AF mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
|
|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use, see ST datasheets for pin AF mapping. Unless you are designing your own keyboard, you shouldn't need to change this|
|
||||||
|
|
||||||
## Software PWM Driver
|
## Software PWM Driver :id=software-pwm-driver
|
||||||
|
|
||||||
Emulation of PWM while running other keyboard tasks, it offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your rules.mk:
|
Emulation of PWM while running other keyboard tasks, it offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your rules.mk:
|
||||||
```makefile
|
```makefile
|
||||||
BACKLIGHT_ENABLE = software
|
BACKLIGHT_DRIVER = software
|
||||||
```
|
```
|
||||||
|
|
||||||
### Software PWM Configuration
|
### Software PWM Configuration
|
||||||
@@ -200,3 +220,29 @@ To activate multiple backlight pins, you need to add something like this to your
|
|||||||
#undef BACKLIGHT_PIN
|
#undef BACKLIGHT_PIN
|
||||||
#define BACKLIGHT_PINS { F5, B2 }
|
#define BACKLIGHT_PINS { F5, B2 }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Custom Driver
|
||||||
|
|
||||||
|
To enable, add this to your rules.mk:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
BACKLIGHT_DRIVER = custom
|
||||||
|
```
|
||||||
|
|
||||||
|
When implementing the custom driver API, the provided keyboard hooks are as follows:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void backlight_init_ports(void) {
|
||||||
|
// Optional - Run on startup
|
||||||
|
// - usually you want to configure pins here
|
||||||
|
}
|
||||||
|
void backlight_set(uint8_t level) {
|
||||||
|
// Optional - Run on level change
|
||||||
|
// - usually you want to respond to the new value
|
||||||
|
}
|
||||||
|
|
||||||
|
void backlight_task(void) {
|
||||||
|
// Optional - Run periodically
|
||||||
|
// - long running actions here can cause performance issues
|
||||||
|
}
|
||||||
|
```
|
||||||
+33
-33
@@ -54,39 +54,39 @@ Hold down the Bootmagic key (Space by default) and the desired hotkey while plug
|
|||||||
|`6` |Make layer 6 the default layer |
|
|`6` |Make layer 6 the default layer |
|
||||||
|`7` |Make layer 7 the default layer |
|
|`7` |Make layer 7 the default layer |
|
||||||
|
|
||||||
## Keycodes
|
## Keycodes :id=keycodes
|
||||||
|
|
||||||
|Keycode |Aliases |Description |
|
|Key |Aliases |Description |
|
||||||
|----------------------------------|---------|------------------------------------------|
|
|----------------------------------|---------|--------------------------------------------------------------------------|
|
||||||
|`MAGIC_CAPSLOCK_TO_CONTROL` | |Treat Caps Lock as Left Control |
|
|`MAGIC_SWAP_CONTROL_CAPSLOCK` |`CL_SWAP`|Swap Caps Lock and Left Control |
|
||||||
|`MAGIC_UNCAPSLOCK_TO_CONTROL` | |Stop treating Caps Lock as Left Control |
|
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` |`CL_NORM`|Unswap Caps Lock and Left Control |
|
||||||
|`MAGIC_HOST_NKRO` | |Force N-Key Rollover (NKRO) on |
|
|`MAGIC_CAPSLOCK_TO_CONTROL` |`CL_CTRL`|Treat Caps Lock as Control |
|
||||||
|`MAGIC_UNHOST_NKRO` | |Force NKRO off |
|
|`MAGIC_UNCAPSLOCK_TO_CONTROL` |`CL_CAPS`|Stop treating Caps Lock as Control |
|
||||||
|`MAGIC_TOGGLE_NKRO` | |Turn NKRO on or off |
|
|`MAGIC_SWAP_LCTL_LGUI` |`LCG_SWP`|Swap Left Control and GUI |
|
||||||
|`MAGIC_NO_GUI` | |Disable the GUI keys (useful when gaming) |
|
|`MAGIC_UNSWAP_LCTL_LGUI` |`LCG_NRM`|Unswap Left Control and GUI |
|
||||||
|`MAGIC_UNNO_GUI` | |Enable the GUI keys |
|
|`MAGIC_SWAP_RCTL_RGUI` |`RCG_SWP`|Swap Right Control and GUI |
|
||||||
|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides (for macOS)|
|
|`MAGIC_UNSWAP_RCTL_RGUI` |`RCG_NRM`|Unswap Right Control and GUI |
|
||||||
|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI |
|
|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Control and GUI on both sides |
|
||||||
|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap |
|
|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Control and GUI on both sides |
|
||||||
|`MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Ctrl and GUI on both sides (for macOS)|
|
|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Control and GUI swap on both sides |
|
||||||
|`MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Ctrl and GUI |
|
|`MAGIC_SWAP_LALT_LGUI` |`LAG_SWP`|Swap Left Alt and GUI |
|
||||||
|`MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Ctrl and GUI swap |
|
|`MAGIC_UNSWAP_LALT_LGUI` |`LAG_NRM`|Unswap Left Alt and GUI |
|
||||||
|`MAGIC_SWAP_BACKSLASH_BACKSPACE` | |Swap `\` and Backspace |
|
|`MAGIC_SWAP_RALT_RGUI` |`RAG_SWP`|Swap Right Alt and GUI |
|
||||||
|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`| |Unswap `\` and Backspace |
|
|`MAGIC_UNSWAP_RALT_RGUI` |`RAG_NRM`|Unswap Right Alt and GUI |
|
||||||
|`MAGIC_SWAP_CONTROL_CAPSLOCK` | |Swap Left Control and Caps Lock |
|
|`MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides |
|
||||||
|`MAGIC_UNSWAP_CONTROL_CAPSLOCK` | |Unswap Left Control and Caps Lock |
|
|`MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides |
|
||||||
|`MAGIC_SWAP_GRAVE_ESC` | |Swap <code>`</code> and Escape |
|
|`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides |
|
||||||
|`MAGIC_UNSWAP_GRAVE_ESC` | |Unswap <code>`</code> and Escape |
|
|`MAGIC_NO_GUI` |`GUI_OFF`|Disable the GUI keys |
|
||||||
|`MAGIC_SWAP_LALT_LGUI` | |Swap Left Alt and Left GUI |
|
|`MAGIC_UNNO_GUI` |`GUI_ON` |Enable the GUI keys |
|
||||||
|`MAGIC_UNSWAP_LALT_LGUI` | |Unswap Left Alt and Left GUI |
|
|`MAGIC_SWAP_GRAVE_ESC` |`GE_SWAP`|Swap <code>`</code> and Escape |
|
||||||
|`MAGIC_SWAP_RALT_RGUI` | |Swap Right Alt and Right GUI |
|
|`MAGIC_UNSWAP_GRAVE_ESC` |`GE_NORM`|Unswap <code>`</code> and Escape |
|
||||||
|`MAGIC_UNSWAP_RALT_RGUI` | |Unswap Right Alt and Right GUI |
|
|`MAGIC_SWAP_BACKSLASH_BACKSPACE` |`BS_SWAP`|Swap `\` and Backspace |
|
||||||
|`MAGIC_SWAP_LCTL_LGUI` | |Swap Left Control and Left GUI |
|
|`MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|`BS_NORM`|Unswap `\` and Backspace |
|
||||||
|`MAGIC_UNSWAP_LCTL_LGUI` | |Unswap Left Control and Left GUI |
|
|`MAGIC_HOST_NKRO` |`NK_ON` |Enable N-key rollover |
|
||||||
|`MAGIC_SWAP_RCTL_RGUI` | |Swap Right Control and Right GUI |
|
|`MAGIC_UNHOST_NKRO` |`NK_OFF` |Disable N-key rollover |
|
||||||
|`MAGIC_UNSWAP_RCTL_RGUI` | |Unswap Right Control and Right GUI |
|
|`MAGIC_TOGGLE_NKRO` |`NK_TOGG`|Toggle N-key rollover |
|
||||||
|`MAGIC_EE_HANDS_LEFT` | |Set "Left Hand" for EE_HANDS handedness |
|
|`MAGIC_EE_HANDS_LEFT` |`EH_LEFT`|Set the master half of a split keyboard as the left hand (for `EE_HANDS`) |
|
||||||
|`MAGIC_EE_HANDS_RIGHT` | |Set "Right Hand" for EE_HANDS handedness |
|
|`MAGIC_EE_HANDS_RIGHT` |`EH_RGHT`|Set the master half of a split keyboard as the right hand (for `EE_HANDS`)|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ If you would like to change the hotkey assignments for Bootmagic, `#define` thes
|
|||||||
|`BOOTMAGIC_KEY_DEFAULT_LAYER_6` |`KC_6` |Make layer 6 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_KEY_DEFAULT_LAYER_7` |`KC_7` |Make layer 7 the default layer |
|
||||||
|
|
||||||
# Bootmagic Lite
|
# Bootmagic Lite :id=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.
|
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.
|
||||||
|
|
||||||
|
|||||||
+34
-18
@@ -2,23 +2,35 @@
|
|||||||
|
|
||||||
Basic encoders are supported by adding this to your `rules.mk`:
|
Basic encoders are supported by adding this to your `rules.mk`:
|
||||||
|
|
||||||
ENCODER_ENABLE = yes
|
```make
|
||||||
|
ENCODER_ENABLE = yes
|
||||||
|
```
|
||||||
|
|
||||||
and this to your `config.h`:
|
and this to your `config.h`:
|
||||||
|
|
||||||
#define ENCODERS_PAD_A { B12 }
|
```c
|
||||||
#define ENCODERS_PAD_B { B13 }
|
#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.:
|
Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.:
|
||||||
|
|
||||||
#define ENCODERS_PAD_A { encoder1a, encoder2a }
|
```c
|
||||||
#define ENCODERS_PAD_B { encoder1b, encoder2b }
|
#define ENCODERS_PAD_A { encoder1a, encoder2a }
|
||||||
|
#define ENCODERS_PAD_B { encoder1b, encoder2b }
|
||||||
|
```
|
||||||
|
|
||||||
If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions.
|
If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions. They can also be flipped with a define:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define ENCODER_DIRECTION_FLIP
|
||||||
|
```
|
||||||
|
|
||||||
Additionally, the resolution can be specified in the same file (the default & suggested is 4):
|
Additionally, the resolution can be specified in the same file (the default & suggested is 4):
|
||||||
|
|
||||||
#define ENCODER_RESOLUTION 4
|
```c
|
||||||
|
#define ENCODER_RESOLUTION 4
|
||||||
|
```
|
||||||
|
|
||||||
## Split Keyboards
|
## Split Keyboards
|
||||||
|
|
||||||
@@ -33,27 +45,31 @@ If you are using different pinouts for the encoders on each half of a split keyb
|
|||||||
|
|
||||||
The callback functions can be inserted into your `<keyboard>.c`:
|
The callback functions can be inserted into your `<keyboard>.c`:
|
||||||
|
|
||||||
void encoder_update_kb(uint8_t index, bool clockwise) {
|
```c
|
||||||
encoder_update_user(index, clockwise);
|
void encoder_update_kb(uint8_t index, bool clockwise) {
|
||||||
}
|
encoder_update_user(index, clockwise);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
or `keymap.c`:
|
or `keymap.c`:
|
||||||
|
|
||||||
void encoder_update_user(uint8_t index, bool clockwise) {
|
```c
|
||||||
if (index == 0) { /* First encoder */
|
void encoder_update_user(uint8_t index, bool clockwise) {
|
||||||
|
if (index == 0) { /* First encoder */
|
||||||
if (clockwise) {
|
if (clockwise) {
|
||||||
tap_code(KC_PGDN);
|
tap_code(KC_PGDN);
|
||||||
} else {
|
} else {
|
||||||
tap_code(KC_PGUP);
|
tap_code(KC_PGUP);
|
||||||
}
|
}
|
||||||
} else if (index == 1) { /* Second encoder */
|
} else if (index == 1) { /* Second encoder */
|
||||||
if (clockwise) {
|
if (clockwise) {
|
||||||
tap_code(KC_UP);
|
tap_code(KC_DOWN);
|
||||||
} else {
|
} else {
|
||||||
tap_code(KC_DOWN);
|
tap_code(KC_UP);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Haptic feedback rules.mk options
|
## Haptic feedback rules.mk options
|
||||||
|
|
||||||
The following options are currently available for haptic feedback in `rule.mk`:
|
The following options are currently available for haptic feedback in `rules.mk`:
|
||||||
|
|
||||||
`HAPTIC_ENABLE += DRV2605L`
|
`HAPTIC_ENABLE += DRV2605L`
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Th
|
|||||||
|
|
||||||
## Caveats
|
## Caveats
|
||||||
|
|
||||||
Key Lock is only able to hold standard action keys and [One Shot modifier](feature_advanced_keycodes.md#one-shot-keys) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`).
|
Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(KC_LSFT)`).
|
||||||
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held.
|
This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held.
|
||||||
|
|
||||||
Switching layers will not cancel the Key Lock.
|
Switching layers will not cancel the Key Lock.
|
||||||
@@ -22,10 +22,10 @@ void matrix_scan_user(void) {
|
|||||||
SEND_STRING("QMK is awesome.");
|
SEND_STRING("QMK is awesome.");
|
||||||
}
|
}
|
||||||
SEQ_TWO_KEYS(KC_D, KC_D) {
|
SEQ_TWO_KEYS(KC_D, KC_D) {
|
||||||
SEND_STRING(SS_LCTRL("a")SS_LCTRL("c"));
|
SEND_STRING(SS_LCTL("a") SS_LCTL("c"));
|
||||||
}
|
}
|
||||||
SEQ_THREE_KEYS(KC_D, KC_D, KC_S) {
|
SEQ_THREE_KEYS(KC_D, KC_D, KC_S) {
|
||||||
SEND_STRING("https://start.duckduckgo.com"SS_TAP(X_ENTER));
|
SEND_STRING("https://start.duckduckgo.com\n");
|
||||||
}
|
}
|
||||||
SEQ_TWO_KEYS(KC_A, KC_S) {
|
SEQ_TWO_KEYS(KC_A, KC_S) {
|
||||||
register_code(KC_LGUI);
|
register_code(KC_LGUI);
|
||||||
@@ -74,7 +74,7 @@ SEQ_THREE_KEYS(KC_C, KC_C, KC_C) {
|
|||||||
|
|
||||||
## Strict Key Processing
|
## Strict Key Processing
|
||||||
|
|
||||||
By default, the Leader Key feature will filter the keycode out of [`Mod-Tap`](feature_advanced_keycodes.md#mod-tap) and [`Layer Tap`](feature_advanced_keycodes.md#switching-and-toggling-layers) functions when checking for the Leader sequences. That means if you're using `LT(3, KC_A)`, it will pick this up as `KC_A` for the sequence, rather than `LT(3, KC_A)`, giving a more expected behavior for newer users.
|
By default, the Leader Key feature will filter the keycode out of [`Mod-Tap`](mod_tap.md) and [`Layer Tap`](feature_advanced_keycodes.md#switching-and-toggling-layers) functions when checking for the Leader sequences. That means if you're using `LT(3, KC_A)`, it will pick this up as `KC_A` for the sequence, rather than `LT(3, KC_A)`, giving a more expected behavior for newer users.
|
||||||
|
|
||||||
While, this may be fine for most, if you want to specify the whole keycode (eg, `LT(3, KC_A)` from the example above) in the sequence, you can enable this by added `#define LEADER_KEY_STRICT_KEY_PROCESSING` to your `config.h` file. This well then disable the filtering, and you'll need to specify the whole keycode.
|
While, this may be fine for most, if you want to specify the whole keycode (eg, `LT(3, KC_A)` from the example above) in the sequence, you can enable this by added `#define LEADER_KEY_STRICT_KEY_PROCESSING` to your `config.h` file. This well then disable the filtering, and you'll need to specify the whole keycode.
|
||||||
|
|
||||||
@@ -115,11 +115,11 @@ void matrix_scan_user(void) {
|
|||||||
|
|
||||||
SEQ_ONE_KEY(KC_E) {
|
SEQ_ONE_KEY(KC_E) {
|
||||||
// Anything you can do in a macro.
|
// Anything you can do in a macro.
|
||||||
SEND_STRING(SS_LCTRL(SS_LSFT("t")));
|
SEND_STRING(SS_LCTL(SS_LSFT("t")));
|
||||||
did_leader_succeed = true;
|
did_leader_succeed = true;
|
||||||
} else
|
} else
|
||||||
SEQ_TWO_KEYS(KC_E, KC_D) {
|
SEQ_TWO_KEYS(KC_E, KC_D) {
|
||||||
SEND_STRING(SS_LGUI("r")"cmd"SS_TAP(KC_ENTER)SS_LCTRL("c"));
|
SEND_STRING(SS_LGUI("r") "cmd\n" SS_LCTL("c"));
|
||||||
did_leader_succeed = true;
|
did_leader_succeed = true;
|
||||||
}
|
}
|
||||||
leader_end();
|
leader_end();
|
||||||
|
|||||||
+28
-13
@@ -67,14 +67,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
case QMKURL:
|
case QMKURL:
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
// when keycode QMKURL is pressed
|
// when keycode QMKURL is pressed
|
||||||
SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER));
|
SEND_STRING("https://qmk.fm/\n");
|
||||||
} else {
|
} else {
|
||||||
// when keycode QMKURL is released
|
// when keycode QMKURL is released
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MY_OTHER_MACRO:
|
case MY_OTHER_MACRO:
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
SEND_STRING(SS_LCTRL("ac")); // selects all and copies
|
SEND_STRING(SS_LCTL("ac")); // selects all and copies
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -107,20 +107,33 @@ Would tap `KC_HOME` - note how the prefix is now `X_`, and not `KC_`. You can al
|
|||||||
|
|
||||||
Which would send "VE" followed by a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline).
|
Which would send "VE" followed by a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline).
|
||||||
|
|
||||||
|
Delays can be also added to the string:
|
||||||
|
|
||||||
|
* `SS_DELAY(msecs)` will delay for the specified number of milliseconds.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO");
|
||||||
|
|
||||||
|
Which would send "VE" followed by a 1-second delay, then a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline, but delayed in the middle).
|
||||||
|
|
||||||
There's also a couple of mod shortcuts you can use:
|
There's also a couple of mod shortcuts you can use:
|
||||||
|
|
||||||
* `SS_LCTRL(string)`
|
* `SS_LCTL(string)`
|
||||||
* `SS_LGUI(string)`
|
|
||||||
* `SS_LALT(string)`
|
|
||||||
* `SS_LSFT(string)`
|
* `SS_LSFT(string)`
|
||||||
* `SS_RALT(string)`
|
* `SS_LALT(string)`
|
||||||
|
* `SS_LGUI(string)`, `SS_LCMD(string)` or `SS_LWIN(string)`
|
||||||
|
* `SS_RCTL(string)`
|
||||||
|
* `SS_RSFT(string)`
|
||||||
|
* `SS_RALT(string)` or `SS_ALGR(string)`
|
||||||
|
* `SS_RGUI(string)`, `SS_RCMD(string)` or `SS_RWIN(string)`
|
||||||
|
|
||||||
These press the respective modifier, send the supplied string and then release the modifier.
|
These press the respective modifier, send the supplied string and then release the modifier.
|
||||||
They can be used like this:
|
They can be used like this:
|
||||||
|
|
||||||
SEND_STRING(SS_LCTRL("a"));
|
SEND_STRING(SS_LCTL("a"));
|
||||||
|
|
||||||
Which would send LCTRL+a (LCTRL down, a, LCTRL up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes.
|
Which would send Left Control+`a` (Left Control down, `a`, Left Control up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes.
|
||||||
|
|
||||||
### Alternative Keymaps
|
### Alternative Keymaps
|
||||||
|
|
||||||
@@ -151,6 +164,8 @@ SEND_STRING(".."SS_TAP(X_END));
|
|||||||
|
|
||||||
There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
|
There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple.
|
||||||
|
|
||||||
|
?> You can also use the functions described in [Useful function](ref_functions.md) for additional functionality. For example `reset_keyboard()` allows you to reset the keyboard as part of a macro.
|
||||||
|
|
||||||
### `record->event.pressed`
|
### `record->event.pressed`
|
||||||
|
|
||||||
This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
|
This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is
|
||||||
@@ -195,11 +210,11 @@ This will clear all mods currently pressed.
|
|||||||
|
|
||||||
This will clear all keys besides the mods currently pressed.
|
This will clear all keys besides the mods currently pressed.
|
||||||
|
|
||||||
## Advanced Example:
|
## Advanced Example:
|
||||||
|
|
||||||
### Super ALT↯TAB
|
### Super ALT↯TAB
|
||||||
|
|
||||||
This macro will register `KC_LALT` and tap `KC_TAB`, then wait for 1000ms. If the key is tapped again, it will send another `KC_TAB`; if there is no tap, `KC_LALT` will be unregistered, thus allowing you to cycle through windows.
|
This macro will register `KC_LALT` and tap `KC_TAB`, then wait for 1000ms. If the key is tapped again, it will send another `KC_TAB`; if there is no tap, `KC_LALT` will be unregistered, thus allowing you to cycle through windows.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
bool is_alt_tab_active = false; # ADD this near the begining of keymap.c
|
bool is_alt_tab_active = false; # ADD this near the begining of keymap.c
|
||||||
@@ -216,7 +231,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
if (!is_alt_tab_active) {
|
if (!is_alt_tab_active) {
|
||||||
is_alt_tab_active = true;
|
is_alt_tab_active = true;
|
||||||
register_code(KC_LALT);
|
register_code(KC_LALT);
|
||||||
}
|
}
|
||||||
alt_tab_timer = timer_read();
|
alt_tab_timer = timer_read();
|
||||||
register_code(KC_TAB);
|
register_code(KC_TAB);
|
||||||
} else {
|
} else {
|
||||||
@@ -227,7 +242,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrix_scan_user(void) { # The very important timer.
|
void matrix_scan_user(void) { # The very important timer.
|
||||||
if (is_alt_tab_active) {
|
if (is_alt_tab_active) {
|
||||||
if (timer_elapsed(alt_tab_timer) > 1000) {
|
if (timer_elapsed(alt_tab_timer) > 1000) {
|
||||||
unregister_code(KC_LALT);
|
unregister_code(KC_LALT);
|
||||||
@@ -316,7 +331,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Advanced Example:
|
## Advanced Example:
|
||||||
|
|
||||||
### Single-Key Copy/Paste
|
### Single-Key Copy/Paste
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ This is the default mode. You can adjust the cursor and scrolling acceleration u
|
|||||||
|`MOUSEKEY_INTERVAL` |50 |Time between cursor movements |
|
|`MOUSEKEY_INTERVAL` |50 |Time between cursor movements |
|
||||||
|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops |
|
|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops |
|
||||||
|`MOUSEKEY_TIME_TO_MAX` |20 |Time until maximum cursor speed is reached |
|
|`MOUSEKEY_TIME_TO_MAX` |20 |Time until maximum cursor speed is reached |
|
||||||
|
|`MOUSEKEY_WHEEL_DELAY` |300 |Delay between pressing a wheel key and wheel movement |
|
||||||
|
|`MOUSEKEY_WHEEL_INTERVAL` |100 |Time between wheel movements |
|
||||||
|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action |
|
|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action |
|
||||||
|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached |
|
|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached |
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ Tips:
|
|||||||
* Setting `MOUSEKEY_DELAY` too low makes the cursor unresponsive. Setting it too high makes small movements difficult.
|
* Setting `MOUSEKEY_DELAY` too low makes the cursor unresponsive. Setting it too high makes small movements difficult.
|
||||||
* For smoother cursor movements, lower the value of `MOUSEKEY_INTERVAL`. If the refresh rate of your display is 60Hz, you could set it to `16` (1/60). As this raises the cursor speed significantly, you may want to lower `MOUSEKEY_MAX_SPEED`.
|
* For smoother cursor movements, lower the value of `MOUSEKEY_INTERVAL`. If the refresh rate of your display is 60Hz, you could set it to `16` (1/60). As this raises the cursor speed significantly, you may want to lower `MOUSEKEY_MAX_SPEED`.
|
||||||
* Setting `MOUSEKEY_TIME_TO_MAX` or `MOUSEKEY_WHEEL_TIME_TO_MAX` to `0` will disable acceleration for the cursor or scrolling respectively. This way you can make one of them constant while keeping the other accelerated, which is not possible in constant speed mode.
|
* Setting `MOUSEKEY_TIME_TO_MAX` or `MOUSEKEY_WHEEL_TIME_TO_MAX` to `0` will disable acceleration for the cursor or scrolling respectively. This way you can make one of them constant while keeping the other accelerated, which is not possible in constant speed mode.
|
||||||
|
* Setting `MOUSEKEY_WHEEL_INTERVAL` too low will make scrolling too fast. Setting it too high will make scrolling too slow when the wheel key is held down.
|
||||||
|
|
||||||
Cursor acceleration uses the same algorithm as the X Window System MouseKeysAccel feature. You can read more about it [on Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys).
|
Cursor acceleration uses the same algorithm as the X Window System MouseKeysAccel feature. You can read more about it [on Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys).
|
||||||
|
|
||||||
|
|||||||
+135
-111
@@ -1,139 +1,142 @@
|
|||||||
# OLED Driver
|
# OLED Driver
|
||||||
|
|
||||||
## OLED Supported Hardware
|
## Supported Hardware
|
||||||
|
|
||||||
OLED modules using SSD1306 or SH1106 driver ICs, communicating over I2C.
|
OLED modules using SSD1306 or SH1106 driver ICs, communicating over I2C.
|
||||||
Tested combinations:
|
Tested combinations:
|
||||||
|
|
||||||
| IC driver | Size | Keyboard Platform | Notes |
|
|IC |Size |Platform|Notes |
|
||||||
|-----------|--------|-------------------|--------------------------|
|
|---------|------|--------|------------------------|
|
||||||
| SSD1306 | 128x32 | AVR | Primary support |
|
|SSD1306 |128x32|AVR |Primary support |
|
||||||
| SSD1306 | 128x64 | AVR | Verified working |
|
|SSD1306 |128x64|AVR |Verified working |
|
||||||
| SSD1306 | 128x32 | ARM | |
|
|SSD1306 |128x32|Arm | |
|
||||||
| SH1106 | 128x64 | AVR | No rotation or scrolling |
|
|SH1106 |128x64|AVR |No rotation or scrolling|
|
||||||
|
|
||||||
Hardware configurations using ARM-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
|
Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested.
|
||||||
|
|
||||||
!> Warning: This OLED Driver currently uses the new i2c_master driver from split common code. If your split keyboard uses I2C to communicate between sides, this driver could cause an address conflict (serial is fine). Please contact your keyboard vendor and ask them to migrate to the latest split common code to fix this. In addition, the display timeout system to reduce OLED burn-in also uses split common to detect keypresses, so you will need to implement custom timeout logic for non-split common keyboards.
|
!> Warning: This OLED driver currently uses the new i2c_master driver from Split Common code. If your split keyboard uses I2C to communicate between sides, this driver could cause an address conflict (serial is fine). Please contact your keyboard vendor and ask them to migrate to the latest Split Common code to fix this. In addition, the display timeout system to reduce OLED burn-in also uses Split Common to detect keypresses, so you will need to implement custom timeout logic for non-Split Common keyboards.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
To enable the OLED feature, there are three steps. First, when compiling your keyboard, you'll need to set `OLED_DRIVER_ENABLE=yes` in `rules.mk`, e.g.:
|
To enable the OLED feature, there are three steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
|
||||||
|
|
||||||
```
|
```make
|
||||||
OLED_DRIVER_ENABLE = yes
|
OLED_DRIVER_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
This enables the feature and the `OLED_DRIVER_ENABLE` define. Then in your `keymap.c` file, you will need to implement the user task call, e.g:
|
Then in your `keymap.c` file, implement the OLED task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`:
|
||||||
|
|
||||||
```C++
|
```c
|
||||||
#ifdef OLED_DRIVER_ENABLE
|
#ifdef OLED_DRIVER_ENABLE
|
||||||
void oled_task_user(void) {
|
void oled_task_user(void) {
|
||||||
// Host Keyboard Layer Status
|
// Host Keyboard Layer Status
|
||||||
oled_write_P(PSTR("Layer: "), false);
|
oled_write_P(PSTR("Layer: "), false);
|
||||||
switch (get_highest_layer(layer_state)) {
|
|
||||||
case _QWERTY:
|
|
||||||
oled_write_P(PSTR("Default\n"), false);
|
|
||||||
break;
|
|
||||||
case _FN:
|
|
||||||
oled_write_P(PSTR("FN\n"), false);
|
|
||||||
break;
|
|
||||||
case _ADJ:
|
|
||||||
oled_write_P(PSTR("ADJ\n"), false);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Or use the write_ln shortcut over adding '\n' to the end of your string
|
|
||||||
oled_write_ln_P(PSTR("Undefined"), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Host Keyboard LED Status
|
switch (get_highest_layer(layer_state)) {
|
||||||
uint8_t led_usb_state = host_keyboard_leds();
|
case _QWERTY:
|
||||||
oled_write_P(led_usb_state & (1<<USB_LED_NUM_LOCK) ? PSTR("NUMLCK ") : PSTR(" "), false);
|
oled_write_P(PSTR("Default\n"), false);
|
||||||
oled_write_P(led_usb_state & (1<<USB_LED_CAPS_LOCK) ? PSTR("CAPLCK ") : PSTR(" "), false);
|
break;
|
||||||
oled_write_P(led_usb_state & (1<<USB_LED_SCROLL_LOCK) ? PSTR("SCRLCK ") : PSTR(" "), false);
|
case _FN:
|
||||||
|
oled_write_P(PSTR("FN\n"), false);
|
||||||
|
break;
|
||||||
|
case _ADJ:
|
||||||
|
oled_write_P(PSTR("ADJ\n"), false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Or use the write_ln shortcut over adding '\n' to the end of your string
|
||||||
|
oled_write_ln_P(PSTR("Undefined"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Host Keyboard LED Status
|
||||||
|
led_t led_state = host_keyboard_led_state();
|
||||||
|
oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
|
||||||
|
oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
|
||||||
|
oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
## Logo Example
|
## Logo Example
|
||||||
|
|
||||||
In the default font, ranges in the font file are reserved for a QMK Logo. To Render this logo to the oled screen, use the following code example:
|
In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the OLED screen, use the following code example:
|
||||||
|
|
||||||
```C++
|
```c
|
||||||
static void render_logo(void) {
|
static void render_logo(void) {
|
||||||
static const char PROGMEM qmk_logo[] = {
|
static const char PROGMEM qmk_logo[] = {
|
||||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94,
|
||||||
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
|
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4,
|
||||||
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0};
|
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
oled_write_P(qmk_logo, false);
|
oled_write_P(qmk_logo, false);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Other Examples
|
## Other Examples
|
||||||
|
|
||||||
In split keyboards, it is very common to have two OLED displays that each render different content and oriented flipped differently. You can do this by switching which content to render by using the return from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g:
|
In split keyboards, it is very common to have two OLED displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g:
|
||||||
|
|
||||||
```C++
|
```c
|
||||||
#ifdef OLED_DRIVER_ENABLE
|
#ifdef OLED_DRIVER_ENABLE
|
||||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
|
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
|
||||||
if (!is_keyboard_master())
|
if (!is_keyboard_master()) {
|
||||||
return OLED_ROTATION_180; // flips the display 180 degrees if offhand
|
return OLED_ROTATION_180; // flips the display 180 degrees if offhand
|
||||||
return rotation;
|
}
|
||||||
|
|
||||||
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void oled_task_user(void) {
|
void oled_task_user(void) {
|
||||||
if (is_keyboard_master()) {
|
if (is_keyboard_master()) {
|
||||||
render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
|
render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
|
||||||
} else {
|
} else {
|
||||||
render_logo(); // Renders a statuc logo
|
render_logo(); // Renders a static logo
|
||||||
oled_scroll_left(); // Turns on scrolling
|
oled_scroll_left(); // Turns on scrolling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Basic Configuration
|
||||||
|
|
||||||
## Basic Configuration
|
|Define |Default |Description |
|
||||||
|
|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Define | Default | Description |
|
|`OLED_DISPLAY_ADDRESS` |`0x3C` |The i2c address of the OLED Display |
|
||||||
|----------------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------|
|
|`OLED_FONT_H` |`"glcdfont.c"` |The font code file to use for custom fonts |
|
||||||
| `OLED_DISPLAY_ADDRESS` | `0x3C` | The i2c address of the OLED Display |
|
|`OLED_FONT_START` |`0` |The starting characer index for custom fonts |
|
||||||
| `OLED_FONT_H` | `"glcdfont.c"` | The font code file to use for custom fonts |
|
|`OLED_FONT_END` |`223` |The ending characer index for custom fonts |
|
||||||
| `OLED_FONT_START` | `0` | The starting characer index for custom fonts |
|
|`OLED_FONT_WIDTH` |`6` |The font width |
|
||||||
| `OLED_FONT_END` | `224` | The ending characer index for custom fonts |
|
|`OLED_FONT_HEIGHT` |`8` |The font height (untested) |
|
||||||
| `OLED_FONT_WIDTH` | `6` | The font width |
|
|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of keyboard inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||||
| `OLED_FONT_HEIGHT` | `8` | The font height (untested) |
|
|`OLED_SCROLL_TIMEOUT` |`0` |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
||||||
| `OLED_TIMEOUT` | `60000` | Turns off the OLED screen after 60000ms of keyboard inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. |
|
||||||
| `OLED_SCROLL_TIMEOUT` | `0` | Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. |
|
|`OLED_IC` |`OLED_IC_SSD1306`|Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller. |
|
||||||
| `OLED_SCROLL_TIMEOUT_RIGHT`| *Not defined* | Scroll timeout direction is right when defined, left when undefined. |
|
|`OLED_COLUMN_OFFSET` |`0` |(SH1106 only.) Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC.|
|
||||||
| `OLED_IC` | `OLED_IC_SSD1306` | Set to `OLED_IC_SH1106` if you're using the SH1106 OLED controller. |
|
|
||||||
| `OLED_COLUMN_OFFSET` | `0` | (SH1106 only.) Shift output to the right this many pixels.<br />Useful for 128x64 displays centered on a 132x64 SH1106 IC. |
|
|
||||||
|
|
||||||
## 128x64 & Custom sized OLED Displays
|
## 128x64 & Custom sized OLED Displays
|
||||||
|
|
||||||
The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind. We have added a define, `OLED_DISPLAY_128X64`, to switch all the values to be used in a 128x64 display, as well as added a custom define, `OLED_DISPLAY_CUSTOM`, that allows you to provide the necessary values to the driver.
|
The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind. We have added a define, `OLED_DISPLAY_128X64`, to switch all the values to be used in a 128x64 display, as well as added a custom define, `OLED_DISPLAY_CUSTOM`, that allows you to provide the necessary values to the driver.
|
||||||
|
|
||||||
|Define |Default |Description |
|
|Define |Default |Description |
|
||||||
|-----------------------|---------------|-----------------------------------------------------------------|
|
|---------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|`OLED_DISPLAY_128X64` |*Not defined* |Changes the display defines for use with 128x64 displays. |
|
|`OLED_DISPLAY_128X64`|*Not defined* |Changes the display defines for use with 128x64 displays. |
|
||||||
|`OLED_DISPLAY_CUSTOM` |*Not defined* |Changes the display defines for use with custom displays.<br />Requires user to implement the below defines. |
|
|`OLED_DISPLAY_CUSTOM`|*Not defined* |Changes the display defines for use with custom displays.<br>Requires user to implement the below defines. |
|
||||||
|`OLED_DISPLAY_WIDTH` |`128` |The width of the OLED display. |
|
|`OLED_DISPLAY_WIDTH` |`128` |The width of the OLED display. |
|
||||||
|`OLED_DISPLAY_HEIGHT` |`32` |The height of the OLED display. |
|
|`OLED_DISPLAY_HEIGHT`|`32` |The height of the OLED display. |
|
||||||
|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br />`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. |
|
|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br>`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. |
|
||||||
|`OLED_BLOCK_TYPE` |`uint16_t` |The unsigned integer type to use for dirty rendering. |
|
|`OLED_BLOCK_TYPE` |`uint16_t` |The unsigned integer type to use for dirty rendering. |
|
||||||
|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br />`(sizeof(OLED_BLOCK_TYPE) * 8)`. |
|
|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br>`(sizeof(OLED_BLOCK_TYPE) * 8)`. |
|
||||||
|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br />`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. |
|
|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. |
|
||||||
|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br />Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`. |
|
|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.<br>Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.|
|
||||||
|`OLED_SOURCE_MAP` |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
|`OLED_SOURCE_MAP` |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
||||||
|`OLED_TARGET_MAP` |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
|`OLED_TARGET_MAP` |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering. |
|
||||||
|
|
||||||
|
|
||||||
### 90 Degree Rotation - Technical Mumbo Jumbo
|
### 90 Degree Rotation - Technical Mumbo Jumbo
|
||||||
|
|
||||||
!> Rotation is unsupported on the SH1106.
|
!> Rotation is unsupported on the SH1106.
|
||||||
|
|
||||||
```C
|
```c
|
||||||
// OLED Rotation enum values are flags
|
// OLED Rotation enum values are flags
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OLED_ROTATION_0 = 0,
|
OLED_ROTATION_0 = 0,
|
||||||
@@ -143,9 +146,9 @@ typedef enum {
|
|||||||
} oled_rotation_t;
|
} oled_rotation_t;
|
||||||
```
|
```
|
||||||
|
|
||||||
OLED displays driven by SSD1306 drivers only natively support in hard ware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an `atmega32u4` board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms.
|
OLED displays driven by SSD1306 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms.
|
||||||
|
|
||||||
90 Degree Rotated Rendering is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the OLED Height, Width, and Block Size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g:
|
90 degree rotation is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the display height, width, and block size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g:
|
||||||
|
|
||||||
| | | | | | |
|
| | | | | | |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
@@ -167,8 +170,8 @@ So those precalculated arrays just index the memory offsets in the order in whic
|
|||||||
|
|
||||||
## OLED API
|
## OLED API
|
||||||
|
|
||||||
```C++
|
```c
|
||||||
// OLED Rotation enum values are flags
|
// OLED rotation enum values are flags
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OLED_ROTATION_0 = 0,
|
OLED_ROTATION_0 = 0,
|
||||||
OLED_ROTATION_90 = 1,
|
OLED_ROTATION_90 = 1,
|
||||||
@@ -218,6 +221,12 @@ void oled_write(const char *data, bool invert);
|
|||||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||||
void oled_write_ln(const char *data, bool invert);
|
void oled_write_ln(const char *data, bool invert);
|
||||||
|
|
||||||
|
// Pans the buffer to the right (or left by passing true) by moving contents of the buffer
|
||||||
|
// Useful for moving the screen in preparation for new drawing
|
||||||
|
// oled_scroll_left or oled_scroll_right should be preferred for all cases of moving a static
|
||||||
|
// image such as a logo or to avoid burn-in as it's much, much less cpu intensive
|
||||||
|
void oled_pan(bool left);
|
||||||
|
|
||||||
// Writes a PROGMEM string to the buffer at current cursor position
|
// Writes a PROGMEM string to the buffer at current cursor position
|
||||||
// Advances the cursor while writing, inverts the pixels if true
|
// Advances the cursor while writing, inverts the pixels if true
|
||||||
// Remapped to call 'void oled_write(const char *data, bool invert);' on ARM
|
// Remapped to call 'void oled_write(const char *data, bool invert);' on ARM
|
||||||
@@ -232,6 +241,9 @@ void oled_write_ln_P(const char *data, bool invert);
|
|||||||
// Writes a string to the buffer at current cursor position
|
// Writes a string to the buffer at current cursor position
|
||||||
void oled_write_raw(const char *data, uint16_t size);
|
void oled_write_raw(const char *data, uint16_t size);
|
||||||
|
|
||||||
|
// Writes a single byte into the buffer at the specified index
|
||||||
|
void oled_write_raw_byte(const char data, uint16_t index);
|
||||||
|
|
||||||
// Writes a PROGMEM string to the buffer at current cursor position
|
// Writes a PROGMEM string to the buffer at current cursor position
|
||||||
void oled_write_raw_P(const char *data, uint16_t size);
|
void oled_write_raw_P(const char *data, uint16_t size);
|
||||||
|
|
||||||
@@ -249,12 +261,24 @@ void oled_task(void);
|
|||||||
// Called at the start of oled_task, weak function overridable by the user
|
// Called at the start of oled_task, weak function overridable by the user
|
||||||
void oled_task_user(void);
|
void oled_task_user(void);
|
||||||
|
|
||||||
// Scrolls the entire display right
|
// Set the specific 8 lines rows of the screen to scroll.
|
||||||
|
// 0 is the default for start, and 7 for end, which is the entire
|
||||||
|
// height of the screen. For 128x32 screens, rows 4-7 are not used.
|
||||||
|
void oled_scroll_set_area(uint8_t start_line, uint8_t end_line);
|
||||||
|
|
||||||
|
// Sets scroll speed, 0-7, fastest to slowest. Default is three.
|
||||||
|
// Does not take effect until scrolling is either started or restarted
|
||||||
|
// the ssd1306 supports 8 speeds with the delay
|
||||||
|
// listed below betwen each frame of the scrolling effect
|
||||||
|
// 0=2, 1=3, 2=4, 3=5, 4=25, 5=64, 6=128, 7=256
|
||||||
|
void oled_scroll_set_speed(uint8_t speed);
|
||||||
|
|
||||||
|
// Begin scrolling the entire display right
|
||||||
// Returns true if the screen was scrolling or starts scrolling
|
// Returns true if the screen was scrolling or starts scrolling
|
||||||
// NOTE: display contents cannot be changed while scrolling
|
// NOTE: display contents cannot be changed while scrolling
|
||||||
bool oled_scroll_right(void);
|
bool oled_scroll_right(void);
|
||||||
|
|
||||||
// Scrolls the entire display left
|
// Begin scrolling the entire display left
|
||||||
// Returns true if the screen was scrolling or starts scrolling
|
// Returns true if the screen was scrolling or starts scrolling
|
||||||
// NOTE: display contents cannot be changed while scrolling
|
// NOTE: display contents cannot be changed while scrolling
|
||||||
bool oled_scroll_left(void);
|
bool oled_scroll_left(void);
|
||||||
@@ -272,26 +296,26 @@ uint8_t oled_max_lines(void);
|
|||||||
|
|
||||||
!> Scrolling and rotation are unsupported on the SH1106.
|
!> Scrolling and rotation are unsupported on the SH1106.
|
||||||
|
|
||||||
## SSD1306.h driver conversion guide
|
## SSD1306.h Driver Conversion Guide
|
||||||
|
|
||||||
|Old API |Recommended New API |
|
|Old API |Recommended New API |
|
||||||
|---------------------------|-----------------------------------|
|
|-------------------------|---------------------------------|
|
||||||
|`struct CharacterMatrix` |*removed - delete all references* |
|
|`struct CharacterMatrix` |*removed - delete all references*|
|
||||||
|`iota_gfx_init` |`oled_init` |
|
|`iota_gfx_init` |`oled_init` |
|
||||||
|`iota_gfx_on` |`oled_on` |
|
|`iota_gfx_on` |`oled_on` |
|
||||||
|`iota_gfx_off` |`oled_off` |
|
|`iota_gfx_off` |`oled_off` |
|
||||||
|`iota_gfx_flush` |`oled_render` |
|
|`iota_gfx_flush` |`oled_render` |
|
||||||
|`iota_gfx_write_char` |`oled_write_char` |
|
|`iota_gfx_write_char` |`oled_write_char` |
|
||||||
|`iota_gfx_write` |`oled_write` |
|
|`iota_gfx_write` |`oled_write` |
|
||||||
|`iota_gfx_write_P` |`oled_write_P` |
|
|`iota_gfx_write_P` |`oled_write_P` |
|
||||||
|`iota_gfx_clear_screen` |`oled_clear` |
|
|`iota_gfx_clear_screen` |`oled_clear` |
|
||||||
|`matrix_clear` |*removed - delete all references* |
|
|`matrix_clear` |*removed - delete all references*|
|
||||||
|`matrix_write_char_inner` |`oled_write_char` |
|
|`matrix_write_char_inner`|`oled_write_char` |
|
||||||
|`matrix_write_char` |`oled_write_char` |
|
|`matrix_write_char` |`oled_write_char` |
|
||||||
|`matrix_write` |`oled_write` |
|
|`matrix_write` |`oled_write` |
|
||||||
|`matrix_write_ln` |`oled_write_ln` |
|
|`matrix_write_ln` |`oled_write_ln` |
|
||||||
|`matrix_write_P` |`oled_write_P` |
|
|`matrix_write_P` |`oled_write_P` |
|
||||||
|`matrix_write_ln_P` |`oled_write_ln_P` |
|
|`matrix_write_ln_P` |`oled_write_ln_P` |
|
||||||
|`matrix_render` |`oled_render` |
|
|`matrix_render` |`oled_render` |
|
||||||
|`iota_gfx_task` |`oled_task` |
|
|`iota_gfx_task` |`oled_task` |
|
||||||
|`iota_gfx_task_user` |`oled_task_user` |
|
|`iota_gfx_task_user` |`oled_task_user` |
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
## Pointing Device
|
# Pointing Device :id=pointing-device
|
||||||
|
|
||||||
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and lightweight. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and lightweight. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you.
|
||||||
|
|
||||||
To enable Pointing Device, uncomment the following line in your rules.mk:
|
To enable Pointing Device, uncomment the following line in your rules.mk:
|
||||||
|
|
||||||
```
|
```makefile
|
||||||
POINTING_DEVICE_ENABLE = yes
|
POINTING_DEVICE_ENABLE = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ When the mouse report is sent, the x, y, v, and h values are set to 0 (this is d
|
|||||||
|
|
||||||
In the following example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. Listen, this is an example:
|
In the following example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. Listen, this is an example:
|
||||||
|
|
||||||
```
|
```c
|
||||||
case MS_SPECIAL:
|
case MS_SPECIAL:
|
||||||
report_mouse_t currentReport = pointing_device_get_report();
|
report_mouse_t currentReport = pointing_device_get_report();
|
||||||
if (record->event.pressed)
|
if (record->event.pressed)
|
||||||
|
|||||||
+30
-29
@@ -1,4 +1,4 @@
|
|||||||
## PS/2 Mouse Support
|
# PS/2 Mouse Support :id=ps2-mouse-support
|
||||||
|
|
||||||
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
|
Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device.
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ 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).
|
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
|
## The Circuitry between Trackpoint and Controller :id=the-circuitry-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+.
|
To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+.
|
||||||
|
|
||||||
@@ -24,20 +24,20 @@ MODULE 5+ --------+--+--------- PWR CONTROLLER
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Busywait Version
|
## Busywait Version :id=busywait-version
|
||||||
|
|
||||||
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
|
Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible.
|
||||||
|
|
||||||
In rules.mk:
|
In rules.mk:
|
||||||
|
|
||||||
```
|
```makefile
|
||||||
PS2_MOUSE_ENABLE = yes
|
PS2_MOUSE_ENABLE = yes
|
||||||
PS2_USE_BUSYWAIT = yes
|
PS2_USE_BUSYWAIT = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
In your keyboard config.h:
|
In your keyboard config.h:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#ifdef PS2_USE_BUSYWAIT
|
#ifdef PS2_USE_BUSYWAIT
|
||||||
# define PS2_CLOCK_PORT PORTD
|
# define PS2_CLOCK_PORT PORTD
|
||||||
# define PS2_CLOCK_PIN PIND
|
# define PS2_CLOCK_PIN PIND
|
||||||
@@ -50,20 +50,20 @@ In your keyboard config.h:
|
|||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Interrupt Version
|
## Interrupt Version :id=interrupt-version
|
||||||
|
|
||||||
The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
|
The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data.
|
||||||
|
|
||||||
In rules.mk:
|
In rules.mk:
|
||||||
|
|
||||||
```
|
```makefile
|
||||||
PS2_MOUSE_ENABLE = yes
|
PS2_MOUSE_ENABLE = yes
|
||||||
PS2_USE_INT = yes
|
PS2_USE_INT = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
In your keyboard config.h:
|
In your keyboard config.h:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#ifdef PS2_USE_INT
|
#ifdef PS2_USE_INT
|
||||||
#define PS2_CLOCK_PORT PORTD
|
#define PS2_CLOCK_PORT PORTD
|
||||||
#define PS2_CLOCK_PIN PIND
|
#define PS2_CLOCK_PIN PIND
|
||||||
@@ -88,20 +88,20 @@ In your keyboard config.h:
|
|||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### USART Version
|
## USART Version :id=usart-version
|
||||||
|
|
||||||
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
|
To use USART on the ATMega32u4, you have to use PD5 for clock and PD2 for data. If one of those are unavailable, you need to use interrupt version.
|
||||||
|
|
||||||
In rules.mk:
|
In rules.mk:
|
||||||
|
|
||||||
```
|
```makefile
|
||||||
PS2_MOUSE_ENABLE = yes
|
PS2_MOUSE_ENABLE = yes
|
||||||
PS2_USE_USART = yes
|
PS2_USE_USART = yes
|
||||||
```
|
```
|
||||||
|
|
||||||
In your keyboard config.h:
|
In your keyboard config.h:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#ifdef PS2_USE_USART
|
#ifdef PS2_USE_USART
|
||||||
#define PS2_CLOCK_PORT PORTD
|
#define PS2_CLOCK_PORT PORTD
|
||||||
#define PS2_CLOCK_PIN PIND
|
#define PS2_CLOCK_PIN PIND
|
||||||
@@ -145,13 +145,13 @@ In your keyboard config.h:
|
|||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
### Additional Settings
|
## Additional Settings :id=additional-settings
|
||||||
|
|
||||||
#### PS/2 Mouse Features
|
### PS/2 Mouse Features :id=ps2-mouse-features
|
||||||
|
|
||||||
These enable settings supported by the PS/2 mouse protocol.
|
These enable settings supported by the PS/2 mouse protocol.
|
||||||
|
|
||||||
```
|
```c
|
||||||
/* Use remote mode instead of the default stream mode (see link) */
|
/* Use remote mode instead of the default stream mode (see link) */
|
||||||
#define PS2_MOUSE_USE_REMOTE_MODE
|
#define PS2_MOUSE_USE_REMOTE_MODE
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ These enable settings supported by the PS/2 mouse protocol.
|
|||||||
|
|
||||||
You can also call the following functions from ps2_mouse.h
|
You can also call the following functions from ps2_mouse.h
|
||||||
|
|
||||||
```
|
```c
|
||||||
void ps2_mouse_disable_data_reporting(void);
|
void ps2_mouse_disable_data_reporting(void);
|
||||||
|
|
||||||
void ps2_mouse_enable_data_reporting(void);
|
void ps2_mouse_enable_data_reporting(void);
|
||||||
@@ -188,36 +188,36 @@ void ps2_mouse_set_resolution(ps2_mouse_resolution_t resolution);
|
|||||||
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
|
void ps2_mouse_set_sample_rate(ps2_mouse_sample_rate_t sample_rate);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Fine Control
|
### Fine Control :id=fine-control
|
||||||
|
|
||||||
Use the following defines to change the sensitivity and speed of the mouse.
|
Use the following defines to change the sensitivity and speed of the mouse.
|
||||||
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
|
Note: you can also use `ps2_mouse_set_resolution` for the same effect (not supported on most touchpads).
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_X_MULTIPLIER 3
|
#define PS2_MOUSE_X_MULTIPLIER 3
|
||||||
#define PS2_MOUSE_Y_MULTIPLIER 3
|
#define PS2_MOUSE_Y_MULTIPLIER 3
|
||||||
#define PS2_MOUSE_V_MULTIPLIER 1
|
#define PS2_MOUSE_V_MULTIPLIER 1
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Scroll Button
|
### Scroll Button :id=scroll-button
|
||||||
|
|
||||||
If you're using a trackpoint, you will likely want to be able to use it for scrolling.
|
If you're using a trackpoint, you will likely want to be able to use it for scrolling.
|
||||||
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
|
It's possible to enable a "scroll button/s" that when pressed will cause the mouse to scroll instead of moving.
|
||||||
To enable the feature, you must set a scroll button mask as follows:
|
To enable the feature, you must set a scroll button mask as follows:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BUTTON_MIDDLE) /* Default */
|
#define PS2_MOUSE_SCROLL_BTN_MASK (1<<PS2_MOUSE_BUTTON_MIDDLE) /* Default */
|
||||||
```
|
```
|
||||||
|
|
||||||
To disable the scroll button feature:
|
To disable the scroll button feature:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_SCROLL_BTN_MASK 0
|
#define PS2_MOUSE_SCROLL_BTN_MASK 0
|
||||||
```
|
```
|
||||||
|
|
||||||
The available buttons are:
|
The available buttons are:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_BTN_LEFT 0
|
#define PS2_MOUSE_BTN_LEFT 0
|
||||||
#define PS2_MOUSE_BTN_RIGHT 1
|
#define PS2_MOUSE_BTN_RIGHT 1
|
||||||
#define PS2_MOUSE_BTN_MIDDLE 2
|
#define PS2_MOUSE_BTN_MIDDLE 2
|
||||||
@@ -229,27 +229,28 @@ Once you've configured your scroll button mask, you must configure the scroll bu
|
|||||||
This is the interval before which if the scroll buttons were released they would be sent to the host.
|
This is the interval before which if the scroll buttons were released they would be sent to the host.
|
||||||
After this interval, they will cause the mouse to scroll and will not be sent.
|
After this interval, they will cause the mouse to scroll and will not be sent.
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_SCROLL_BTN_SEND 300 /* Default */
|
#define PS2_MOUSE_SCROLL_BTN_SEND 300 /* Default */
|
||||||
```
|
```
|
||||||
|
|
||||||
To disable sending the scroll buttons:
|
To disable sending the scroll buttons:
|
||||||
```
|
|
||||||
|
```c
|
||||||
#define PS2_MOUSE_SCROLL_BTN_SEND 0
|
#define PS2_MOUSE_SCROLL_BTN_SEND 0
|
||||||
```
|
```
|
||||||
|
|
||||||
Fine control over the scrolling is supported with the following defines:
|
Fine control over the scrolling is supported with the following defines:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_SCROLL_DIVISOR_H 2
|
#define PS2_MOUSE_SCROLL_DIVISOR_H 2
|
||||||
#define PS2_MOUSE_SCROLL_DIVISOR_V 2
|
#define PS2_MOUSE_SCROLL_DIVISOR_V 2
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Invert Mouse and Scroll Axes
|
### Invert Mouse and Scroll Axes :id=invert-mouse-and-scroll-axes
|
||||||
|
|
||||||
To invert the X and Y axes you can put:
|
To invert the X and Y axes you can put:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_INVERT_X
|
#define PS2_MOUSE_INVERT_X
|
||||||
#define PS2_MOUSE_INVERT_Y
|
#define PS2_MOUSE_INVERT_Y
|
||||||
```
|
```
|
||||||
@@ -258,18 +259,18 @@ into config.h.
|
|||||||
|
|
||||||
To reverse the scroll axes you can put:
|
To reverse the scroll axes you can put:
|
||||||
|
|
||||||
```
|
```c
|
||||||
#define PS2_MOUSE_INVERT_H
|
#define PS2_MOUSE_INVERT_H
|
||||||
#define PS2_MOUSE_INVERT_V
|
#define PS2_MOUSE_INVERT_V
|
||||||
```
|
```
|
||||||
|
|
||||||
into config.h.
|
into config.h.
|
||||||
|
|
||||||
#### Debug Settings
|
### Debug Settings :id=debug-settings
|
||||||
|
|
||||||
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
To debug the mouse, add `debug_mouse = true` or enable via bootmagic.
|
||||||
|
|
||||||
```
|
```c
|
||||||
/* To debug the mouse reports */
|
/* To debug the mouse reports */
|
||||||
#define PS2_MOUSE_DEBUG_HID
|
#define PS2_MOUSE_DEBUG_HID
|
||||||
#define PS2_MOUSE_DEBUG_RAW
|
#define PS2_MOUSE_DEBUG_RAW
|
||||||
|
|||||||
+48
-39
@@ -1,22 +1,22 @@
|
|||||||
# RGB Matrix Lighting
|
# RGB Matrix Lighting :id=rgb-matrix-lighting
|
||||||
|
|
||||||
This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it.
|
This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it.
|
||||||
|
|
||||||
If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead.
|
If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead.
|
||||||
|
|
||||||
## Driver configuration
|
## Driver configuration :id=driver-configuration
|
||||||
---
|
---
|
||||||
### IS31FL3731
|
### IS31FL3731 :id=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`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
```C
|
```makefile
|
||||||
RGB_MATRIX_ENABLE = IS31FL3731
|
RGB_MATRIX_ENABLE = IS31FL3731
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure the hardware via your `config.h`:
|
Configure the hardware via your `config.h`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
// 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)
|
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||||
// The address will vary depending on your wiring:
|
// The address will vary depending on your wiring:
|
||||||
@@ -39,7 +39,7 @@ Currently only 2 drivers are supported, but it would be trivial to support all 4
|
|||||||
|
|
||||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
/* Refer to IS31 manual for these locations
|
/* Refer to IS31 manual for these locations
|
||||||
* driver
|
* driver
|
||||||
@@ -55,19 +55,19 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
|||||||
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).
|
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/IS31FL3737
|
### IS31FL3733/IS31FL3737 :id=is31fl3733is31fl3737
|
||||||
|
|
||||||
!> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`.
|
!> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`.
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
```C
|
```makefile
|
||||||
RGB_MATRIX_ENABLE = IS31FL3733
|
RGB_MATRIX_ENABLE = IS31FL3733
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure the hardware via your `config.h`:
|
Configure the hardware via your `config.h`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
// This is a 7-bit address, that gets left-shifted and bit 0
|
// 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)
|
// set to 0 for write, 1 for read (as per I2C protocol)
|
||||||
// The address will vary depending on your wiring:
|
// The address will vary depending on your wiring:
|
||||||
@@ -90,7 +90,7 @@ Currently only a single drivers is supported, but it would be trivial to support
|
|||||||
|
|
||||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
|
||||||
/* Refer to IS31 manual for these locations
|
/* Refer to IS31 manual for these locations
|
||||||
* driver
|
* driver
|
||||||
@@ -107,17 +107,17 @@ Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### WS2812
|
### WS2812 :id=ws2812
|
||||||
|
|
||||||
There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`:
|
There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`:
|
||||||
|
|
||||||
```C
|
```makefile
|
||||||
RGB_MATRIX_ENABLE = WS2812
|
RGB_MATRIX_ENABLE = WS2812
|
||||||
```
|
```
|
||||||
|
|
||||||
Configure the hardware via your `config.h`:
|
Configure the hardware via your `config.h`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
// The pin connected to the data pin of the LEDs
|
// The pin connected to the data pin of the LEDs
|
||||||
#define RGB_DI_PIN D7
|
#define RGB_DI_PIN D7
|
||||||
// The number of LEDs connected
|
// The number of LEDs connected
|
||||||
@@ -128,7 +128,7 @@ Configure the hardware via your `config.h`:
|
|||||||
|
|
||||||
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
const led_config_t g_led_config = { {
|
const led_config_t g_led_config = { {
|
||||||
// Key Matrix to LED Index
|
// Key Matrix to LED Index
|
||||||
{ 5, NO_LED, NO_LED, 0 },
|
{ 5, NO_LED, NO_LED, 0 },
|
||||||
@@ -146,7 +146,7 @@ const led_config_t g_led_config = { {
|
|||||||
|
|
||||||
The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position:
|
The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION
|
x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION
|
||||||
y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION
|
y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION
|
||||||
```
|
```
|
||||||
@@ -157,7 +157,7 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
|||||||
|
|
||||||
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type.
|
||||||
|
|
||||||
## Flags
|
## Flags :id=flags
|
||||||
|
|
||||||
|Define |Description |
|
|Define |Description |
|
||||||
|------------------------------------|-------------------------------------------|
|
|------------------------------------|-------------------------------------------|
|
||||||
@@ -169,32 +169,37 @@ As mentioned earlier, the center of the keyboard by default is expected to be `{
|
|||||||
|`#define LED_FLAG_UNDERGLOW 0x02` |If the LED is for underglow. |
|
|`#define LED_FLAG_UNDERGLOW 0x02` |If the LED is for underglow. |
|
||||||
|`#define LED_FLAG_KEYLIGHT 0x04` |If the LED is for key backlight. |
|
|`#define LED_FLAG_KEYLIGHT 0x04` |If the LED is for key backlight. |
|
||||||
|
|
||||||
## Keycodes
|
## Keycodes :id=keycodes
|
||||||
|
|
||||||
All RGB keycodes are currently shared with the RGBLIGHT system:
|
All RGB keycodes are currently shared with the RGBLIGHT system:
|
||||||
|
|
||||||
* `RGB_TOG` - toggle
|
|Key |Aliases |Description |
|
||||||
* `RGB_MOD` - cycle through modes
|
|-------------------|----------|--------------------------------------------------------------------------------------|
|
||||||
* `RGB_HUI` - increase hue
|
|`RGB_TOG` | |Toggle RGB lighting on or off |
|
||||||
* `RGB_HUD` - decrease hue
|
|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held |
|
||||||
* `RGB_SAI` - increase saturation
|
|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held |
|
||||||
* `RGB_SAD` - decrease saturation
|
|`RGB_HUI` | |Increase hue, decrease hue when Shift is held |
|
||||||
* `RGB_VAI` - increase value
|
|`RGB_HUD` | |Decrease hue, increase hue when Shift is held |
|
||||||
* `RGB_VAD` - decrease value
|
|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held |
|
||||||
* `RGB_SPI` - increase speed effect (no EEPROM support)
|
|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held |
|
||||||
* `RGB_SPD` - decrease speed effect (no EEPROM support)
|
|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held |
|
||||||
|
|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held |
|
||||||
|
|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held|
|
||||||
|
|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held|
|
||||||
|
|
||||||
* `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system
|
* `RGB_MODE_*` keycodes will generally work, but are not currently mapped to the correct effects for the RGB Matrix system
|
||||||
|
|
||||||
## RGB Matrix Effects
|
## RGB Matrix Effects :id=rgb-matrix-effects
|
||||||
|
|
||||||
All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available:
|
All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
enum rgb_matrix_effects {
|
enum rgb_matrix_effects {
|
||||||
RGB_MATRIX_NONE = 0,
|
RGB_MATRIX_NONE = 0,
|
||||||
RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support
|
RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support
|
||||||
RGB_MATRIX_ALPHAS_MODS, // Static dual hue, speed is hue for secondary hue
|
RGB_MATRIX_ALPHAS_MODS, // Static dual hue, speed is hue for secondary hue
|
||||||
RGB_MATRIX_GRADIENT_UP_DOWN, // Static gradient top to bottom, speed controls how much gradient changes
|
RGB_MATRIX_GRADIENT_UP_DOWN, // Static gradient top to bottom, speed controls how much gradient changes
|
||||||
|
RGB_MATRIX_GRADIENT_LEFT_RIGHT, // Static gradient left to right, speed controls how much gradient changes
|
||||||
RGB_MATRIX_BREATHING, // Single hue brightness cycling animation
|
RGB_MATRIX_BREATHING, // Single hue brightness cycling animation
|
||||||
RGB_MATRIX_BAND_SAT, // Single hue band fading saturation scrolling left to right
|
RGB_MATRIX_BAND_SAT, // Single hue band fading saturation scrolling left to right
|
||||||
RGB_MATRIX_BAND_VAL, // Single hue band fading brightness scrolling left to right
|
RGB_MATRIX_BAND_VAL, // Single hue band fading brightness scrolling left to right
|
||||||
@@ -280,16 +285,16 @@ You can disable a single effect by defining `DISABLE_[EFFECT_NAME]` in your `con
|
|||||||
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Disables `RGB_MATRIX_SOLID_MULTISPLASH` |
|
|`#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Disables `RGB_MATRIX_SOLID_MULTISPLASH` |
|
||||||
|
|
||||||
|
|
||||||
## Custom RGB Matrix Effects
|
## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects
|
||||||
|
|
||||||
By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rule.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.
|
By setting `RGB_MATRIX_CUSTOM_USER` (and/or `RGB_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files.
|
||||||
|
|
||||||
To declare new effects, create a new `rgb_matrix_user/kb.inc` that looks something like this:
|
To declare new effects, create a new `rgb_matrix_user/kb.inc` that looks something like this:
|
||||||
|
|
||||||
`rgb_matrix_user.inc` should go in the root of the keymap directory.
|
`rgb_matrix_user.inc` should go in the root of the keymap directory.
|
||||||
`rgb_matrix_kb.inc` should go in the root of the keyboard directory.
|
`rgb_matrix_kb.inc` should go in the root of the keyboard directory.
|
||||||
|
|
||||||
```C
|
```c
|
||||||
// !!! DO NOT ADD #pragma once !!! //
|
// !!! DO NOT ADD #pragma once !!! //
|
||||||
|
|
||||||
// Step 1.
|
// Step 1.
|
||||||
@@ -336,7 +341,7 @@ static bool my_cool_effect2(effect_params_t* params) {
|
|||||||
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/`
|
For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix_animation/`
|
||||||
|
|
||||||
|
|
||||||
## Colors
|
## Colors :id=colors
|
||||||
|
|
||||||
These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
|
These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions.
|
||||||
|
|
||||||
@@ -364,9 +369,9 @@ These are shorthands to popular colors. The `RGB` ones can be passed to the `set
|
|||||||
These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list!
|
These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight_list.h). Feel free to add to this list!
|
||||||
|
|
||||||
|
|
||||||
## Additional `config.h` Options
|
## Additional `config.h` Options :id=additional-configh-options
|
||||||
|
|
||||||
```C
|
```c
|
||||||
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses
|
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses
|
||||||
#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
|
#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses)
|
||||||
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
|
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
|
||||||
@@ -375,23 +380,27 @@ These are defined in [`rgblight_list.h`](https://github.com/qmk/qmk_firmware/blo
|
|||||||
#define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
|
#define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness)
|
||||||
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
|
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
|
||||||
#define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set
|
#define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set
|
||||||
|
#define RGB_MATRIX_STARTUP_HUE 0 // Sets the default hue value, if none has been set
|
||||||
|
#define RGB_MATRIX_STARTUP_SAT 255 // Sets the default saturation value, if none has been set
|
||||||
|
#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
|
||||||
|
#define RGB_MATRIX_STARTUP_SPD 127 // Sets the default animation speed, if none has been set
|
||||||
```
|
```
|
||||||
|
|
||||||
## EEPROM storage
|
## EEPROM storage :id=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:
|
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:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
#define EECONFIG_RGB_MATRIX (uint32_t *)28
|
#define EECONFIG_RGB_MATRIX (uint32_t *)28
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `28` is an unused index from `eeconfig.h`.
|
Where `28` is an unused index from `eeconfig.h`.
|
||||||
|
|
||||||
## Suspended state
|
## Suspended state :id=suspended-state
|
||||||
|
|
||||||
To use the suspend feature, add this to your `<keyboard>.c`:
|
To use the suspend feature, add this to your `<keyboard>.c`:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
void suspend_power_down_kb(void)
|
void suspend_power_down_kb(void)
|
||||||
{
|
{
|
||||||
rgb_matrix_set_suspend_state(true);
|
rgb_matrix_set_suspend_state(true);
|
||||||
|
|||||||
@@ -48,12 +48,12 @@ Changing the **Value** sets the overall brightness.<br>
|
|||||||
|`RGB_TOG` | |Toggle RGB lighting on or off |
|
|`RGB_TOG` | |Toggle RGB lighting on or off |
|
||||||
|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held |
|
|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held |
|
||||||
|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held|
|
|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held|
|
||||||
|`RGB_HUI` | |Increase hue |
|
|`RGB_HUI` | |Increase hue, decrease hue when Shift is held |
|
||||||
|`RGB_HUD` | |Decrease hue |
|
|`RGB_HUD` | |Decrease hue, increase hue when Shift is held |
|
||||||
|`RGB_SAI` | |Increase saturation |
|
|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held |
|
||||||
|`RGB_SAD` | |Decrease saturation |
|
|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held |
|
||||||
|`RGB_VAI` | |Increase value (brightness) |
|
|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held |
|
||||||
|`RGB_VAD` | |Decrease value (brightness) |
|
|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held |
|
||||||
|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode |
|
|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode |
|
||||||
|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode |
|
|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode |
|
||||||
|`RGB_MODE_RAINBOW` |`RGB_M_R` |Rainbow animation mode |
|
|`RGB_MODE_RAINBOW` |`RGB_M_R` |Rainbow animation mode |
|
||||||
@@ -172,6 +172,62 @@ const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
|
|||||||
const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
|
const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Lighting Layers
|
||||||
|
|
||||||
|
By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make
|
||||||
|
it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do.
|
||||||
|
|
||||||
|
To define a layer, we modify `keymap.c` to list out LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Light LEDs 6 to 9 and 12 to 15 red when caps lock is active. Hard to ignore!
|
||||||
|
const rgblight_segment_t PROGMEM my_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS(
|
||||||
|
{6, 4, HSV_RED}, // Light 4 LEDs, starting with LED 6
|
||||||
|
{12, 4, HSV_RED} // Light 4 LEDs, starting with LED 12
|
||||||
|
);
|
||||||
|
// Light LEDs 9 & 10 in cyan when keyboard layer 1 is active
|
||||||
|
const rgblight_segment_t PROGMEM my_layer1_layer[] = RGBLIGHT_LAYER_SEGMENTS(
|
||||||
|
{9, 2, HSV_CYAN}
|
||||||
|
);
|
||||||
|
// Light LEDs 11 & 12 in purple when keyboard layer 2 is active
|
||||||
|
const rgblight_segment_t PROGMEM my_layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS(
|
||||||
|
{11, 2, HSV_PURPLE},
|
||||||
|
);
|
||||||
|
// etc..
|
||||||
|
```
|
||||||
|
|
||||||
|
We combine these layers into an array using the `RGBLIGHT_LAYERS_LIST` macro, and assign it to the `rgblight_layers` variable during keyboard setup. Note that you can only define up to 8 lighting layers. Any extra layers will be ignored. Since the different lighting layers overlap, the order matters in the array, with later layers taking precedence:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Now define the array of layers. Later layers take precedence
|
||||||
|
const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
|
||||||
|
my_capslock_layer,
|
||||||
|
my_layer1_layer, // Overrides caps lock layer
|
||||||
|
my_layer2_layer // Overrides other layers
|
||||||
|
);
|
||||||
|
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
// Enable the LED layers
|
||||||
|
rgblight_layers = my_rgb_layers;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we enable and disable the lighting layers whenever the state of the keyboard changes:
|
||||||
|
|
||||||
|
```c
|
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
// Both layers will light up if both kb layers are active
|
||||||
|
rgblight_set_layer_state(1, layer_state_cmp(state, 1));
|
||||||
|
rgblight_set_layer_state(2, layer_state_cmp(state, 2));
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool led_update_user(led_t led_state) {
|
||||||
|
rgblight_set_layer_state(0, led_state.caps_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Functions
|
## 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:
|
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:
|
||||||
@@ -263,6 +319,12 @@ rgblight_sethsv(HSV_GREEN, 2); // led 2
|
|||||||
|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
|
|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
|
||||||
|`rgblight_sethsv_noeeprom(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
|
|`rgblight_sethsv_noeeprom(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
|
||||||
|
|
||||||
|
#### layer functions
|
||||||
|
|Function |Description |
|
||||||
|
|--------------------------------------------|-------------|
|
||||||
|
|`rgblight_get_layer_state(i)` |Returns `true` if lighting layer `i` is enabled |
|
||||||
|
|`rgblight_set_layer_state(i, is_on)` |Enable or disable lighting layer `i` based on value of `bool is_on` |
|
||||||
|
|
||||||
#### query
|
#### query
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|-----------------------|-----------------|
|
|-----------------------|-----------------|
|
||||||
|
|||||||
@@ -198,10 +198,15 @@ This option changes the startup behavior to detect an active USB connection when
|
|||||||
?> This setting will stop the ability to demo using battery packs.
|
?> This setting will stop the ability to demo using battery packs.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define SPLIT_USB_TIMEOUT 2500
|
#define SPLIT_USB_TIMEOUT 2000
|
||||||
```
|
```
|
||||||
This sets the maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`.
|
This sets the maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define SPLIT_USB_TIMEOUT_POLL 10
|
||||||
|
```
|
||||||
|
This sets the poll frequency when detecting master/slave when using `SPLIT_USB_DETECT`
|
||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|
||||||
Nicinabox has a [very nice and detailed guide](https://github.com/nicinabox/lets-split-guide) for the Let's Split keyboard, that covers most everything you need to know, including troubleshooting information.
|
Nicinabox has a [very nice and detailed guide](https://github.com/nicinabox/lets-split-guide) for the Let's Split keyboard, that covers most everything you need to know, including troubleshooting information.
|
||||||
|
|||||||
+15
-15
@@ -1,16 +1,16 @@
|
|||||||
# Stenography in QMK
|
# Stenography in QMK :id=stenography-in-qmk
|
||||||
|
|
||||||
[Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy).
|
[Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy).
|
||||||
|
|
||||||
The [Open Steno Project](http://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports
|
The [Open Steno Project](http://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports
|
||||||
|
|
||||||
## Plover with QWERTY Keyboard
|
## Plover with QWERTY Keyboard :id=plover-with-qwerty-keyboard
|
||||||
|
|
||||||
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
|
Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar.
|
||||||
|
|
||||||
To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
|
To use Plover with QMK just enable NKRO and optionally adjust your layout if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys.
|
||||||
|
|
||||||
## Plover with Steno Protocol
|
## Plover with Steno Protocol :id=plover-with-steno-protocol
|
||||||
|
|
||||||
Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
|
Plover also understands the language of several steno machines. QMK can speak a couple of these languages, TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`.
|
||||||
|
|
||||||
@@ -20,26 +20,26 @@ In this mode Plover expects to speak with a steno machine over a serial port so
|
|||||||
|
|
||||||
> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
|
> Note: Due to hardware limitations you may not be able to run both a virtual serial port and mouse emulation at the same time.
|
||||||
|
|
||||||
### TX Bolt
|
### TX Bolt :id=tx-bolt
|
||||||
|
|
||||||
TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
|
TX Bolt communicates the status of 24 keys over a very simple protocol in variable-sized (1-5 byte) packets.
|
||||||
|
|
||||||
### GeminiPR
|
### GeminiPR :id=geminipr
|
||||||
|
|
||||||
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
|
GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including supporting non-English theories.
|
||||||
|
|
||||||
## Configuring QMK for Steno
|
## Configuring QMK for Steno :id=configuring-qmk-for-steno
|
||||||
|
|
||||||
Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
|
Firstly, enable steno in your keymap's Makefile. You may also need disable mousekeys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them.
|
||||||
|
|
||||||
```Makefile
|
```makefile
|
||||||
STENO_ENABLE = yes
|
STENO_ENABLE = yes
|
||||||
MOUSEKEY_ENABLE = no
|
MOUSEKEY_ENABLE = no
|
||||||
```
|
```
|
||||||
|
|
||||||
In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
|
In your keymap create a new layer for Plover. You will need to include `keymap_steno.h`. See `planck/keymaps/steno/keymap.c` for an example. Remember to create a key to switch to the layer as well as a key for exiting the layer. If you would like to switch modes on the fly you can use the keycodes `QK_STENO_BOLT` and `QK_STENO_GEMINI`. If you only want to use one of the protocols you may set it up in your initialization function:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
void matrix_init_user() {
|
void matrix_init_user() {
|
||||||
steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
|
steno_set_mode(STENO_MODE_GEMINI); // or STENO_MODE_BOLT
|
||||||
}
|
}
|
||||||
@@ -49,37 +49,37 @@ Once you have your keyboard flashed launch Plover. Click the 'Configure...' butt
|
|||||||
|
|
||||||
On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
|
On the display tab click 'Open stroke display'. With Plover disabled you should be able to hit keys on your keyboard and see them show up in the stroke display window. Use this to make sure you have set up your keymap correctly. You are now ready to steno!
|
||||||
|
|
||||||
## Learning Stenography
|
## Learning Stenography :id=learning-stenography
|
||||||
|
|
||||||
* [Learn Plover!](https://sites.google.com/site/ploverdoc/)
|
* [Learn Plover!](https://sites.google.com/site/learnplover/)
|
||||||
* [QWERTY Steno](http://qwertysteno.com/Home/)
|
* [QWERTY Steno](http://qwertysteno.com/Home/)
|
||||||
* [Steno Jig](https://joshuagrams.github.io/steno-jig/)
|
* [Steno Jig](https://joshuagrams.github.io/steno-jig/)
|
||||||
* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki
|
* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki
|
||||||
|
|
||||||
## Interfacing with the code
|
## Interfacing with the code :id=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.
|
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
|
```c
|
||||||
bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]);
|
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.
|
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
|
```c
|
||||||
bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; }
|
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.
|
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
|
```c
|
||||||
bool postprocess_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed);
|
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.
|
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
|
## Keycode Reference :id=keycode-reference
|
||||||
|
|
||||||
As defined in `keymap_steno.h`.
|
As defined in `keymap_steno.h`.
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ If you want to implement this in your userspace, then you may want to check out
|
|||||||
|
|
||||||
> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
|
> In this configuration "hold" takes place **after** tap dance timeout (see `ACTION_TAP_DANCE_FN_ADVANCED_TIME`). To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`).
|
||||||
|
|
||||||
### Example 5: Using tap dance for advanced mod-tap and layer-tap keys
|
### Example 5: Using tap dance for advanced mod-tap and layer-tap keys :id=example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys
|
||||||
|
|
||||||
Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`.
|
Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`.
|
||||||
|
|
||||||
|
|||||||
+16
-5
@@ -193,12 +193,23 @@ By default, when the keyboard boots, it will initialize the input mode to the la
|
|||||||
|
|
||||||
!> Using `UNICODE_SELECTED_MODES` means you don't have to initially set the input mode in `matrix_init_user()` (or a similar function); the Unicode system will do that for you on startup. This has the added benefit of avoiding unnecessary writes to EEPROM.
|
!> Using `UNICODE_SELECTED_MODES` means you don't have to initially set the input mode in `matrix_init_user()` (or a similar function); the Unicode system will do that for you on startup. This has the added benefit of avoiding unnecessary writes to EEPROM.
|
||||||
|
|
||||||
## `send_unicode_hex_string`
|
## `send_unicode_string()`
|
||||||
|
|
||||||
To type multiple characters for things like (ノಠ痊ಠ)ノ彡┻━┻, you can use `send_unicode_hex_string()` much like `SEND_STRING()` except you would use hex values separate by spaces.
|
This function is much like `send_string()` but allows you to input UTF-8 characters directly, and supports all code points (provided the selected input method also supports it). Make sure your `keymap.c` is formatted in UTF-8 encoding.
|
||||||
For example, the table flip seen above would be `send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B")`
|
|
||||||
|
|
||||||
There are many ways to get a hex code, but an easy one is [this site](https://r12a.github.io/app-conversion/). Just make sure to convert to hexadecimal, and that is your string.
|
```c
|
||||||
|
send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
|
||||||
|
```
|
||||||
|
|
||||||
|
## `send_unicode_hex_string()`
|
||||||
|
|
||||||
|
Similar to `send_unicode_string()`, but the characters are represented by their code point values in ASCII, separated by spaces. For example, the table flip above would be achieved with:
|
||||||
|
|
||||||
|
```c
|
||||||
|
send_unicode_hex_string("0028 30CE 0CA0 75CA 0CA0 0029 30CE 5F61 253B 2501 253B");
|
||||||
|
```
|
||||||
|
|
||||||
|
An easy way to convert your Unicode string to this format is by using [this site](https://r12a.github.io/app-conversion/), and taking the result in the "Hex/UTF-32" section.
|
||||||
|
|
||||||
## Additional Language Support
|
## Additional Language Support
|
||||||
|
|
||||||
@@ -228,6 +239,6 @@ AutoHotkey inserts the Text right of `Send, ` when this combination is pressed.
|
|||||||
|
|
||||||
If you enable the US International layout on the system, it will use punctuation to accent the characters.
|
If you enable the US International layout on the system, it will use punctuation to accent the characters.
|
||||||
|
|
||||||
For instance, typing "`a" will result in à.
|
For instance, typing "\`a" will result in à.
|
||||||
|
|
||||||
You can find details on how to enable this [here](https://support.microsoft.com/en-us/help/17424/windows-change-keyboard-layout).
|
You can find details on how to enable this [here](https://support.microsoft.com/en-us/help/17424/windows-change-keyboard-layout).
|
||||||
@@ -97,13 +97,25 @@ 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.
|
Additionally, this is a good place to document your code, if you wish to share it with others.
|
||||||
|
|
||||||
# Examples
|
## Build All Keyboards That Support a Specific Keymap
|
||||||
|
|
||||||
|
Want to check all your keymaps build in a single command? You can run:
|
||||||
|
|
||||||
|
make all:<name>
|
||||||
|
|
||||||
|
For example,
|
||||||
|
|
||||||
|
make all:jack
|
||||||
|
|
||||||
|
This is ideal for when you want ensure everything compiles successfully when preparing a [_Pull request_](https://github.com/qmk/qmk_firmware/pulls).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
For a brief example, checkout [`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna).
|
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.
|
For a more complicated example, checkout [`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna)'s userspace.
|
||||||
|
|
||||||
|
|
||||||
## Customized Functions
|
### 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.
|
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.
|
||||||
|
|
||||||
@@ -130,7 +142,7 @@ The `_keymap` part here doesn't matter, it just needs to be something other than
|
|||||||
|
|
||||||
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).
|
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).
|
||||||
|
|
||||||
## Custom Features
|
### Custom Features
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -166,7 +178,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## 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. 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.
|
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.
|
||||||
|
|
||||||
@@ -208,15 +220,15 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
clear_mods(); clear_oneshot_mods();
|
clear_mods(); clear_oneshot_mods();
|
||||||
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP);
|
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP);
|
||||||
#ifndef FLASH_BOOTLOADER
|
#ifndef FLASH_BOOTLOADER
|
||||||
if ( (temp_mod | temp_osm) & MOD_MASK_SHIFT )
|
if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
|
||||||
#endif
|
#endif
|
||||||
{ //
|
{
|
||||||
SEND_STRING(":flash");
|
SEND_STRING(":flash");
|
||||||
}
|
}
|
||||||
if ( (temp_mod | temp_osm) & MOD_MASK_CTRL) {
|
if ((temp_mod | temp_osm) & MOD_MASK_CTRL) {
|
||||||
SEND_STRING(" -j8 --output-sync");
|
SEND_STRING(" -j8 --output-sync");
|
||||||
}
|
}
|
||||||
SEND_STRING(SS_TAP(X_ENTER));
|
tap_code(KC_ENT);
|
||||||
set_mods(temp_mod);
|
set_mods(temp_mod);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
# QMK Features
|
|
||||||
|
|
||||||
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, 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.
|
|
||||||
* [Bluetooth](feature_bluetooth.md) - BlueTooth 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").
|
|
||||||
* [Debounce API](feature_debounce_type.md) - Customization of debouncing algorithms, and the ability to add more/custom debouncing.
|
|
||||||
* [DIP Switch](feature_dip_switch.md) - Toggle switches for customizing board function.
|
|
||||||
* [Dynamic Macros](feature_dynamic_macros.md) - Record and playback macros from the keyboard itself.
|
|
||||||
* [Encoders](feature_encoders.md) - Rotary encoders!
|
|
||||||
* [Grave Escape](feature_grave_esc.md) - Lets you use a single key for Esc and Grave.
|
|
||||||
* [Haptic Feedback](feature_haptic_feedback.md) - Add haptic feedback drivers to your board.
|
|
||||||
* [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.
|
|
||||||
* [LED Matrix](feature_led_matrix.md) - LED Matrix single color lights for per key lighting (Single Color, not RGB).
|
|
||||||
* [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.
|
|
||||||
* [OLED Driver](feature_oled_driver.md) - Add OLED screens to your keyboard.
|
|
||||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys) - Sticky Keys, lets you 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.
|
|
||||||
* [Split Keyboard](feature_split_keyboard.md)
|
|
||||||
* [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.
|
|
||||||
* [Terminal](feature_terminal.md) - CLI interface to the internals of your keyboard.
|
|
||||||
* [Thermal Printer](feature_thermal_printer.md) - Connect a thermal printer to your keyboard to be able to toggle on a printed log of everything you type.
|
|
||||||
* [Unicode](feature_unicode.md) - Unicode input support.
|
|
||||||
* [Userspace](feature_userspace.md) - Share code between different keymaps and keyboards.
|
|
||||||
* [Velocikey](feature_velocikey.md) - Allows changes in RGB animation speed based on WPM/Typing speed.
|
|
||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
# Flashing Instructions and Bootloader Information
|
# Flashing Instructions and Bootloader Information
|
||||||
|
|
||||||
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.
|
There are quite a few different types of bootloaders that keyboards use, and just about all of them 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 in 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).
|
||||||
|
|
||||||
## DFU
|
## DFU
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ or
|
|||||||
make <keyboard>:<keymap>:avrdude
|
make <keyboard>:<keymap>:avrdude
|
||||||
|
|
||||||
|
|
||||||
#### Caterina commands
|
### Caterina commands
|
||||||
|
|
||||||
There are a number of DFU commands that you can use to flash firmware to a DFU device:
|
There are a number of DFU commands that you can use to flash firmware to a DFU device:
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ There are a number of DFU commands that you can use to flash firmware to a DFU d
|
|||||||
|
|
||||||
## Halfkay
|
## Halfkay
|
||||||
|
|
||||||
Halfkay is a super-slim protocol developed by PJRC that uses HID, and come on all Teensys (namely the 2.0).
|
Halfkay is a super-slim protocol developed by PJRC that uses HID, and comes on all Teensys (namely the 2.0).
|
||||||
|
|
||||||
To ensure compatibility with the Halfkay bootloader, make sure this block is present your `rules.mk`:
|
To ensure compatibility with the Halfkay bootloader, make sure this block is present your `rules.mk`:
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ General flashing sequence:
|
|||||||
|
|
||||||
## bootloadHID Flashing Target
|
## bootloadHID Flashing Target
|
||||||
|
|
||||||
Using the QMK installation script, detailed [here](newbs_getting_started.md), the required bootloadHID tools should be automatically installed.
|
?> Using the QMK installation script, detailed [here](newbs_getting_started.md), the required bootloadHID tools should be automatically installed.
|
||||||
|
|
||||||
To flash via the command line, use the target `:bootloadHID` by executing the following command:
|
To flash via the command line, use the target `:bootloadHID` by executing the following command:
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Sinon, vous pouvez aussi le télécharger directement en ([zip](https://github.c
|
|||||||
|
|
||||||
## Comment le compiler
|
## Comment le compiler
|
||||||
|
|
||||||
Avant d'être prêt à compiler vous allez devoir [installer un environnement](getting_started_build_tools.md) pour les développements AVR et/ou ARM. Une fois ceci fait, vous pourrez utiliser la commande `make` pour compiler le clavier et la disposition avec une commande de ce type :
|
Avant d'être prêt à compiler vous allez devoir [installer un environnement](fr-fr/getting_started_build_tools.md) pour les développements AVR et/ou ARM. Une fois ceci fait, vous pourrez utiliser la commande `make` pour compiler le clavier et la disposition avec une commande de ce type :
|
||||||
|
|
||||||
make planck/rev4:default
|
make planck/rev4:default
|
||||||
|
|
||||||
@@ -29,4 +29,4 @@ Cette commande compilera la révision `rev4` du clavier `planck` avec la disposi
|
|||||||
|
|
||||||
## Comment le personnaliser
|
## Comment le personnaliser
|
||||||
|
|
||||||
QMK a beaucoup de [fonctionnalités](features.md) à explorer, et [une documentation](http://docs.qmk.fm) très abondante que vous pourrez parcourir. La plupart des fonctionnalités vous permettrons de modifier vos [dispositions](keymap.md) (keymaps) et de changer [les codes de caractères](keycodes.md) (keycodes).
|
QMK a beaucoup de [fonctionnalités](fr-fr/features.md) à explorer, et [une documentation](http://docs.qmk.fm) très abondante que vous pourrez parcourir. La plupart des fonctionnalités vous permettrons de modifier vos [dispositions](fr-fr/keymap.md) (keymaps) et de changer [les codes de caractères](fr-fr/keycodes.md) (keycodes).
|
||||||
+81
-81
@@ -29,97 +29,97 @@
|
|||||||
**En Anglais**
|
**En Anglais**
|
||||||
|
|
||||||
* Guides détaillés
|
* Guides détaillés
|
||||||
* [Installation des outils de compilation](getting_started_build_tools.md)
|
* [Installation des outils de compilation](fr-fr/getting_started_build_tools.md)
|
||||||
* [Guide Vagrant](getting_started_vagrant.md)
|
* [Guide Vagrant](fr-fr/getting_started_vagrant.md)
|
||||||
* [Commandes de compilations](getting_started_make_guide.md)
|
* [Commandes de compilations](fr-fr/getting_started_make_guide.md)
|
||||||
* [Flasher les firmwares](fr-fr/flashing.md)
|
* [Flasher les firmwares](fr-fr/flashing.md)
|
||||||
* [Personnaliser les fonctionnalités](custom_quantum_functions.md)
|
* [Personnaliser les fonctionnalités](fr-fr/custom_quantum_functions.md)
|
||||||
* [Aperçu des fonctionnalités des dispositions](keymap.md)
|
* [Aperçu des fonctionnalités des dispositions](fr-fr/keymap.md)
|
||||||
|
|
||||||
* [Hardware](hardware.md)
|
* [Hardware](fr-fr/hardware.md)
|
||||||
* [Processeurs AVR](hardware_avr.md)
|
* [Processeurs AVR](fr-fr/hardware_avr.md)
|
||||||
* [Pilotes / Drivers](hardware_drivers.md)
|
* [Pilotes / Drivers](fr-fr/hardware_drivers.md)
|
||||||
|
|
||||||
* Réferences
|
* Réferences
|
||||||
* [Lignes de conduite des claviers](hardware_keyboard_guidelines.md)
|
* [Lignes de conduite des claviers](fr-fr/hardware_keyboard_guidelines.md)
|
||||||
* [Options de configurations](config_options.md)
|
* [Options de configurations](fr-fr/config_options.md)
|
||||||
* [Keycodes / Codes des caractères](keycodes.md)
|
* [Keycodes / Codes des caractères](fr-fr/keycodes.md)
|
||||||
* [Conventions de codage - C](coding_conventions_c.md)
|
* [Conventions de codage - C](fr-fr/coding_conventions_c.md)
|
||||||
* [Conventions de codage - Python](coding_conventions_python.md)
|
* [Conventions de codage - Python](fr-fr/coding_conventions_python.md)
|
||||||
* [Meilleurs pratiques sur la documentation](documentation_best_practices.md)
|
* [Meilleurs pratiques sur la documentation](fr-fr/documentation_best_practices.md)
|
||||||
* [Modèles de documentation](documentation_templates.md)
|
* [Modèles de documentation](fr-fr/documentation_templates.md)
|
||||||
* [Glossaire](reference_glossary.md)
|
* [Glossaire](fr-fr/reference_glossary.md)
|
||||||
* [Tests unitaires](unit_testing.md)
|
* [Tests unitaires](fr-fr/unit_testing.md)
|
||||||
* [Fonctions utiles](ref_functions.md)
|
* [Fonctions utiles](fr-fr/ref_functions.md)
|
||||||
* [Support de configuration](reference_configurator_support.md)
|
* [Support de configuration](fr-fr/reference_configurator_support.md)
|
||||||
* [Format du fichier info.json](reference_info_json.md)
|
* [Format du fichier info.json](fr-fr/reference_info_json.md)
|
||||||
* [Développer la CLI en Python](cli_development.md)
|
* [Développer la CLI en Python](fr-fr/cli_development.md)
|
||||||
|
|
||||||
* [Fonctionnalités](features.md)
|
* [Fonctionnalités](fr-fr/features.md)
|
||||||
* [Keycodes basiques](keycodes_basic.md)
|
* [Keycodes basiques](fr-fr/keycodes_basic.md)
|
||||||
* [Touches utilisées avec Shift (US ANSI)](keycodes_us_ansi_shifted.md)
|
* [Touches utilisées avec Shift (US ANSI)](fr-fr/keycodes_us_ansi_shifted.md)
|
||||||
* [Keycodes quantiques](quantum_keycodes.md)
|
* [Keycodes quantiques](fr-fr/quantum_keycodes.md)
|
||||||
* [Keycodes avancés](feature_advanced_keycodes.md)
|
* [Keycodes avancés](fr-fr/feature_advanced_keycodes.md)
|
||||||
* [Fonctionnalités audio](feature_audio.md)
|
* [Fonctionnalités audio](fr-fr/feature_audio.md)
|
||||||
* [Majuscule automatique](feature_auto_shift.md)
|
* [Majuscule automatique](fr-fr/feature_auto_shift.md)
|
||||||
* [Rétroéclairage](feature_backlight.md)
|
* [Rétroéclairage](fr-fr/feature_backlight.md)
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
* [Bluetooth](fr-fr/feature_bluetooth.md)
|
||||||
* [Bootmagic](feature_bootmagic.md)
|
* [Bootmagic](fr-fr/feature_bootmagic.md)
|
||||||
* [Combos](feature_combo.md)
|
* [Combos](fr-fr/feature_combo.md)
|
||||||
* [Commande](feature_command.md)
|
* [Commande](fr-fr/feature_command.md)
|
||||||
* [API anti-rebond](feature_debounce_type.md)
|
* [API anti-rebond](fr-fr/feature_debounce_type.md)
|
||||||
* [DIP Switch](feature_dip_switch.md)
|
* [DIP Switch](fr-fr/feature_dip_switch.md)
|
||||||
* [Macros dynamiques](feature_dynamic_macros.md)
|
* [Macros dynamiques](fr-fr/feature_dynamic_macros.md)
|
||||||
* [Interrupteurs rotatifs](feature_encoders.md)
|
* [Interrupteurs rotatifs](fr-fr/feature_encoders.md)
|
||||||
* [Grave Escape](feature_grave_esc.md)
|
* [Grave Escape](fr-fr/feature_grave_esc.md)
|
||||||
* [Retour haptique](feature_haptic_feedback.md)
|
* [Retour haptique](fr-fr/feature_haptic_feedback.md)
|
||||||
* [Contrôleur LCD HD44780](feature_hd44780.md)
|
* [Contrôleur LCD HD44780](fr-fr/feature_hd44780.md)
|
||||||
* [Touche à verrou / Lock-key](feature_key_lock.md)
|
* [Touche à verrou / Lock-key](fr-fr/feature_key_lock.md)
|
||||||
* [Dispositions / layouts](feature_layouts.md)
|
* [Dispositions / layouts](fr-fr/feature_layouts.md)
|
||||||
* [Touche leader](feature_leader_key.md)
|
* [Touche leader](fr-fr/feature_leader_key.md)
|
||||||
* [Matrice LED](feature_led_matrix.md)
|
* [Matrice LED](fr-fr/feature_led_matrix.md)
|
||||||
* [Macros](feature_macros.md)
|
* [Macros](fr-fr/feature_macros.md)
|
||||||
* [Boutons de souris](feature_mouse_keys.md)
|
* [Boutons de souris](fr-fr/feature_mouse_keys.md)
|
||||||
* [Pilotes / Drivers OLED](feature_oled_driver.md)
|
* [Pilotes / Drivers OLED](fr-fr/feature_oled_driver.md)
|
||||||
* [Touche one-shot](feature_advanced_keycodes.md#one-shot-keys)
|
* [Touche one-shot](fr-fr/one_shot_keys.md)
|
||||||
* [Périphériques de pointage](feature_pointing_device.md)
|
* [Périphériques de pointage](fr-fr/feature_pointing_device.md)
|
||||||
* [Souris PS/2](feature_ps2_mouse.md)
|
* [Souris PS/2](fr-fr/feature_ps2_mouse.md)
|
||||||
* [Éclairage RGB](feature_rgblight.md)
|
* [Éclairage RGB](fr-fr/feature_rgblight.md)
|
||||||
* [Matrice RGB](feature_rgb_matrix.md)
|
* [Matrice RGB](fr-fr/feature_rgb_matrix.md)
|
||||||
* [Space Cadet](feature_space_cadet.md)
|
* [Space Cadet](fr-fr/feature_space_cadet.md)
|
||||||
* [Claviers scindés / splittés](feature_split_keyboard.md)
|
* [Claviers scindés / splittés](fr-fr/feature_split_keyboard.md)
|
||||||
* [Stenographie](feature_stenography.md)
|
* [Stenographie](fr-fr/feature_stenography.md)
|
||||||
* [Inversion des mains](feature_swap_hands.md)
|
* [Inversion des mains](fr-fr/feature_swap_hands.md)
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
* [Tap Dance](fr-fr/feature_tap_dance.md)
|
||||||
* [Terminale](feature_terminal.md)
|
* [Terminale](fr-fr/feature_terminal.md)
|
||||||
* [Imprimante thermique](feature_thermal_printer.md)
|
* [Imprimante thermique](fr-fr/feature_thermal_printer.md)
|
||||||
* [Caractères unicodes](feature_unicode.md)
|
* [Caractères unicodes](fr-fr/feature_unicode.md)
|
||||||
* [Dossier utilisateur](feature_userspace.md)
|
* [Dossier utilisateur](fr-fr/feature_userspace.md)
|
||||||
* [Velocikey](feature_velocikey.md)
|
* [Velocikey](fr-fr/feature_velocikey.md)
|
||||||
|
|
||||||
* Pour les makers et les bricoleurs
|
* Pour les makers et les bricoleurs
|
||||||
* [Guide des claviers soudés à la main](hand_wire.md)
|
* [Guide des claviers soudés à la main](fr-fr/hand_wire.md)
|
||||||
* [Guide de flash de l’ISP](isp_flashing_guide.md)
|
* [Guide de flash de l’ISP](fr-fr/isp_flashing_guide.md)
|
||||||
* [Guide du débogage ARM](arm_debugging.md)
|
* [Guide du débogage ARM](fr-fr/arm_debugging.md)
|
||||||
* [Drivers i2c](i2c_driver.md)
|
* [Drivers i2c](fr-fr/i2c_driver.md)
|
||||||
* [Contrôles des GPIO](internals_gpio_control.md)
|
* [Contrôles des GPIO](fr-fr/internals_gpio_control.md)
|
||||||
* [Conversion en Proton C](proton_c_conversion.md)
|
* [Conversion en Proton C](fr-fr/proton_c_conversion.md)
|
||||||
|
|
||||||
* Pour aller plus loin
|
* Pour aller plus loin
|
||||||
* [Comment fonctionnent les claviers](how_keyboards_work.md)
|
* [Comment fonctionnent les claviers](fr-fr/how_keyboards_work.md)
|
||||||
* [Comprendre QMK](understanding_qmk.md)
|
* [Comprendre QMK](fr-fr/understanding_qmk.md)
|
||||||
|
|
||||||
* Autres sujets
|
* Autres sujets
|
||||||
* [Utiliser Eclipse avec QMK](other_eclipse.md)
|
* [Utiliser Eclipse avec QMK](fr-fr/other_eclipse.md)
|
||||||
* [Utiliser VSCode avec QMK](other_vscode.md)
|
* [Utiliser VSCode avec QMK](fr-fr/other_vscode.md)
|
||||||
* [Support](support.md)
|
* [Support](fr-fr/getting_started_getting_help.md)
|
||||||
* [Comment ajouter des traductions](translating.md)
|
* [Comment ajouter des traductions](fr-fr/translating.md)
|
||||||
|
|
||||||
* À l’intérieur de QMK (En cours de documentation)
|
* À l’intérieur de QMK (En cours de documentation)
|
||||||
* [Définitions](internals_defines.md)
|
* [Définitions](fr-fr/internals_defines.md)
|
||||||
* [Input Callback Reg](internals_input_callback_reg.md)
|
* [Input Callback Reg](fr-fr/internals_input_callback_reg.md)
|
||||||
* [Appareils Midi](internals_midi_device.md)
|
* [Appareils Midi](fr-fr/internals_midi_device.md)
|
||||||
* [Installation d’un appareil Midi](internals_midi_device_setup_process.md)
|
* [Installation d’un appareil Midi](fr-fr/internals_midi_device_setup_process.md)
|
||||||
* [Utilitaires Midi](internals_midi_util.md)
|
* [Utilitaires Midi](fr-fr/internals_midi_util.md)
|
||||||
* [Fonctions Midi](internals_send_functions.md)
|
* [Fonctions Midi](fr-fr/internals_send_functions.md)
|
||||||
* [Outils Sysex](internals_sysex_tools.md)
|
* [Outils Sysex](fr-fr/internals_sysex_tools.md)
|
||||||
@@ -86,10 +86,6 @@ Relancer le script d'installation de QMK (`./util/qmk_install.sh` situé dans r
|
|||||||
|
|
||||||
Si vous rencontrez toujours des problèmes, essayez de télécharger et lancer Zadig. Voir [Installation du driver du bootloader avec Zadig](driver_installation_zadig.md) pour plus d'informations.
|
Si vous rencontrez toujours des problèmes, essayez de télécharger et lancer Zadig. Voir [Installation du driver du bootloader avec Zadig](driver_installation_zadig.md) pour plus d'informations.
|
||||||
|
|
||||||
## WINAVR est obsolète
|
|
||||||
|
|
||||||
Il n'est plus recommandé et peut causer des problèmes. Voir [TMK Issue #99](https://github.com/tmk/tmk_keyboard/issues/99).
|
|
||||||
|
|
||||||
## USB VID et PID
|
## USB VID et PID
|
||||||
|
|
||||||
Vous pouvez utiliser l'ID de votre choix en modifier `config.h`. Il y a peu de chance de conflit avec d'autres produits.
|
Vous pouvez utiliser l'ID de votre choix en modifier `config.h`. Il y a peu de chance de conflit avec d'autres produits.
|
||||||
@@ -103,30 +99,6 @@ Vous pouvez acheter un VID:PID unique ici. Je ne pense pas que ce soit nécessai
|
|||||||
- http://www.obdev.at/products/vusb/license.html
|
- http://www.obdev.at/products/vusb/license.html
|
||||||
- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1
|
- http://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1
|
||||||
|
|
||||||
## Cortex: `cstddef: No such file or directory`
|
|
||||||
|
|
||||||
Ce problème existait avec le GCC 4.8 d'Ubuntu 14.04, la solution a nécessité de mettre à jour vers 4.9 avec ce PPA.
|
|
||||||
https://launchpad.net/~terry.guo/+archive/ubuntu/gcc-arm-embedded
|
|
||||||
|
|
||||||
https://github.com/tmk/tmk_keyboard/issues/212
|
|
||||||
https://github.com/tmk/tmk_keyboard/wiki/mbed-cortex-porting#compile-error-cstddef
|
|
||||||
https://developer.mbed.org/forum/mbed/topic/5205/
|
|
||||||
|
|
||||||
## `clock_prescale_set` and `clock_div_1` Not Available
|
|
||||||
|
|
||||||
Votre chaîne d'outils (Toolchain) est trop vieille pour supporter le MCU. Par exemple, WinAVR 20100110 ne supporte pas ATMega32u2.
|
|
||||||
|
|
||||||
```
|
|
||||||
Compiling C: ../../tmk_core/protocol/lufa/lufa.c
|
|
||||||
avr-gcc -c -mmcu=atmega32u2 -gdwarf-2 -DF_CPU=16000000UL -DINTERRUPT_CONTROL_ENDPOINT -DBOOTLOADER_SIZE=4096 -DF_USB=16000000UL -DARCH=ARCH_AVR8 -DUSB_DEVICE_ONLY -DUSE_FLASH_DESCRIPTORS -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DFIXED_NUM_CONFIGURATIONS=1 -DPROTOCOL_LUFA -DEXTRAKEY_ENABLE -DCONSOLE_ENABLE -DCOMMAND_ENABLE -DVERSION=unknown -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fdata-sections -fno-inline-small-functions -fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Wstrict-prototypes -Wa,-adhlns=obj_alps64/protocol/lufa/lufa.lst -I. -I../../tmk_core -I../../tmk_core/protocol/lufa -I../../tmk_core/protocol/lufa/LUFA-git -I../../tmk_core/common -std=gnu99 -include config.h -MMD -MP -MF .dep/obj_alps64_protocol_lufa_lufa.o.d ../../tmk_core/protocol/lufa/lufa.c -o obj_alps64/protocol/lufa/lufa.o
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c: In function 'setup_mcu':
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: warning: implicit declaration of function 'clock_prescale_set'
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: 'clock_div_1' undeclared (first use in this function)
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: (Each undeclared identifier is reported only once
|
|
||||||
../../tmk_core/protocol/lufa/lufa.c:575: error: for each function it appears in.)
|
|
||||||
make: *** [obj_alps64/protocol/lufa/lufa.o] Error 1
|
|
||||||
```
|
|
||||||
|
|
||||||
## BOOTLOADER_SIZE pour AVR
|
## BOOTLOADER_SIZE pour AVR
|
||||||
|
|
||||||
Notez que la taille du bootloader pour les Teensy2.0++ est de 2048bytes. Quelques Makefiles peuvent contenir une erreur et avoir le mauvais commentaire.
|
Notez que la taille du bootloader pour les Teensy2.0++ est de 2048bytes. Quelques Makefiles peuvent contenir une erreur et avoir le mauvais commentaire.
|
||||||
|
|||||||
@@ -104,58 +104,6 @@ En C, `1` implique un type [int] qui est [16 bits] pour les AVR, ce qui implique
|
|||||||
|
|
||||||
http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279
|
http://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279
|
||||||
|
|
||||||
## Bootloader Jump ne fonctionne pas
|
|
||||||
|
|
||||||
Configurez correctement la taille du bootloader dans le **Makefile**. Une mauvaise taille de section du bootloader empêchera probablement le démarrage avec **Magic command** et **Boot Magic**.
|
|
||||||
|
|
||||||
```
|
|
||||||
# Size of Bootloaders in bytes:
|
|
||||||
# Atmel DFU loader(ATmega32U4) 4096
|
|
||||||
# Atmel DFU loader(AT90USB128) 8192
|
|
||||||
# LUFA bootloader(ATmega32U4) 4096
|
|
||||||
# Arduino Caterina(ATmega32U4) 4096
|
|
||||||
# USBaspLoader(ATmega***) 2048
|
|
||||||
# Teensy halfKay(ATmega32U4) 512
|
|
||||||
# Teensy++ halfKay(AT90USB128) 2048
|
|
||||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
|
||||||
```
|
|
||||||
|
|
||||||
La taille de la section de démarrage de AVR est définie par l'option **BOOTSZ** fuse. Vérifiez la fiche technique du MCU. Veuilez noter que les tailles et adresses sont définies en **Word** (2 octets) dans la fiche technique alors que TMK utilise des **Byte**.
|
|
||||||
|
|
||||||
La section de boot AVR se trouve à la fin de la mémoire flash, comme suit.
|
|
||||||
|
|
||||||
```
|
|
||||||
byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB1286)
|
|
||||||
0x0000 +---------------+ 0x00000 +---------------+
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| Application | | Application |
|
|
||||||
| | | |
|
|
||||||
= = = =
|
|
||||||
| | 32KB-4KB | | 128KB-8KB
|
|
||||||
0x6000 +---------------+ 0x1E000 +---------------+
|
|
||||||
| Bootloader | 4KB | Bootloader | 8KB
|
|
||||||
0x7FFF +---------------+ 0x1FFFF +---------------+
|
|
||||||
|
|
||||||
|
|
||||||
byte Teensy(ATMega32u4) byte Teensy++(AT90SUB1286)
|
|
||||||
0x0000 +---------------+ 0x00000 +---------------+
|
|
||||||
| | | |
|
|
||||||
| | | |
|
|
||||||
| Application | | Application |
|
|
||||||
| | | |
|
|
||||||
= = = =
|
|
||||||
| | 32KB-512B | | 128KB-2KB
|
|
||||||
0x7E00 +---------------+ 0x1FC00 +---------------+
|
|
||||||
| Bootloader | 512B | Bootloader | 2KB
|
|
||||||
0x7FFF +---------------+ 0x1FFFF +---------------+
|
|
||||||
```
|
|
||||||
|
|
||||||
Référez-vous à cette discussion pour plus de référence.
|
|
||||||
https://github.com/tmk/tmk_keyboard/issues/179
|
|
||||||
|
|
||||||
Si vous utilisez un TeensyUSB, il y a un [bug connu](https://github.com/qmk/qmk_firmware/issues/164) qui fait que le bouton reset matériel empêche la touche RESET de fonctionner. Débrancher et rebrancher le clavier devrait résoudre le problème.
|
|
||||||
|
|
||||||
## Les touches spéciales ne fonctionnent pas (Touche Système, Touches de contrôle du son)
|
## Les touches spéciales ne fonctionnent pas (Touche Système, Touches de contrôle du son)
|
||||||
|
|
||||||
Vous devez définir `EXTRAKEY_ENABLE` dans le fichier `rules.mk` pour les utiliser dans QMK.
|
Vous devez définir `EXTRAKEY_ENABLE` dans le fichier `rules.mk` pour les utiliser dans QMK.
|
||||||
@@ -189,25 +137,6 @@ Si vous voulez garder JTAG activé, ajoutez la ligne suivante à votre fichier `
|
|||||||
#define NO_JTAG_DISABLE
|
#define NO_JTAG_DISABLE
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding LED Indicators of Lock Keys
|
|
||||||
|
|
||||||
Si vous souhaitez votre propre indicateur LED pour CapsLock, ScrollLock et NumLock alors lisez ce post.
|
|
||||||
|
|
||||||
http://deskthority.net/workshop-f7/tmk-keyboard-firmware-collection-t4478-120.html#p191560
|
|
||||||
|
|
||||||
## Programmer Arduino Micro/Leonardo
|
|
||||||
|
|
||||||
Appuyez sur le bouton reset puis lancez la commande suivante dans les 8 secondes.
|
|
||||||
|
|
||||||
```
|
|
||||||
avrdude -patmega32u4 -cavr109 -b57600 -Uflash:w:adb_usb.hex -P/dev/ttyACM0
|
|
||||||
```
|
|
||||||
|
|
||||||
Le nom du périphérique peut varier en fonction de votre système.
|
|
||||||
|
|
||||||
http://arduino.cc/en/Main/ArduinoBoardMicro
|
|
||||||
https://geekhack.org/index.php?topic=14290.msg1563867#msg1563867
|
|
||||||
|
|
||||||
## Compatibilité USB 3
|
## Compatibilité USB 3
|
||||||
|
|
||||||
Il semble que certaines personnes ont eu des problèmes avec les ports USB 3, essayez un port USB 2.
|
Il semble que certaines personnes ont eu des problèmes avec les ports USB 3, essayez un port USB 2.
|
||||||
|
|||||||
@@ -72,24 +72,7 @@ Des vieux claviers mécaniques ont parfois des touches à verrouillage, mais les
|
|||||||
|
|
||||||
## Ajouter des caractères spéciaux autres que ASCII comme la cédille 'Ç'
|
## Ajouter des caractères spéciaux autres que ASCII comme la cédille 'Ç'
|
||||||
|
|
||||||
IL N'EXISTE AUCUNE METHODE UNIVERSELLE POUR LES AJOUTER QUI FONCTIONNE SUR TOUS LES SYSTEMES. Vous devez définir une **MACRO** d'une manière spécifique à votre OS ou layout.
|
Voir la fonctionnalité [Unicode](feature_unicode.md).
|
||||||
|
|
||||||
Voir ce post pour un exemple de code **MACRO**.
|
|
||||||
|
|
||||||
http://deskthority.net/workshop-f7/tmk-keyboard-firmware-collection-t4478-120.html#p195620
|
|
||||||
|
|
||||||
Sous **Windows** vous pouvez utiliser la touche `AltGr` ou **Alt code**.
|
|
||||||
* http://en.wikipedia.org/wiki/AltGr_key
|
|
||||||
* http://en.wikipedia.org/wiki/Alt_code
|
|
||||||
|
|
||||||
Sous **Mac OS** définissez une combinaison de touche `Option`.
|
|
||||||
* http://en.wikipedia.org/wiki/Option_key#Alternative_keyboard_input
|
|
||||||
|
|
||||||
Sous **Xorg** vous pouvez utiliser une touche `compose` à la place.
|
|
||||||
* http://en.wikipedia.org/wiki/Compose_key
|
|
||||||
|
|
||||||
Et voir ceci pour une entrée **Unicode**.
|
|
||||||
* http://en.wikipedia.org/wiki/Unicode_input
|
|
||||||
|
|
||||||
## Touche `Fn` sur macOS
|
## Touche `Fn` sur macOS
|
||||||
|
|
||||||
@@ -144,54 +127,6 @@ Cette fonctionnalité permet d'utiliser une touche à la fois comme touche Écha
|
|||||||
|
|
||||||
Voir la fonctionnalité [Grave Escape](feature_grave_esc.md).
|
Voir la fonctionnalité [Grave Escape](feature_grave_esc.md).
|
||||||
|
|
||||||
## Avoir les touches modificatrices qui ont double usage en flèches directionnelles.
|
|
||||||
|
|
||||||
Ceci transforme les touches "modificateur droit" en touches fléchées lorsque les touches sont seulement "tapées" tout en restant des modificateurs lorsqu'elles sont maintenues.
|
|
||||||
|
|
||||||
Dans TMK la fonction double rôle s'appelle **TAP**.
|
|
||||||
|
|
||||||
```C
|
|
||||||
|
|
||||||
#include "keymap_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Arrow keys on right modifier keys with TMK dual role feature
|
|
||||||
*
|
|
||||||
* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#213-modifier-with-tap-keydual-role
|
|
||||||
* https://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
|
|
||||||
*/
|
|
||||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
||||||
/* 0: qwerty */
|
|
||||||
[0] = LAYOUT( \
|
|
||||||
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, NUHS,BSPC, \
|
|
||||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, \
|
|
||||||
LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, \
|
|
||||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH,FN0, ESC, \
|
|
||||||
FN4, LGUI,LALT, SPC, APP, FN2, FN1, FN3),
|
|
||||||
[1] = LAYOUT( \
|
|
||||||
GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS,TRNS, \
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,\
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, \
|
|
||||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,FN5, TRNS, \
|
|
||||||
TRNS,TRNS,TRNS, TRNS, TRNS,FN7, FN6, FN8),
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint16_t PROGMEM fn_actions[] = {
|
|
||||||
[0] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_UP),
|
|
||||||
[1] = ACTION_MODS_TAP_KEY(MOD_RGUI, KC_DOWN),
|
|
||||||
[2] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_LEFT),
|
|
||||||
[3] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_RIGHT),
|
|
||||||
[4] = ACTION_LAYER_MOMENTARY(1),
|
|
||||||
[5] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_PGUP),
|
|
||||||
[6] = ACTION_MODS_TAP_KEY(MOD_RGUI, KC_PGDN),
|
|
||||||
[7] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_HOME),
|
|
||||||
[8] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_END),
|
|
||||||
};
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Touches double rôle : https://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
|
|
||||||
|
|
||||||
## Eject sur Mac OSX
|
## Eject sur Mac OSX
|
||||||
|
|
||||||
Le keycode`KC_EJCT` fonctionne sous OSX. https://github.com/tmk/tmk_keyboard/issues/250
|
Le keycode`KC_EJCT` fonctionne sous OSX. https://github.com/tmk/tmk_keyboard/issues/250
|
||||||
|
|||||||
@@ -16,17 +16,23 @@ Faites attention à sélectionner "HTTPS", et sélectionnez le lien et copiez-le
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Ensuite, entrez `git clone` dans la ligne de commande, et collez votre lien:
|
Ensuite, entrez `git clone --recurse-submodules ` dans la ligne de commande, et collez votre lien:
|
||||||
|
|
||||||
```
|
```
|
||||||
user@computer:~$ git clone https://github.com/whoeveryouare/qmk_firmware.git
|
user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git
|
||||||
Cloning into 'qmk_firmware'...
|
Cloning into 'qmk_firmware'...
|
||||||
remote: Counting objects: 46625, done.
|
remote: Enumerating objects: 9, done.
|
||||||
remote: Compressing objects: 100% (2/2), done.
|
remote: Counting objects: 100% (9/9), done.
|
||||||
remote: Total 46625 (delta 0), reused 0 (delta 0), pack-reused 46623
|
remote: Compressing objects: 100% (5/5), done.
|
||||||
Receiving objects: 100% (46625/46625), 84.47 MiB | 3.14 MiB/s, done.
|
remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874
|
||||||
Resolving deltas: 100% (29362/29362), done.
|
Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done.
|
||||||
Checking out files: 100% (2799/2799), done.
|
Resolving deltas: 100% (119972/119972), done.
|
||||||
|
...
|
||||||
|
Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b'
|
||||||
|
Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486'
|
||||||
|
Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780'
|
||||||
|
Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d'
|
||||||
|
Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2'
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous avez maintenant votre fork QMK sur votre machine locale, vous pouvez ajouter votre keymap, la compiler et la flasher sur votre board. Une fois heureux avec vos changements, vous pouvez les ajouter, commit, et pousser vers votre fork comme suit:
|
Vous avez maintenant votre fork QMK sur votre machine locale, vous pouvez ajouter votre keymap, la compiler et la flasher sur votre board. Une fois heureux avec vos changements, vous pouvez les ajouter, commit, et pousser vers votre fork comme suit:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Le but de cette page est d'expliquer les informations de base qui vous serons n
|
|||||||
|
|
||||||
## Structure de base de QMK
|
## Structure de base de QMK
|
||||||
|
|
||||||
QMK est un fork du projet [tmk_keyboard](https://github.com/tmk/tmk_keyboard) créé par [Jun Wako](https://github.com/tmk). Le code originel de TMK, avec quelques modifications, se trouve dans le dossier `tmk`. Les additions que QMK amène au projet se trouvent dans le dossier `quantum`. Les projets de clavier se trouvent dans les dossiers `handwired` et `keyboard`.
|
QMK est un fork du projet [tmk_keyboard](https://github.com/tmk/tmk_keyboard) créé par [Jun Wako](https://github.com/tmk). Le code originel de TMK, avec quelques modifications, se trouve dans le dossier `tmk_core`. Les additions que QMK amène au projet se trouvent dans le dossier `quantum`. Les projets de clavier se trouvent dans les dossiers `handwired` et `keyboard`.
|
||||||
|
|
||||||
### Structure du Userspace
|
### Structure du Userspace
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Le [Configurateur de QMK](https://config.qmk.fm) est une interface graphique en
|
|||||||
|
|
||||||
?> **S'il vous plaît, suivez les étapes suivantes dans l'ordre.**
|
?> **S'il vous plaît, suivez les étapes suivantes dans l'ordre.**
|
||||||
|
|
||||||
Regardez le [Tutoriel vidéo](https://youtu.be/tx54jkRC9ZY)
|
Regardez le [Tutoriel vidéo](https://youtu.be/tx54jkRC9ZY)https://www.youtube.com/watch?v=-imgglzDMdY)
|
||||||
|
|
||||||
Le configurateur de QMK fonctionne mieux avec Chrome et Firefox.
|
Le configurateur de QMK fonctionne mieux avec Chrome et Firefox.
|
||||||
|
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
# Installing Build Tools
|
|
||||||
|
|
||||||
This page describes setting up the build environment for QMK. These instructions cover AVR processors (such as the atmega32u4).
|
|
||||||
|
|
||||||
<!-- FIXME: We should have ARM instructions somewhere. -->
|
|
||||||
|
|
||||||
**Note:** If this is your first time here, check out the [Complete Newbs Guide](newbs.md) page.
|
|
||||||
|
|
||||||
Before continuing, double check that your submodules (third-party libraries) are up to date by running `make git-submodule`.
|
|
||||||
|
|
||||||
## Linux
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
The current requirements are the following, but not all might be needed depending on what you do. Also note that some systems might not have all the dependencies available as packages, or they might be named differently.
|
|
||||||
|
|
||||||
```
|
|
||||||
build-essential
|
|
||||||
gcc
|
|
||||||
unzip
|
|
||||||
wget
|
|
||||||
zip
|
|
||||||
gcc-avr
|
|
||||||
binutils-avr
|
|
||||||
avr-libc
|
|
||||||
dfu-programmer
|
|
||||||
dfu-util
|
|
||||||
gcc-arm-none-eabi
|
|
||||||
binutils-arm-none-eabi
|
|
||||||
libnewlib-arm-none-eabi
|
|
||||||
git
|
|
||||||
```
|
|
||||||
|
|
||||||
Install the dependencies with your favorite package manager.
|
|
||||||
|
|
||||||
Debian / Ubuntu example:
|
|
||||||
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install gcc unzip wget zip gcc-avr binutils-avr avr-libc dfu-programmer dfu-util gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi
|
|
||||||
|
|
||||||
Fedora / Red Hat example:
|
|
||||||
|
|
||||||
sudo dnf install gcc unzip wget zip dfu-util dfu-programmer avr-gcc avr-libc binutils-avr32-linux-gnu arm-none-eabi-gcc-cs arm-none-eabi-binutils-cs arm-none-eabi-newlib
|
|
||||||
|
|
||||||
Arch / Manjaro example:
|
|
||||||
|
|
||||||
pacman -S base-devel gcc unzip wget zip avr-gcc avr-binutils avr-libc dfu-util arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib git dfu-programmer dfu-util
|
|
||||||
|
|
||||||
## Nix
|
|
||||||
|
|
||||||
If you're on [NixOS](https://nixos.org/), or have Nix installed on Linux or macOS, run `nix-shell` from the repository root to get a build environment.
|
|
||||||
|
|
||||||
By default, this will download compilers for both AVR and ARM. If you don't need both, disable the `avr` or `arm` arguments, e.g.:
|
|
||||||
|
|
||||||
nix-shell --arg arm false
|
|
||||||
|
|
||||||
## macOS
|
|
||||||
If you're using [homebrew,](http://brew.sh/) you can use the following commands:
|
|
||||||
|
|
||||||
brew tap osx-cross/avr
|
|
||||||
brew tap PX4/homebrew-px4
|
|
||||||
brew update
|
|
||||||
brew install avr-gcc@8
|
|
||||||
brew link --force avr-gcc@8
|
|
||||||
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-gcc@8` can take over 20 minutes and exhibit high CPU usage.
|
|
||||||
|
|
||||||
## Windows with msys2 (recommended)
|
|
||||||
|
|
||||||
The best environment to use, for Windows Vista through any later version (tested on 7 and 10), is [msys2](http://www.msys2.org).
|
|
||||||
|
|
||||||
* 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 repository. For example, if it's in the root of your c drive:
|
|
||||||
* `$ cd /c/qmk_firmware`
|
|
||||||
* 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).
|
|
||||||
|
|
||||||
### Creators Update
|
|
||||||
If you have Windows 10 with Creators Update or later, you can build and flash the firmware directly. Before the Creators Update, only building was possible. If you don't have it yet or if are unsure, follow [these instructions](https://support.microsoft.com/en-us/instantanswers/d4efb316-79f0-1aa1-9ef3-dcada78f3fa0/get-the-windows-10-creators-update).
|
|
||||||
|
|
||||||
### Windows Subsystem for Linux
|
|
||||||
In addition to the Creators Update, you need Windows 10 Subystem for Linux, so install it following [these instructions](http://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/). If you already have the Windows 10 Subsystem for Linux from the Anniversary update it's recommended that you [upgrade](https://betanews.com/2017/04/14/upgrade-windows-subsystem-for-linux/) it to 16.04LTS, because some keyboards don't compile with the toolchains included in 14.04LTS. Note that you need to know what your are doing if you chose the `sudo do-release-upgrade` method.
|
|
||||||
|
|
||||||
### Git
|
|
||||||
If you already have cloned the repository on your Windows file system you can ignore this section.
|
|
||||||
|
|
||||||
You will need to clone the repository to your Windows file system using the normal Git for Windows and **not** the WSL Git. So if you haven't installed Git before, [download](https://git-scm.com/download/win) and install it. Then [set it up](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup), it's important that you setup the e-mail and user name, especially if you are planning to contribute.
|
|
||||||
|
|
||||||
Once Git is installed, open the Git Bash command and change the directory to where you want to clone QMK; note that you have to use forward slashes, and that your c drive is accessed like this `/c/path/to/where/you/want/to/go`. Then run `git clone --recurse-submodules https://github.com/qmk/qmk_firmware`, this will create a new folder `qmk_firmware` as a subfolder of the current one.
|
|
||||||
|
|
||||||
### Toolchain Setup
|
|
||||||
The Toolchain setup is done through the Windows Subsystem for Linux, and the process is fully automated. If you want to do everything manually, there are no other instructions than the scripts themselves, but you can always open issues and ask for more information.
|
|
||||||
|
|
||||||
1. Open "Bash On Ubuntu On Windows" from the start menu.
|
|
||||||
2. Go to the directory where you cloned `qmk_firmware`. Note that the paths start with `/mnt/` in the WSL, so you have to write for example `cd /mnt/c/path/to/qmk_firmware`.
|
|
||||||
3. Run `util/wsl_install.sh` and follow the on-screen instructions.
|
|
||||||
4. Close the Bash command window, and re-open it.
|
|
||||||
5. You are ready to compile and flash the firmware!
|
|
||||||
|
|
||||||
### Some Important Things to Keep in Mind
|
|
||||||
* You can run `util/wsl_install.sh` again to get all the newest updates.
|
|
||||||
* Your QMK repository need to be on a Windows file system path, since WSL can't run executables outside it.
|
|
||||||
* The WSL Git is **not** compatible with the Windows Git, so use the Windows Git Bash or a windows Git GUI for all Git operations
|
|
||||||
* You can edit files either inside WSL or normally using Windows, but note that if you edit makefiles or shell scripts, make sure you are using an editor that saves the files with Unix line endings. Otherwise the compilation might not work.
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
If this is a bit complex for you, Docker might be the turnkey solution you need. After installing [Docker CE](https://docs.docker.com/install/#supported-platforms), run the following command from the `qmk_firmware` directory to build a keyboard/keymap:
|
|
||||||
```bash
|
|
||||||
util/docker_build.sh keyboard:keymap
|
|
||||||
# For example: util/docker_build.sh ergodox_ez:steno
|
|
||||||
```
|
|
||||||
This will compile the desired keyboard/keymap and leave the resulting `.hex` or `.bin` file in the QMK directory for you to flash. If `:keymap` is omitted, the `default` keymap is used. Note that the parameter format is the same as when building with `make`.
|
|
||||||
|
|
||||||
You can also start the script without any parameters, in which case it will ask you to input the build parameters one by one, which you may find easier to use:
|
|
||||||
```bash
|
|
||||||
util/docker_build.sh
|
|
||||||
# Reads parameters as input (leave blank for defaults)
|
|
||||||
```
|
|
||||||
|
|
||||||
There is also support for building _and_ flashing the keyboard straight from Docker by specifying the `target` as well:
|
|
||||||
```bash
|
|
||||||
util/docker_build.sh keyboard:keymap:target
|
|
||||||
# For example: util/docker_build.sh planck/rev6:default:flash
|
|
||||||
```
|
|
||||||
If you're on Linux, this should work out of the box. On Windows and macOS, it requires [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) to be running. This is tedious to set up, so it's not recommended; use [QMK Toolbox](https://github.com/qmk/qmk_toolbox) instead.
|
|
||||||
|
|
||||||
!> Docker for Windows requires [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) to be enabled. This means that it cannot work on versions of Windows which don't have Hyper-V, such as Windows 7, Windows 8 and **Windows 10 Home**.
|
|
||||||
|
|
||||||
## Vagrant
|
|
||||||
If you have any problems building the firmware, you can try using a tool called Vagrant. It will set up a virtual computer with a known configuration that's ready-to-go for firmware building. OLKB does NOT host the files for this virtual computer. Details on how to set up Vagrant are in the [vagrant guide](getting_started_vagrant.md).
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# Getting Help
|
|
||||||
|
|
||||||
There are a lot of resources for getting help with QMK.
|
|
||||||
|
|
||||||
## Realtime Chat
|
|
||||||
|
|
||||||
You can find QMK developers and users on our main [Discord server](https://discord.gg/Uq7gcHh). There are specific channels in the server for chatting about the firmware, Toolbox, hardware, and configurator.
|
|
||||||
|
|
||||||
## OLKB Subreddit
|
|
||||||
|
|
||||||
The official QMK forum is [/r/olkb](https://reddit.com/r/olkb) on [reddit.com](https://reddit.com).
|
|
||||||
|
|
||||||
## Github Issues
|
|
||||||
|
|
||||||
You can open an [issue on GitHub](https://github.com/qmk/qmk_firmware/issues). This is especially handy when your issue will require long-term discussion or debugging.
|
|
||||||
@@ -16,17 +16,23 @@ 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:
|
From here, enter `git clone --recurse-submodules ` into the command line, and then paste your link:
|
||||||
|
|
||||||
```
|
```
|
||||||
user@computer:~$ git clone https://github.com/whoeveryouare/qmk_firmware.git
|
user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git
|
||||||
Cloning into 'qmk_firmware'...
|
Cloning into 'qmk_firmware'...
|
||||||
remote: Counting objects: 46625, done.
|
remote: Enumerating objects: 9, done.
|
||||||
remote: Compressing objects: 100% (2/2), done.
|
remote: Counting objects: 100% (9/9), done.
|
||||||
remote: Total 46625 (delta 0), reused 0 (delta 0), pack-reused 46623
|
remote: Compressing objects: 100% (5/5), done.
|
||||||
Receiving objects: 100% (46625/46625), 84.47 MiB | 3.14 MiB/s, done.
|
remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874
|
||||||
Resolving deltas: 100% (29362/29362), done.
|
Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done.
|
||||||
Checking out files: 100% (2799/2799), done.
|
Resolving deltas: 100% (119972/119972), done.
|
||||||
|
...
|
||||||
|
Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b'
|
||||||
|
Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486'
|
||||||
|
Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780'
|
||||||
|
Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d'
|
||||||
|
Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2'
|
||||||
```
|
```
|
||||||
|
|
||||||
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:
|
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:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This page attempts to explain the basic information you need to know to work wit
|
|||||||
|
|
||||||
## Basic QMK Structure
|
## Basic QMK Structure
|
||||||
|
|
||||||
QMK is a fork of [Jun Wako](https://github.com/tmk)'s [tmk_keyboard](https://github.com/tmk/tmk_keyboard) project. The original TMK code, with modifications, can be found in the `tmk` folder. The QMK additions to the project may be found in the `quantum` folder. Keyboard projects may be found in the `handwired` and `keyboard` folders.
|
QMK is a fork of [Jun Wako](https://github.com/tmk)'s [tmk_keyboard](https://github.com/tmk/tmk_keyboard) project. The original TMK code, with modifications, can be found in the `tmk_core` folder. The QMK additions to the project may be found in the `quantum` folder. Keyboard projects may be found in the `handwired` and `keyboard` folders.
|
||||||
|
|
||||||
### Userspace Structure
|
### Userspace Structure
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ To disable debug messages (*dprint*) and reduce the .hex file size, include `#de
|
|||||||
|
|
||||||
To disable print messages (*print*, *xprintf*) and user print messages (*uprint*) and reduce the .hex file size, include `#define NO_PRINT` in your `config.h` file.
|
To disable print messages (*print*, *xprintf*) and user print messages (*uprint*) and reduce the .hex file size, include `#define NO_PRINT` in your `config.h` file.
|
||||||
|
|
||||||
To disable print messages (*print*, *xprintf*) and **KEEP** user print messages (*uprint*), include `#define USER_PRINT` in your `config.h` file.
|
To disable print messages (*print*, *xprintf*) and **KEEP** user print messages (*uprint*), include `#define USER_PRINT` in your `config.h` file (do not also include `#define NO_PRINT` in this case).
|
||||||
|
|
||||||
To see the text, open `hid_listen` and enjoy looking at your printed messages.
|
To see the text, open `hid_listen` and enjoy looking at your printed messages.
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ As there is no standard split communication driver for ARM-based split keyboards
|
|||||||
|
|
||||||
`CUSTOM_MATRIX`
|
`CUSTOM_MATRIX`
|
||||||
|
|
||||||
Lets you replace the default matrix scanning routine with your own code. You will need to provide your own implementations of matrix_init() and matrix_scan().
|
Lets you replace the default matrix scanning routine with your own code. For further details, see the [Custom Matrix page](custom_matrix.md).
|
||||||
|
|
||||||
`DEBOUNCE_TYPE`
|
`DEBOUNCE_TYPE`
|
||||||
|
|
||||||
|
|||||||
+49
-291
@@ -1,114 +1,5 @@
|
|||||||
# Hand-Wiring Guide
|
# Hand-Wiring Guide
|
||||||
|
|
||||||
## Preamble: How a Keyboard Matrix Works (and why we need diodes)
|
|
||||||
|
|
||||||
The collapsible section below covers why keyboards are wired the way they are, as outlined in this guide. It isn't required reading to make your own hand wired keyboard, but provides background information.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
|
|
||||||
<summary>Click for details</summary>
|
|
||||||
|
|
||||||
Without a matrix circuit each switch would require its own wire directly to the controller.
|
|
||||||
|
|
||||||
Simply put, when the circuit is arranged in rows and columns, if a key is pressed, a column wire makes contact with a row wire and completes a circuit. The keyboard controller detects this closed circuit and registers it as a key press.
|
|
||||||
|
|
||||||
The microcontroller will be setup up via the firmware to send a logical 1 to the columns, one at a time, and read from the rows, all at once - this process is called matrix scanning. The matrix is a bunch of open switches that, by default, don't allow any current to pass through - the firmware will read this as no keys being pressed. As soon as you press one key down, the logical 1 that was coming from the column the keyswitch is attached to gets passed through the switch and to the corresponding row - check out the following 2x2 example:
|
|
||||||
|
|
||||||
Column 0 being scanned Column 1 being scanned
|
|
||||||
x x
|
|
||||||
col0 col1 col0 col1
|
|
||||||
| | | |
|
|
||||||
row0 ---(key0)---(key1) row0 ---(key0)---(key1)
|
|
||||||
| | | |
|
|
||||||
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
|
||||||
|
|
||||||
The `x` represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an `x`. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column.
|
|
||||||
|
|
||||||
When we press `key0`, `col0` gets connected to `row0`, so the values that the firmware receives for that row is `0b01` (the `0b` here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected:
|
|
||||||
|
|
||||||
Column 0 being scanned Column 1 being scanned
|
|
||||||
x x
|
|
||||||
col0 col1 col0 col1
|
|
||||||
| | | |
|
|
||||||
x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1)
|
|
||||||
| | | |
|
|
||||||
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
|
||||||
|
|
||||||
We can now see that `row0` has an `x`, so has the value of 1. As a whole, the data the firmware receives when `key0` is pressed is
|
|
||||||
|
|
||||||
col0: 0b01
|
|
||||||
col1: 0b00
|
|
||||||
│└row0
|
|
||||||
└row1
|
|
||||||
|
|
||||||
A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious:
|
|
||||||
|
|
||||||
Column 0 being scanned Column 1 being scanned
|
|
||||||
x x
|
|
||||||
col0 col1 col0 col1
|
|
||||||
| | | |
|
|
||||||
x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1)
|
|
||||||
| | | |
|
|
||||||
x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3)
|
|
||||||
|
|
||||||
Remember that this ^ is still connected to row1
|
|
||||||
|
|
||||||
The data we get from that is:
|
|
||||||
|
|
||||||
col0: 0b11
|
|
||||||
col1: 0b11
|
|
||||||
│└row0
|
|
||||||
└row1
|
|
||||||
|
|
||||||
Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this;
|
|
||||||
|
|
||||||
Column 0 being scanned Column 1 being scanned
|
|
||||||
x x
|
|
||||||
col0 col1 col0 col1
|
|
||||||
│ │ | │
|
|
||||||
(key0) (key1) (key0) (key1)
|
|
||||||
! │ ! │ ! | ! │
|
|
||||||
row0 ─────┴────────┘ │ row0 ─────┴────────┘ │
|
|
||||||
│ │ | │
|
|
||||||
(key2) (key3) (key2) (key3)
|
|
||||||
! ! ! !
|
|
||||||
row1 ─────┴────────┘ row1 ─────┴────────┘
|
|
||||||
|
|
||||||
In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|`
|
|
||||||
|
|
||||||
Now when we press the three keys, invoking what would be a ghosting scenario:
|
|
||||||
|
|
||||||
Column 0 being scanned Column 1 being scanned
|
|
||||||
x x
|
|
||||||
col0 col1 col0 col1
|
|
||||||
│ │ │ │
|
|
||||||
(┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1)
|
|
||||||
! │ ! │ ! │ ! │
|
|
||||||
x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
(key2) (┌─┘3) (key2) (┌─┘3)
|
|
||||||
! ! ! !
|
|
||||||
row1 ─────┴────────┘ x row1 ─────┴────────┘
|
|
||||||
|
|
||||||
Things act as they should! Which will get us the following data:
|
|
||||||
|
|
||||||
col0: 0b01
|
|
||||||
col1: 0b11
|
|
||||||
│└row0
|
|
||||||
└row1
|
|
||||||
|
|
||||||
The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS.
|
|
||||||
|
|
||||||
Further reading:
|
|
||||||
- [Wikipedia article](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit)
|
|
||||||
- [Deskthority article](https://deskthority.net/wiki/Keyboard_matrix)
|
|
||||||
- [Keyboard Matrix Help by Dave Dribin (2000)](https://www.dribin.org/dave/keyboard/one_html/)
|
|
||||||
- [How Key Matrices Works by PCBheaven](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (animated examples)
|
|
||||||
- [How keyboards work - QMK documentation](how_keyboards_work.md)
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
|
||||||
## Parts list
|
## Parts list
|
||||||
|
|
||||||
You will need: (where *x* is the number of keys on your planned keyboard)
|
You will need: (where *x* is the number of keys on your planned keyboard)
|
||||||
@@ -141,29 +32,29 @@ Start by installing the switches and stabilisers in the plate. Depending on the
|
|||||||
|
|
||||||
If you are following a pre-existing handwire guide (e.g. for the keyboards in the [handwire firmware section](https://github.com/qmk/qmk_firmware/tree/master/keyboards/handwired) you can skip this step, just ensure you wire the matrix as described.
|
If you are following a pre-existing handwire guide (e.g. for the keyboards in the [handwire firmware section](https://github.com/qmk/qmk_firmware/tree/master/keyboards/handwired) you can skip this step, just ensure you wire the matrix as described.
|
||||||
|
|
||||||
What you want to achieve is one leg from each switch being attached to the corresponding switches next to it (rows) and the other leg being attached to the switches above and below it (columns) and a diode to one of the legs, mosy commonly this will be the leg attached to the rows, and the diode will face away from it (Column to Row) i.e. with the wire furthest from the black line on the diode connected to the switch (as current will only travel in one direction through a diode)
|
What you want to achieve is one leg from each switch being attached to the corresponding switches next to it (rows) and the other leg being attached to the switches above and below it (columns) and a diode to one of the legs, mosy commonly this will be the leg attached to the rows, and the diode will face away from it (Column to Row) i.e. with the wire furthest from the black line on the diode connected to the switch (as current will only travel in one direction through a diode).
|
||||||
|
|
||||||
It is fairly simple to plan for an ortholinear keyboard (like a Planck).
|
It is fairly simple to plan for an ortholinear keyboard (like a Planck).
|
||||||
|
|
||||||

|

|
||||||
Image from [RoastPotatoes' "How to hand wire a Planck"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/)
|
Image from [RoastPotatoes' "How to hand wire a Planck"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/)
|
||||||
|
|
||||||
But the larger and more complicated your keyboard, the more complex the matrix. [Keyboard Firmware Builder](https://kbfirmware.com/) can help you plan your matrix layout (shown here with a basic fullsize ISO keyboard imported from [Keyboard Layout Editor](http://www.keyboard-layout-editor.com).
|
But the larger and more complicated your keyboard, the more complex the matrix. [Keyboard Firmware Builder](https://kbfirmware.com/) can help you plan your matrix layout (shown here with a basic fullsize ISO keyboard imported from [Keyboard Layout Editor](http://www.keyboard-layout-editor.com).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Bear in mind that the number of rows plus the number of columns can not exceed the number of I/O pins on your controller. So the fullsize matrix shown above would be possible on a Proton C or Teensy++, but not on a regular Teensy or Pro Micro
|
Bear in mind that the number of rows plus the number of columns can not exceed the number of I/O pins on your controller. So the fullsize matrix shown above would be possible on a Proton C or Teensy++, but not on a regular Teensy or Pro Micro.
|
||||||
|
|
||||||
#### Common Microcontroller Boards
|
### Common Microcontroller Boards
|
||||||
|
|
||||||
| Board | Controller | # I/O | Pinout |
|
| Board | Controller | # I/O | Pinout |
|
||||||
| :------------ |:-------------:| ------:| ------ |
|
| :------------ |:-------------:| ------:| ------ |
|
||||||
| Pro Micro* | ATmega32u4 | 20 | [link](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro#Teensy++_2.0) |
|
| Pro Micro* | ATmega32u4 | 20 | [link](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro#Teensy++_2.0) |
|
||||||
| Teensy 2.0 | ATmega32u4 | 25 | [link](https://www.pjrc.com/teensy/pinout.html) |
|
| Teensy 2.0 | ATmega32u4 | 25 | [link](https://www.pjrc.com/teensy/pinout.html) |
|
||||||
| [QMK Proton C](https://qmk.fm/proton-c/) | STM32F303xC | 36 | [link 1](https://i.imgur.com/RhtrAlc.png), [2](https://deskthority.net/wiki/QMK_Proton_C) |
|
| [QMK Proton C](https://qmk.fm/proton-c/) | STM32F303xC | 36 | [link 1](https://i.imgur.com/RhtrAlc.png), [2](https://deskthority.net/wiki/QMK_Proton_C) |
|
||||||
| Teensy++ 2.0 | AT90USB1286 | 46 | [link](https://www.pjrc.com/teensy/pinout.html#Teensy_2.0) |
|
| Teensy++ 2.0 | AT90USB1286 | 46 | [link](https://www.pjrc.com/teensy/pinout.html#Teensy_2.0) |
|
||||||
|
|
||||||
*Elite C is essentially the same as a pro micro with a USB-C instead of Micro-USB
|
*Elite C is essentially the same as a Pro Micro with a USB-C instead of Micro-USB
|
||||||
|
|
||||||
There are also a number of boards designed specifically for handwiring that mount directly to a small number of switches and offer pinouts for the rest. Though these are generally more expensive and may be more difficult to get hold of.
|
There are also a number of boards designed specifically for handwiring that mount directly to a small number of switches and offer pinouts for the rest. Though these are generally more expensive and may be more difficult to get hold of.
|
||||||
|
|
||||||
@@ -204,7 +95,7 @@ If you are planning a split keyboard (e.g. Dactyl) each half will require a cont
|
|||||||
|
|
||||||
There are a lot of soldering guides and tips available elsewhere but here are some of the most useful and relevant for hand wiring:
|
There are a lot of soldering guides and tips available elsewhere but here are some of the most useful and relevant for hand wiring:
|
||||||
|
|
||||||
To ensure a strong solder joint you want a good amount of contact between the solder and the 2 peices of metal you are connecting, a good way of doing this (though not required) is looping around pins or twisting wires together before applying solder.
|
To ensure a strong solder joint you want a good amount of contact between the solder and the two pieces of metal you are connecting. A good way of doing this (though not required) is looping around pins or twisting wires together before applying solder.
|
||||||
|
|
||||||
<img src="https://i.imgur.com/eHJjmnU.jpg" alt="Looped around rod" width="200"/> <img src="https://i.imgur.com/8nbxmmr.jpg?1" alt="Looped diode leg" width="200"/>
|
<img src="https://i.imgur.com/eHJjmnU.jpg" alt="Looped around rod" width="200"/> <img src="https://i.imgur.com/8nbxmmr.jpg?1" alt="Looped diode leg" width="200"/>
|
||||||
|
|
||||||
@@ -220,24 +111,11 @@ When you come to apply the solder, hold the soldering iron against the two surfa
|
|||||||
|
|
||||||
Don't hold the iron on the solder/joint longer than necessary. Heat will be conducted through the surfaces and can damage components (melt switch housings etc.). Also, solder contains flux, which aids in ["wetting"](https://en.m.wikipedia.org/wiki/Wetting). The longer heat is applied to the solder the more flux will evaporate meaning you may end up with a bad solder joint with peaks which, apart from looking bad, may also increase the risk of electrical shorts.
|
Don't hold the iron on the solder/joint longer than necessary. Heat will be conducted through the surfaces and can damage components (melt switch housings etc.). Also, solder contains flux, which aids in ["wetting"](https://en.m.wikipedia.org/wiki/Wetting). The longer heat is applied to the solder the more flux will evaporate meaning you may end up with a bad solder joint with peaks which, apart from looking bad, may also increase the risk of electrical shorts.
|
||||||
|
|
||||||
The following collapsible section describes in detail how to solder rows using the bent diode technique and columns using short lengths of wire.
|
#### Soldering the Diodes
|
||||||
|
|
||||||
<details>
|
Starting at the top-left switch, place the diode (with tweezers if you have them) on the switch so that the diode itself is vertically aligned, and the black line is facing toward you. The input lead of the diode should be touching the left contact on the switch, and the bent, output end should be facing to the right and resting on the switch there, like this:
|
||||||
|
|
||||||
<summary>Click for details</summary>
|

|
||||||
|
|
||||||
## Soldering the Diodes
|
|
||||||
|
|
||||||
Starting at the top-left switch, place the diode (with tweezers if you have them) on the switch so that the diode itself is vertically aligned, and the black line is facing toward you. The straight end of the diode should be touching the left contact on the switch, and the bent end should be facing to the right and resting on the switch there, like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
│o
|
|
||||||
┌┴┐ o
|
|
||||||
│ │ O
|
|
||||||
├─┤
|
|
||||||
└┬┘
|
|
||||||
└─────────────
|
|
||||||
```
|
|
||||||
|
|
||||||
Letting the diode rest, grab your solder, and touch both it and the soldering iron to the left contact at the same time - the rosin in the solder should make it easy for the solder to flow over both the diode and the keyswitch contact. The diode may move a little, and if it does, carefully position it back it place by grabbing the bent end of the diode - the other end will become hot very quickly. If you find that it's moving too much, using needle-nose pliers of some sort may help to keep the diode still when soldering.
|
Letting the diode rest, grab your solder, and touch both it and the soldering iron to the left contact at the same time - the rosin in the solder should make it easy for the solder to flow over both the diode and the keyswitch contact. The diode may move a little, and if it does, carefully position it back it place by grabbing the bent end of the diode - the other end will become hot very quickly. If you find that it's moving too much, using needle-nose pliers of some sort may help to keep the diode still when soldering.
|
||||||
|
|
||||||
@@ -247,20 +125,13 @@ After soldering things in place, it may be helpful to blow on the joint to push
|
|||||||
|
|
||||||
When the first diode is complete, the next one will need to be soldered to both the keyswitch, and the previous diode at the new elbow. That will look something like this:
|
When the first diode is complete, the next one will need to be soldered to both the keyswitch, and the previous diode at the new elbow. That will look something like this:
|
||||||
|
|
||||||
```
|

|
||||||
│o │o
|
|
||||||
┌┴┐ o ┌┴┐ o
|
|
||||||
│ │ O │ │ O
|
|
||||||
├─┤ ├─┤
|
|
||||||
└┬┘ └┬┘
|
|
||||||
└────────────────┴─────────────
|
|
||||||
```
|
|
||||||
|
|
||||||
After completing a row, use the wire cutters to trim the excess wire from the tops of the diodes, and from the right side on the final switch. This process will need to completed for each row you have.
|
After completing a row, use the wire cutters to trim the excess wire from the tops of the diodes, and from the right side on the final switch. This process will need to completed for each row you have.
|
||||||
|
|
||||||
When all of the diodes are completely soldered, it's a good idea to quickly inspect each one to ensure that your solder joints are solid and sturdy - repairing things after this is possible, but more difficult.
|
When all of the diodes are completely soldered, it's a good idea to quickly inspect each one to ensure that your solder joints are solid and sturdy - repairing things after this is possible, but more difficult.
|
||||||
|
|
||||||
## Soldering the Columns
|
#### Soldering the Columns
|
||||||
|
|
||||||
You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch.
|
You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch.
|
||||||
|
|
||||||
@@ -270,9 +141,7 @@ Before beginning to solder, it helps to have your wire pre-bent (if using single
|
|||||||
|
|
||||||
If you're not using any insulation, you can try to keep the column wires elevated, and solder them near the tips of the keyswitch contacts - if the wires are sturdy enough, they won't short out to the row wiring an diodes.
|
If you're not using any insulation, you can try to keep the column wires elevated, and solder them near the tips of the keyswitch contacts - if the wires are sturdy enough, they won't short out to the row wiring an diodes.
|
||||||
|
|
||||||
</details>
|
## Wiring up the controller
|
||||||
|
|
||||||
# Wiring up the controller
|
|
||||||
|
|
||||||
Now that the matrix itself is complete, it's time to connect what you've done to the microcontroller board.
|
Now that the matrix itself is complete, it's time to connect what you've done to the microcontroller board.
|
||||||
|
|
||||||
@@ -280,15 +149,16 @@ Place the microcontroller where you want it to be located, give thought to mount
|
|||||||
|
|
||||||
Find the pinout/documentation for your microcontroller board ([links here](#common-microcontroller-boards)) and make a note of all the digital I/O pins on it (note that on some controllers, like the teensy, analogue I/O can double as digital) as these are the pins you want to connect your wires to.
|
Find the pinout/documentation for your microcontroller board ([links here](#common-microcontroller-boards)) and make a note of all the digital I/O pins on it (note that on some controllers, like the teensy, analogue I/O can double as digital) as these are the pins you want to connect your wires to.
|
||||||
|
|
||||||
<details>
|
----
|
||||||
|
|
||||||
<summary>Specific instructions for the Teensy 2.0</summary>
|
### Specific instructions for the Teensy 2.0
|
||||||
|
|
||||||
There are some pins on the Teensy that are special, like D6 (the LED on the chip), or some of the UART, SPI, I2C, or PWM channels, but only avoid those if you're planning something in addition to a keyboard. If you're unsure about wanting to add something later, you should have enough pins in total to avoid a couple.
|
There are some pins on the Teensy that are special, like D6 (the LED on the chip), or some of the UART, SPI, I2C, or PWM channels, but only avoid those if you're planning something in addition to a keyboard. If you're unsure about wanting to add something later, you should have enough pins in total to avoid a couple.
|
||||||
|
|
||||||
The pins you'll absolutely have to avoid, as with any controller, are: GND, VCC, AREF, and RST - all the others are usable and accessible in the firmware.
|
The pins you'll absolutely have to avoid, as with any controller, are: GND, VCC, AREF, and RST - all the others are usable and accessible in the firmware.
|
||||||
|
|
||||||
</details>
|
----
|
||||||
|
|
||||||
|
|
||||||
Cut wires to the length of the distance from the a point on each column/row to the controller. You can solder anywhere along the row, as long as it's after the diode - soldering before the diode (on the keyswitch side) will cause that row not to work.
|
Cut wires to the length of the distance from the a point on each column/row to the controller. You can solder anywhere along the row, as long as it's after the diode - soldering before the diode (on the keyswitch side) will cause that row not to work.
|
||||||
|
|
||||||
@@ -301,150 +171,32 @@ As you solder the wires to the controller make a note of which row/column is goi
|
|||||||
As you move along, be sure that the controller is staying in place - recutting and soldering the wires is a pain!
|
As you move along, be sure that the controller is staying in place - recutting and soldering the wires is a pain!
|
||||||
|
|
||||||
|
|
||||||
|
## Getting Some Basic Firmware Set Up
|
||||||
# Getting Some Basic Firmware Set Up
|
|
||||||
|
|
||||||
From here, you should have a working keyboard once you program a firmware.
|
From here, you should have a working keyboard once you program a firmware.
|
||||||
|
|
||||||
Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](http://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix).
|
Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](http://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix).
|
||||||
|
|
||||||
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, and the .zip of source files can be modified for advanced functionality and compiled locally using the method described in the collapsable section below, or using the more comprehensive [getting started guide.](newbs_getting_started)
|
Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, and the .zip of source files can be modified for advanced functionality and compiled locally using the method described in [Building Your First Firmware](newbs_building_firmware?id=build-your-firmware).
|
||||||
|
|
||||||
|
The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the code from your .zip file in a modern version of QMK Firmware, you'll need to open the .zip and follow these instructions:
|
||||||
|
|
||||||
<details>
|
1. Extract the `kb` folder to `qmk_firmware/keyboards/handwired/`.
|
||||||
|
2. Open the extracted `kb` folder, then proceed to the `keymaps/default/` folder, and open `keymap.c`.
|
||||||
<summary>Creating and compiling your firmware locally (command line method)</summary>
|
3. Locate and delete the `action_get_macro` code block:
|
||||||
|
```
|
||||||
To start out, download [the firmware](https://github.com/qmk/qmk_firmware/) - We'll be doing a lot from the Terminal/command prompt, so get that open, along with a decent text editor like [Sublime Text](http://www.sublimetext.com/) (paid) or [Visual Studio Code](https://code.visualstudio.com) (free).
|
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
|
||||||
|
...
|
||||||
The first thing we're going to do is create a new keyboard. In your terminal, run this command, which will ask you some questions and generate a basic keyboard project:
|
return MACRO_NONE;
|
||||||
|
|
||||||
```
|
|
||||||
./util/new_keyboard.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
You'll want to navigate to the `keyboards/<project_name>/` folder by typing, like the print-out from the script specifies:
|
|
||||||
|
|
||||||
```
|
|
||||||
cd keyboards/<project_name>
|
|
||||||
```
|
|
||||||
|
|
||||||
### `config.h`
|
|
||||||
|
|
||||||
The first thing you're going to want to modify is the `config.h` file. Find `MATRIX_ROWS` and `MATRIX_COLS` and change their definitions to match the dimensions of your keyboard's matrix.
|
|
||||||
|
|
||||||
Farther down are `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`. Change their definitions to match how you wired up your matrix (looking from the top of the keyboard, the rows run top-to-bottom and the columns run left-to-right). Likewise, change the definition of `UNUSED_PINS` to match the pins you did not use (this will save power).
|
|
||||||
|
|
||||||
### `<project_name>.h`
|
|
||||||
|
|
||||||
The next file you'll want to look at is `<project_name>.h`. You're going to want to rewrite the `LAYOUT` definition - the format and syntax here is extremely important, so pay attention to how things are setup. The first half of the definition are considered the arguments - this is the format that you'll be following in your keymap later on, so you'll want to have as many k*xy* variables here as you do keys. The second half is the part that the firmware actually looks at, and will contain gaps depending on how you wired your matrix.
|
|
||||||
|
|
||||||
We'll dive into how this will work with the following example. Say we have a keyboard like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌───┬───┬───┐
|
|
||||||
│ │ │ │
|
|
||||||
├───┴─┬─┴───┤
|
|
||||||
│ │ │
|
|
||||||
└─────┴─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
This can be described by saying the top row is 3 1u keys, and the bottom row is 2 1.5u keys. The difference between the two rows is important, because the bottom row has an unused column spot (3 v 2). Let's say that this is how we wired the columns:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌───┬───┬───┐
|
|
||||||
│ ┋ │ ┋ │ ┋ │
|
|
||||||
├─┋─┴─┬─┴─┋─┤
|
|
||||||
│ ┋ │ ┋ │
|
|
||||||
└─────┴─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
The middle column is unused on the bottom row in this example. Our `LAYOUT` definition would look like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
#define LAYOUT( \
|
|
||||||
k00, k01, k02, \
|
|
||||||
k10, k11, \
|
|
||||||
) \
|
|
||||||
{ \
|
|
||||||
{ k00, k01, k02 }, \
|
|
||||||
{ k10, KC_NO, k11 }, \
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
4. Save and close `keymap.c`.
|
||||||
Notice how the top half is spaced to resemble our physical layout - this helps us understand which keys are associated with which columns. The bottom half uses the keycode `KC_NO` where there is no keyswitch wired in. It's easiest to keep the bottom half aligned in a grid to help us make sense of how the firmware actually sees the wiring.
|
|
||||||
|
|
||||||
Let's say that instead, we wired our keyboard like this (a fair thing to do):
|
|
||||||
|
|
||||||
```
|
|
||||||
┌───┬───┬───┐
|
|
||||||
│ ┋ │ ┋│ ┋ │
|
|
||||||
├─┋─┴─┬┋┴───┤
|
|
||||||
│ ┋ │┋ │
|
|
||||||
└─────┴─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
This would require our `LAYOUT` definition to look like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
#define LAYOUT( \
|
|
||||||
k00, k01, k02, \
|
|
||||||
k10, k11, \
|
|
||||||
) \
|
|
||||||
{ \
|
|
||||||
{ k00, k01, k02 }, \
|
|
||||||
{ k10, k11, KC_NO }, \
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Notice how the `k11` and `KC_NO` switched places to represent the wiring, and the unused final column on the bottom row. Sometimes it'll make more sense to put a keyswitch on a particular column, but in the end, it won't matter, as long as all of them are accounted for. You can use this process to write out the `LAYOUT` for your entire keyboard - be sure to remember that your keyboard is actually backwards when looking at the underside of it.
|
|
||||||
|
|
||||||
### `keymaps/<variant>/default.c`
|
|
||||||
|
|
||||||
This is the actual keymap for your keyboard, and the main place you'll make changes as you perfect your layout. `default.c` is the file that gets pull by default when typing `make`, but you can make other files as well, and specify them by typing `make handwired/<keyboard>:<variant>`, which will pull `keymaps/<variant>/keymap.c`.
|
|
||||||
|
|
||||||
The basis of a keymap is its layers - by default, layer 0 is active. You can activate other layers, the highest of which will be referenced first. Let's start with our base layer.
|
|
||||||
|
|
||||||
Using our previous example, let's say we want to create the following layout:
|
|
||||||
|
|
||||||
```
|
|
||||||
┌───┬───┬───┐
|
|
||||||
│ A │ 1 │ H │
|
|
||||||
├───┴─┬─┴───┤
|
|
||||||
│ TAB │ SPC │
|
|
||||||
└─────┴─────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
This can be accomplished by using the following `keymaps` definition:
|
|
||||||
|
|
||||||
```
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
||||||
[0] = LAYOUT( /* Base */
|
|
||||||
KC_A, KC_1, KC_H, \
|
|
||||||
KC_TAB, KC_SPC \
|
|
||||||
),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the layout of the keycodes is similar to the physical layout of our keyboard - this make it much easier to see what's going on. A lot of the keycodes should be fairly obvious, but for a full list of them, check out [Keycodes](keycodes.md) - there are also a lot of aliases to condense your keymap file.
|
|
||||||
|
|
||||||
It's also important to use the `LAYOUT` function we defined earlier - this is what allows the firmware to associate our intended readable keymap with the actual wiring.
|
|
||||||
|
|
||||||
## Compiling Your Firmware
|
|
||||||
|
|
||||||
After you've written out your entire keymap, you're ready to get the firmware compiled and onto your Teensy. Before compiling, you'll need to get your [development environment set-up](getting_started_build_tools.md) - you can skip the dfu-programmer instructions, but you'll need to download and install the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to get the firmware on your Teensy.
|
|
||||||
|
|
||||||
Once everything is installed, running `make` in the terminal should get you some output, and eventually a `<project_name>.hex` file in that folder. If you're having trouble with this step, see the end of the guide for the trouble-shooting section.
|
|
||||||
|
|
||||||
Once you have your `<project_name>.hex` file, open up the Teensy loader application, and click the file icon. From here, navigate to your `QMK/keyboards/<project_name>/` folder, and select the `<project_name>.hex` file. Plug in your keyboard and press the button on the Teensy - you should see the LED on the device turn off once you do. The Teensy Loader app will change a little, and the buttons should be clickable - click the download button (down arrow), and then the reset button (right arrow), and your keyboard should be ready to go!
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Flashing the Firmware
|
## Flashing the Firmware
|
||||||
|
|
||||||
Install [QMK toolbox](https://github.com/qmk/qmk_toolbox).
|
Install [QMK Toolbox](https://github.com/qmk/qmk_toolbox).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Under "Local File" navigate to your newly created .hex file. Under "Microcontroller", select the corresponding one for your controller board (common ones available [here](#common-microcontroller-boards)).
|
Under "Local File" navigate to your newly created .hex file. Under "Microcontroller", select the corresponding one for your controller board (common ones available [here](#common-microcontroller-boards)).
|
||||||
|
|
||||||
@@ -453,20 +205,20 @@ Plug in your keyboard and press the reset button (or short the Reset and Ground
|
|||||||
|
|
||||||
## Testing Your Firmware
|
## Testing Your Firmware
|
||||||
|
|
||||||
Use a website such as [keyboard tester](https://www.keyboardtester.com/tester.html)/[keyboard checker](http://keyboardchecker.com/) or just open a text editor and try typing - you should get the characters that you put into your keymap. Test each key, and make a note of the ones that aren't working. Here's a quick trouble-shooting guide for non-working keys:
|
Use a website such as [QMK Configurator's Keyboard Tester](https://config.qmk.fm/#/test), [Keyboard Tester](https://www.keyboardtester.com/tester.html), or [Keyboard Checker](http://keyboardchecker.com/) or just open a text editor and try typing - you should get the characters that you put into your keymap. Test each key, and make a note of the ones that aren't working. Here's a quick trouble-shooting guide for non-working keys:
|
||||||
|
|
||||||
0. Flip the keyboard back over and short the keyswitch's contacts with a piece wire - this will eliminate the possibility of the keyswitch being bad and needing to be replaced.
|
1. Flip the keyboard back over and short the keyswitch's contacts with a piece wire - this will eliminate the possibility of the keyswitch being bad and needing to be replaced.
|
||||||
1. Check the solder points on the keyswitch - these need to be plump and whole. If you touch it with a moderate amount of force and it comes apart, it's not strong enough.
|
2. Check the solder points on the keyswitch - these need to be plump and whole. If you touch it with a moderate amount of force and it comes apart, it's not strong enough.
|
||||||
2. Check the solder joints on the diode - if the diode is loose, part of your row may register, while the other may not.
|
3. Check the solder joints on the diode - if the diode is loose, part of your row may register, while the other may not.
|
||||||
3. Check the solder joints on the columns - if your column wiring is loose, part or all of the column may not work.
|
4. Check the solder joints on the columns - if your column wiring is loose, part or all of the column may not work.
|
||||||
4. Check the solder joints on both sides of the wires going to/from the Teensy - the wires need to be fully soldered and connect to both sides.
|
5. Check the solder joints on both sides of the wires going to/from the Teensy - the wires need to be fully soldered and connect to both sides.
|
||||||
5. Check the `<project_name>.h` file for errors and incorrectly placed `KC_NO`s - if you're unsure where they should be, instead duplicate a k*xy* variable.
|
6. Check the `<project_name>.h` file for errors and incorrectly placed `KC_NO`s - if you're unsure where they should be, instead duplicate a k*xy* variable.
|
||||||
6. Check to make sure you actually compiled the firmware and flashed the Teensy correctly. Unless you got error messages in the terminal, or a pop-up during flashing, you probably did everything correctly.
|
7. Check to make sure you actually compiled the firmware and flashed the Teensy correctly. Unless you got error messages in the terminal, or a pop-up during flashing, you probably did everything correctly.
|
||||||
7. Use a multimeter to check that the switch is actually closing when actuated (completing the circuit when pressed down).
|
8. Use a multimeter to check that the switch is actually closing when actuated (completing the circuit when pressed down).
|
||||||
|
|
||||||
If you've done all of these things, keep in mind that sometimes you might have had multiple things affecting the keyswitch, so it doesn't hurt to test the keyswitch by shorting it out at the end.
|
If you've done all of these things, keep in mind that sometimes you might have had multiple things affecting the keyswitch, so it doesn't hurt to test the keyswitch by shorting it out at the end.
|
||||||
|
|
||||||
# Finishing up
|
## Finishing up
|
||||||
|
|
||||||
Once you have confirmed that the keyboard is working, if you have used a seperate (non handwire specific) controller you will want to secure it in place. This can be done in many different ways e.g. hot glue, double sided sticky tape, 3D printed caddy, electrical tape.
|
Once you have confirmed that the keyboard is working, if you have used a seperate (non handwire specific) controller you will want to secure it in place. This can be done in many different ways e.g. hot glue, double sided sticky tape, 3D printed caddy, electrical tape.
|
||||||
|
|
||||||
@@ -474,7 +226,7 @@ If you found this fullfilling you could experiment by adding additional features
|
|||||||
|
|
||||||
There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](http://docs.qmk.fm) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](http://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/Uq7gcHh) for help!
|
There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](http://docs.qmk.fm) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](http://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/Uq7gcHh) for help!
|
||||||
|
|
||||||
# Links to other guides:
|
## Links to Other Guides
|
||||||
|
|
||||||
- [matt3o's step by step guide (BrownFox build)](https://deskthority.net/viewtopic.php?f=7&t=6050) also his [website](https://matt3o.com/hand-wiring-a-custom-keyboard/) and [video guide](https://www.youtube.com/watch?v=LVzpsjFWPP4)
|
- [matt3o's step by step guide (BrownFox build)](https://deskthority.net/viewtopic.php?f=7&t=6050) also his [website](https://matt3o.com/hand-wiring-a-custom-keyboard/) and [video guide](https://www.youtube.com/watch?v=LVzpsjFWPP4)
|
||||||
- [Cribbit's "Modern hand wiring guide - stronger, cleaner, easier"](https://geekhack.org/index.php?topic=87689.0)
|
- [Cribbit's "Modern hand wiring guide - stronger, cleaner, easier"](https://geekhack.org/index.php?topic=87689.0)
|
||||||
@@ -483,4 +235,10 @@ There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](htt
|
|||||||
- [Masterzen's "Handwired keyboard build log"](http://www.masterzen.fr/2018/12/16/handwired-keyboard-build-log-part-1/)
|
- [Masterzen's "Handwired keyboard build log"](http://www.masterzen.fr/2018/12/16/handwired-keyboard-build-log-part-1/)
|
||||||
|
|
||||||
|
|
||||||
|
# Legacy Content
|
||||||
|
|
||||||
|
This page used to include more content. We have moved a section that used to be part of this page its own page. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for.
|
||||||
|
|
||||||
|
## Preamble: How a Keyboard Matrix Works (and why we need diodes) :id=preamble-how-a-keyboard-matrix-works-and-why-we-need-diodes
|
||||||
|
|
||||||
|
* [How a Keyboard Matrix Works](how_a_matrix_works.md)
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Hardware
|
|
||||||
|
|
||||||
QMK runs on a variety of hardware. If your processor can be targeted by [LUFA](http://www.fourwalledcubicle.com/LUFA.php) or [ChibiOS](http://www.chibios.com) you can probably get QMK running on it. This section explores getting QMK running on, and communicating with, hardware of all kinds.
|
|
||||||
|
|
||||||
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
|
|
||||||
* [AVR Processors](hardware_avr.md)
|
|
||||||
* ARM Processors (TBD)
|
|
||||||
* [Drivers](hardware_drivers.md)
|
|
||||||
@@ -33,3 +33,7 @@ Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to in
|
|||||||
## IS31FL3733
|
## 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.
|
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.
|
||||||
|
|
||||||
|
## 24xx series external I2C EEPROM
|
||||||
|
|
||||||
|
Support for an external I2C-based EEPROM instead of using the on-chip EEPROM. For more information on how to setup the driver see the [EEPROM Driver](eeprom_driver.md) page.
|
||||||
@@ -20,7 +20,7 @@ QMK (*Quantum Mechanical Keyboard*) היא קהילת קוד פתוח (open sour
|
|||||||
|
|
||||||
## איך לקמפל
|
## איך לקמפל
|
||||||
|
|
||||||
לפני שתצליחו לקמפל, תדרשו [להתקין סביבה](getting_started_build_tools.md) עבור פיתוח AVR ו/או ARM. ברגע שהדבר בוצע, תוכלו להריץ פקודת `make` כדי לבנות מקלדת ומיפוי עם התחביר הבא:
|
לפני שתצליחו לקמפל, תדרשו [להתקין סביבה](he-il/getting_started_build_tools.md) עבור פיתוח AVR ו/או ARM. ברגע שהדבר בוצע, תוכלו להריץ פקודת `make` כדי לבנות מקלדת ומיפוי עם התחביר הבא:
|
||||||
|
|
||||||
make planck/rev4:default
|
make planck/rev4:default
|
||||||
|
|
||||||
@@ -30,5 +30,5 @@ QMK (*Quantum Mechanical Keyboard*) היא קהילת קוד פתוח (open sour
|
|||||||
|
|
||||||
## איך להתאים
|
## איך להתאים
|
||||||
|
|
||||||
לQMK יש המון [יכולות](features.md) שאפשר לנווט בהן, וכמות נכבדת של [תיעוד ודוקומנטציה](http://docs.qmk.fm) בה אפשר לנבור. רוב הפיצ׳רים באים לידי ביטוי על ידי שינוי [מיפוי המקלדת](keymap.md) ושינוי [קודי המקשים](keycodes.md).
|
לQMK יש המון [יכולות](he-il/features.md) שאפשר לנווט בהן, וכמות נכבדת של [תיעוד ודוקומנטציה](http://docs.qmk.fm) בה אפשר לנבור. רוב הפיצ׳רים באים לידי ביטוי על ידי שינוי [מיפוי המקלדת](he-il/keymap.md) ושינוי [קודי המקשים](he-il/keycodes.md).
|
||||||
</div>
|
</div>
|
||||||
+106
-105
@@ -1,6 +1,7 @@
|
|||||||
<div dir="rtl" markdown="1">
|
<div dir="rtl" markdown="1">
|
||||||
|
|
||||||
**בשפה העברית**
|
**בשפה העברית**
|
||||||
* [המדריך המלא למתחילים](newbs.md)
|
* [המדריך המלא למתחילים](he-il/newbs.md)
|
||||||
* [מקורות ללמידה](he-il/newbs_learn_more_resources.md)
|
* [מקורות ללמידה](he-il/newbs_learn_more_resources.md)
|
||||||
* [בסיס QMK](he-il/README.md)
|
* [בסיס QMK](he-il/README.md)
|
||||||
* [מבוא לQMK](he-il/getting_started_introduction.md)
|
* [מבוא לQMK](he-il/getting_started_introduction.md)
|
||||||
@@ -13,126 +14,126 @@
|
|||||||
* [איך לתעד נכון](he-il/documentation_best_practices.md)
|
* [איך לתעד נכון](he-il/documentation_best_practices.md)
|
||||||
|
|
||||||
**בשפה האנגלית**
|
**בשפה האנגלית**
|
||||||
* [המדריך המלא למתחילים](newbs.md)
|
* [המדריך המלא למתחילים](he-il/newbs.md)
|
||||||
* [התחלה](newbs_getting_started.md)
|
* [התחלה](he-il/newbs_getting_started.md)
|
||||||
* [בנייה של הקושחה הראשונה שלך](newbs_building_firmware.md)
|
* [בנייה של הקושחה הראשונה שלך](he-il/newbs_building_firmware.md)
|
||||||
* [צריבה של הקושחה](newbs_flashing.md)
|
* [צריבה של הקושחה](he-il/newbs_flashing.md)
|
||||||
* [בדיקות ודיבאגינג](newbs_testing_debugging.md)
|
* [בדיקות ודיבאגינג](he-il/newbs_testing_debugging.md)
|
||||||
* [עבודה נכונה ב GIT](newbs_best_practices.md)
|
* [עבודה נכונה ב GIT](he-il/newbs_best_practices.md)
|
||||||
* [מקורות ללמידה](newbs_learn_more_resources.md)
|
* [מקורות ללמידה](he-il/newbs_learn_more_resources.md)
|
||||||
|
|
||||||
* [בסיס QMK](README.md)
|
* [בסיס QMK](he-il/README.md)
|
||||||
* [מבוא לQMK](getting_started_introduction.md)
|
* [מבוא לQMK](he-il/getting_started_introduction.md)
|
||||||
* [QMK CLI](cli.md)
|
* [QMK CLI](he-il/cli.md)
|
||||||
* [QMK CLI Config](cli_configuration.md)
|
* [QMK CLI Config](he-il/cli_configuration.md)
|
||||||
* [תרומה ל QMK](contributing.md)
|
* [תרומה ל QMK](he-il/contributing.md)
|
||||||
* [איך להשתמש בGithub](getting_started_github.md)
|
* [איך להשתמש בGithub](he-il/getting_started_github.md)
|
||||||
* [קבלת עזרה](getting_started_getting_help.md)
|
* [קבלת עזרה](he-il/getting_started_getting_help.md)
|
||||||
|
|
||||||
* [שינויים משמעותיים](breaking_changes.md)
|
* [שינויים משמעותיים](he-il/breaking_changes.md)
|
||||||
* [2019 Aug 30](ChangeLog/20190830.md)
|
* [2019 Aug 30](he-il/ChangeLog/20190830.md)
|
||||||
|
|
||||||
* [שאלות נפוצות](faq.md)
|
* [שאלות נפוצות](he-il/faq.md)
|
||||||
* [שאלות נפוצות כלליות](faq_general.md)
|
* [שאלות נפוצות כלליות](he-il/faq_general.md)
|
||||||
* [בנייה/קומפילציה של QMK](faq_build.md)
|
* [בנייה/קומפילציה של QMK](he-il/faq_build.md)
|
||||||
* [דיבאגינג ופתרון תקלות של QMK](faq_debug.md)
|
* [דיבאגינג ופתרון תקלות של QMK](he-il/faq_debug.md)
|
||||||
* [מיפוי מקשים](faq_keymap.md)
|
* [מיפוי מקשים](he-il/faq_keymap.md)
|
||||||
* [התקנת דרייברים עם Zadig](driver_installation_zadig.md)
|
* [התקנת דרייברים עם Zadig](he-il/driver_installation_zadig.md)
|
||||||
|
|
||||||
* מדריכים מפורטים
|
* מדריכים מפורטים
|
||||||
* [התקנת כלי Build](getting_started_build_tools.md)
|
* [התקנת כלי Build](he-il/getting_started_build_tools.md)
|
||||||
* [מדריך Vagrant](getting_started_vagrant.md)
|
* [מדריך Vagrant](he-il/getting_started_vagrant.md)
|
||||||
* [הוראות בנייה/קומפילציה](getting_started_make_guide.md)
|
* [הוראות בנייה/קומפילציה](he-il/getting_started_make_guide.md)
|
||||||
* [צריבת קושחה](flashing.md)
|
* [צריבת קושחה](he-il/flashing.md)
|
||||||
* [התאמה אישית של הפונקציונאליות](custom_quantum_functions.md)
|
* [התאמה אישית של הפונקציונאליות](he-il/custom_quantum_functions.md)
|
||||||
* [מיפוי מקשים](keymap.md)
|
* [מיפוי מקשים](he-il/keymap.md)
|
||||||
|
|
||||||
* [חומרה](hardware.md)
|
* [חומרה](he-il/hardware.md)
|
||||||
* [מעבדי AVR](hardware_avr.md)
|
* [מעבדי AVR](he-il/hardware_avr.md)
|
||||||
* [דרייברים](hardware_drivers.md)
|
* [דרייברים](he-il/hardware_drivers.md)
|
||||||
|
|
||||||
* התייחסויות
|
* התייחסויות
|
||||||
* [מדריך למקלדות](hardware_keyboard_guidelines.md)
|
* [מדריך למקלדות](he-il/hardware_keyboard_guidelines.md)
|
||||||
* [אפשרויות הגדרות](config_options.md)
|
* [אפשרויות הגדרות](he-il/config_options.md)
|
||||||
* [קודי מקשים](keycodes.md)
|
* [קודי מקשים](he-il/keycodes.md)
|
||||||
* [קונבנציות קוד - C](coding_conventions_c.md)
|
* [קונבנציות קוד - C](he-il/coding_conventions_c.md)
|
||||||
* [קונבנציות קוד - Python](coding_conventions_python.md)
|
* [קונבנציות קוד - Python](he-il/coding_conventions_python.md)
|
||||||
* [איך לתעד נכון](documentation_best_practices.md)
|
* [איך לתעד נכון](he-il/documentation_best_practices.md)
|
||||||
* [טמפלטים לדוקומנטציה](documentation_templates.md)
|
* [טמפלטים לדוקומנטציה](he-il/documentation_templates.md)
|
||||||
* [מילון](reference_glossary.md)
|
* [מילון](he-il/reference_glossary.md)
|
||||||
* [בדיקות יחידה](unit_testing.md)
|
* [בדיקות יחידה](he-il/unit_testing.md)
|
||||||
* [פונקציות שימושיות](ref_functions.md)
|
* [פונקציות שימושיות](he-il/ref_functions.md)
|
||||||
* [תמיכה בConfigurator](reference_configurator_support.md)
|
* [תמיכה בConfigurator](he-il/reference_configurator_support.md)
|
||||||
* [פורמט info.json](reference_info_json.md)
|
* [פורמט info.json](he-il/reference_info_json.md)
|
||||||
* [פיתוח בPython CLI](cli_development.md)
|
* [פיתוח בPython CLI](he-il/cli_development.md)
|
||||||
|
|
||||||
* [תכונות](features.md)
|
* [תכונות](he-il/features.md)
|
||||||
* [Basic Keycodes](keycodes_basic.md)
|
* [Basic Keycodes](he-il/keycodes_basic.md)
|
||||||
* [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md)
|
* [US ANSI Shifted Keys](he-il/keycodes_us_ansi_shifted.md)
|
||||||
* [Quantum Keycodes](quantum_keycodes.md)
|
* [Quantum Keycodes](he-il/quantum_keycodes.md)
|
||||||
* [Advanced Keycodes](feature_advanced_keycodes.md)
|
* [Advanced Keycodes](he-il/feature_advanced_keycodes.md)
|
||||||
* [Audio](feature_audio.md)
|
* [Audio](he-il/feature_audio.md)
|
||||||
* [Auto Shift](feature_auto_shift.md)
|
* [Auto Shift](he-il/feature_auto_shift.md)
|
||||||
* [Backlight](feature_backlight.md)
|
* [Backlight](he-il/feature_backlight.md)
|
||||||
* [Bluetooth](feature_bluetooth.md)
|
* [Bluetooth](he-il/feature_bluetooth.md)
|
||||||
* [Bootmagic](feature_bootmagic.md)
|
* [Bootmagic](he-il/feature_bootmagic.md)
|
||||||
* [Combos](feature_combo.md)
|
* [Combos](he-il/feature_combo.md)
|
||||||
* [Command](feature_command.md)
|
* [Command](he-il/feature_command.md)
|
||||||
* [Debounce API](feature_debounce_type.md)
|
* [Debounce API](he-il/feature_debounce_type.md)
|
||||||
* [DIP Switch](feature_dip_switch.md)
|
* [DIP Switch](he-il/feature_dip_switch.md)
|
||||||
* [Dynamic Macros](feature_dynamic_macros.md)
|
* [Dynamic Macros](he-il/feature_dynamic_macros.md)
|
||||||
* [Encoders](feature_encoders.md)
|
* [Encoders](he-il/feature_encoders.md)
|
||||||
* [Grave Escape](feature_grave_esc.md)
|
* [Grave Escape](he-il/feature_grave_esc.md)
|
||||||
* [Haptic Feedback](feature_haptic_feedback.md)
|
* [Haptic Feedback](he-il/feature_haptic_feedback.md)
|
||||||
* [HD44780 LCD Controller](feature_hd44780.md)
|
* [HD44780 LCD Controller](he-il/feature_hd44780.md)
|
||||||
* [Key Lock](feature_key_lock.md)
|
* [Key Lock](he-il/feature_key_lock.md)
|
||||||
* [Layouts](feature_layouts.md)
|
* [Layouts](he-il/feature_layouts.md)
|
||||||
* [Leader Key](feature_leader_key.md)
|
* [Leader Key](he-il/feature_leader_key.md)
|
||||||
* [LED Matrix](feature_led_matrix.md)
|
* [LED Matrix](he-il/feature_led_matrix.md)
|
||||||
* [Macros](feature_macros.md)
|
* [Macros](he-il/feature_macros.md)
|
||||||
* [Mouse Keys](feature_mouse_keys.md)
|
* [Mouse Keys](he-il/feature_mouse_keys.md)
|
||||||
* [OLED Driver](feature_oled_driver.md)
|
* [OLED Driver](he-il/feature_oled_driver.md)
|
||||||
* [One Shot Keys](feature_advanced_keycodes.md#one-shot-keys)
|
* [One Shot Keys](he-il/one_shot_keys.md)
|
||||||
* [Pointing Device](feature_pointing_device.md)
|
* [Pointing Device](he-il/feature_pointing_device.md)
|
||||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
* [PS/2 Mouse](he-il/feature_ps2_mouse.md)
|
||||||
* [RGB Lighting](feature_rgblight.md)
|
* [RGB Lighting](he-il/feature_rgblight.md)
|
||||||
* [RGB Matrix](feature_rgb_matrix.md)
|
* [RGB Matrix](he-il/feature_rgb_matrix.md)
|
||||||
* [Space Cadet](feature_space_cadet.md)
|
* [Space Cadet](he-il/feature_space_cadet.md)
|
||||||
* [Split Keyboard](feature_split_keyboard.md)
|
* [Split Keyboard](he-il/feature_split_keyboard.md)
|
||||||
* [Stenography](feature_stenography.md)
|
* [Stenography](he-il/feature_stenography.md)
|
||||||
* [Swap Hands](feature_swap_hands.md)
|
* [Swap Hands](he-il/feature_swap_hands.md)
|
||||||
* [Tap Dance](feature_tap_dance.md)
|
* [Tap Dance](he-il/feature_tap_dance.md)
|
||||||
* [Terminal](feature_terminal.md)
|
* [Terminal](he-il/feature_terminal.md)
|
||||||
* [Thermal Printer](feature_thermal_printer.md)
|
* [Thermal Printer](he-il/feature_thermal_printer.md)
|
||||||
* [Unicode](feature_unicode.md)
|
* [Unicode](he-il/feature_unicode.md)
|
||||||
* [Userspace](feature_userspace.md)
|
* [Userspace](he-il/feature_userspace.md)
|
||||||
* [Velocikey](feature_velocikey.md)
|
* [Velocikey](he-il/feature_velocikey.md)
|
||||||
|
|
||||||
* למייקרים ומודרים
|
* למייקרים ומודרים
|
||||||
* [מדריך לכתיבה ידנית](hand_wire.md)
|
* [מדריך לכתיבה ידנית](he-il/hand_wire.md)
|
||||||
* [מדריך לצריבת ISP](isp_flashing_guide.md)
|
* [מדריך לצריבת ISP](he-il/isp_flashing_guide.md)
|
||||||
* [מדריך לדיבאגינג ARM](arm_debugging.md)
|
* [מדריך לדיבאגינג ARM](he-il/arm_debugging.md)
|
||||||
* [מנהל התקן I2C](i2c_driver.md)
|
* [מנהל התקן I2C](he-il/i2c_driver.md)
|
||||||
* [בקרת GPIO](internals_gpio_control.md)
|
* [בקרת GPIO](he-il/internals_gpio_control.md)
|
||||||
* [המרת Proton C](proton_c_conversion.md)
|
* [המרת Proton C](he-il/proton_c_conversion.md)
|
||||||
|
|
||||||
* להבנה עמוקה יותר
|
* להבנה עמוקה יותר
|
||||||
* [איך עובדות מקלדות](how_keyboards_work.md)
|
* [איך עובדות מקלדות](he-il/how_keyboards_work.md)
|
||||||
* [להבין את QMK](understanding_qmk.md)
|
* [להבין את QMK](he-il/understanding_qmk.md)
|
||||||
|
|
||||||
* נושאים נוספים
|
* נושאים נוספים
|
||||||
* [שימוש ב - Eclipse עם QMK](other_eclipse.md)
|
* [שימוש ב - Eclipse עם QMK](he-il/other_eclipse.md)
|
||||||
* [שימוש ב - VSCode עם QMK](other_vscode.md)
|
* [שימוש ב - VSCode עם QMK](he-il/other_vscode.md)
|
||||||
* [תמיכה](support.md)
|
* [תמיכה](he-il/getting_started_getting_help.md)
|
||||||
* [כיצד להוסיף תרגום](translating.md)
|
* [כיצד להוסיף תרגום](he-il/translating.md)
|
||||||
|
|
||||||
* QMK מבפנים (בתהליך)
|
* QMK מבפנים (בתהליך)
|
||||||
* [Defines](internals_defines.md)
|
* [Defines](he-il/internals_defines.md)
|
||||||
* [Input Callback Reg](internals_input_callback_reg.md)
|
* [Input Callback Reg](he-il/internals_input_callback_reg.md)
|
||||||
* [Midi Device](internals_midi_device.md)
|
* [Midi Device](he-il/internals_midi_device.md)
|
||||||
* [Midi Device Setup Process](internals_midi_device_setup_process.md)
|
* [Midi Device Setup Process](he-il/internals_midi_device_setup_process.md)
|
||||||
* [Midi Util](internals_midi_util.md)
|
* [Midi Util](he-il/internals_midi_util.md)
|
||||||
* [Send Functions](internals_send_functions.md)
|
* [Send Functions](he-il/internals_send_functions.md)
|
||||||
* [Sysex Tools](internals_sysex_tools.md)
|
* [Sysex Tools](he-il/internals_sysex_tools.md)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<div dir="rtl" markdown="1">
|
|
||||||
# איך להפוך לשותף של QMK
|
|
||||||
|
|
||||||
שותף של QMK הוא יצרן מקלדות או מעצב שמעוניין בלעזור ל-QMK לגדול ולתמוך במקלד(ו)ת שלהם, ולעודד את המשתמשים והצרכנים להוסיף יכולות, רעיונות ומיפויים. אנחנו תמיד מחפשים עוד מקלדות ומשתפי פעולה, אבל אנחנו מבקשים שיעמדו בדרישות הבאות:
|
|
||||||
|
|
||||||
* **קיום לוח PCB למכירה.** לצערינו, יש יותר מידי הסתבכויות ובעיות עם מקלדות המחווטות ידנית.
|
|
||||||
* **תחזוק המקלדת ב-QMK.** זה אולי רק ידרוש הגדרה בסיסית כדי לגרום למקלדת לעבוד, אבל זה גם יכול לכלול התאמה של שינויים בקוד הליבה של QMK שיכול לשבור קוד ייחודי שלכם.
|
|
||||||
* **אישור ומיזוג Pull Requests של מיפויי מקלדת עבור המקלדת** אנחנו רוצים לעודד משתמשים לתרום את מיפויי המקלדת שלהם לאחרים כדי לעזור לאחרים להתחיל ליצור את שלהם.
|
|
||||||
|
|
||||||
אם אתם עומדים בדרישות הללו, שלחו לנו מייל לכתובת hello@qmk.fm עם מבוא וקישורים עבור המקלדת שלכם.
|
|
||||||
</div>
|
|
||||||
@@ -17,19 +17,25 @@ Github עלול להיות קצת טריקי למי שלא מכיר את העב
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
מכאן והלאה, הקיש `git clone ` בשורת הפקודה והדביקו את הלינק שלכם:
|
מכאן והלאה, הקיש `git clone --recurse-submodules ` בשורת הפקודה והדביקו את הלינק שלכם:
|
||||||
|
|
||||||
<div dir="ltr" markdown="1">
|
<div dir="ltr" markdown="1">
|
||||||
|
|
||||||
```
|
```
|
||||||
user@computer:~$ git clone https://github.com/whoeveryouare/qmk_firmware.git
|
user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git
|
||||||
Cloning into 'qmk_firmware'...
|
Cloning into 'qmk_firmware'...
|
||||||
remote: Counting objects: 46625, done.
|
remote: Enumerating objects: 9, done.
|
||||||
remote: Compressing objects: 100% (2/2), done.
|
remote: Counting objects: 100% (9/9), done.
|
||||||
remote: Total 46625 (delta 0), reused 0 (delta 0), pack-reused 46623
|
remote: Compressing objects: 100% (5/5), done.
|
||||||
Receiving objects: 100% (46625/46625), 84.47 MiB | 3.14 MiB/s, done.
|
remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874
|
||||||
Resolving deltas: 100% (29362/29362), done.
|
Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done.
|
||||||
Checking out files: 100% (2799/2799), done.
|
Resolving deltas: 100% (119972/119972), done.
|
||||||
|
...
|
||||||
|
Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b'
|
||||||
|
Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486'
|
||||||
|
Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780'
|
||||||
|
Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d'
|
||||||
|
Submodule path 'lib/ugfx': checked out '3e97b74e03c93631cdd3ddb2ce43b963fdce19b2'
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -66,4 +72,4 @@ To https://github.com/whoeveryouare/qmk_firmware.git
|
|||||||

|

|
||||||
|
|
||||||
אחרי שהגשתם, אנו עלולים לפנות אליכם לגבי השינויים שהצעתם, נבקש שתבצעו שינויים ובסופו של דבר נקבל את השינויים! תודה שתרמתם לפרוייקט QMK :)
|
אחרי שהגשתם, אנו עלולים לפנות אליכם לגבי השינויים שהצעתם, נבקש שתבצעו שינויים ובסופו של דבר נקבל את השינויים! תודה שתרמתם לפרוייקט QMK :)
|
||||||
</div>
|
</div>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
## מבנה QMK בסיסי
|
## מבנה QMK בסיסי
|
||||||
|
|
||||||
QMK הוא פורק של הפרוייקט [tmk_keyboard](https://github.com/tmk/tmk_keyboard) של [Jun Wako](https://github.com/tmk). קוד הTMK המקורי, עם התאמות, יכול להמצא בתיקיית `tmk`. התוספות של QMK לפרוייקט יכולות להמצא בתיקיית `quantum`. פרוייקטי מקלדות יכולות להמצא בתיקיות `handwired` ו- `keyboard`.
|
QMK הוא פורק של הפרוייקט [tmk_keyboard](https://github.com/tmk/tmk_keyboard) של [Jun Wako](https://github.com/tmk). קוד הTMK המקורי, עם התאמות, יכול להמצא בתיקיית `tmk_core`. התוספות של QMK לפרוייקט יכולות להמצא בתיקיית `quantum`. פרוייקטי מקלדות יכולות להמצא בתיקיות `handwired` ו- `keyboard`.
|
||||||
|
|
||||||
### מבנה אחסון המשתמש
|
### מבנה אחסון המשתמש
|
||||||
|
|
||||||
@@ -69,4 +69,4 @@ In every keymap folder, the following files may be found. Only `keymap.c` is req
|
|||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -17,18 +17,8 @@
|
|||||||
|`DEBUG` | |Toggle debug mode |
|
|`DEBUG` | |Toggle debug mode |
|
||||||
|`EEPROM_RESET` |`EEP_RST` |Resets EEPROM state by reinitializing it |
|
|`EEPROM_RESET` |`EEP_RST` |Resets EEPROM state by reinitializing it |
|
||||||
|`KC_GESC` |`GRAVE_ESC`|Escape when tapped, <code>`</code> when pressed with Shift or GUI|
|
|`KC_GESC` |`GRAVE_ESC`|Escape when tapped, <code>`</code> when pressed with Shift or GUI|
|
||||||
|`KC_LSPO` | |Left Shift when held, `(` when tapped |
|
|
||||||
|`KC_RSPC` | |Right Shift when held, `)` when tapped |
|
|
||||||
|`KC_LCPO` | |Left Control when held, `(` when tapped |
|
|
||||||
|`KC_RCPC` | |Right Control when held, `)` when tapped |
|
|
||||||
|`KC_LAPO` | |Left Alt when held, `(` when tapped |
|
|
||||||
|`KC_RAPC` | |Right Alt when held, `)` when tapped |
|
|
||||||
|`KC_SFTENT` | |Right Shift when held, Enter when tapped |
|
|
||||||
|`KC_LEAD` | |The [Leader key](feature_leader_key.md) |
|
|`KC_LEAD` | |The [Leader key](feature_leader_key.md) |
|
||||||
|`KC_LOCK` | |The [Lock key](feature_key_lock.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 |
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# How a Keyboard Matrix Works
|
||||||
|
|
||||||
|
Keyboard switch matrices are arranged in rows and columns. Without a matrix circuit, each switch would require its own wire directly to the controller.
|
||||||
|
|
||||||
|
When the circuit is arranged in rows and columns, if a key is pressed, a column wire makes contact with a row wire and completes a circuit. The keyboard controller detects this closed circuit and registers it as a key press.
|
||||||
|
|
||||||
|
The microcontroller will be set up via the firmware to send a logical 1 to the columns, one at a time, and read from the rows, all at once - this process is called matrix scanning. The matrix is a bunch of open switches that, by default, don't allow any current to pass through - the firmware will read this as no keys being pressed. As soon as you press one key down, the logical 1 that was coming from the column the keyswitch is attached to gets passed through the switch and to the corresponding row - check out the following 2x2 example:
|
||||||
|
|
||||||
|
Column 0 being scanned Column 1 being scanned
|
||||||
|
x x
|
||||||
|
col0 col1 col0 col1
|
||||||
|
| | | |
|
||||||
|
row0 ---(key0)---(key1) row0 ---(key0)---(key1)
|
||||||
|
| | | |
|
||||||
|
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
||||||
|
|
||||||
|
The `x` represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an `x`. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column.
|
||||||
|
|
||||||
|
When we press `key0`, `col0` gets connected to `row0`, so the values that the firmware receives for that row is `0b01` (the `0b` here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected:
|
||||||
|
|
||||||
|
Column 0 being scanned Column 1 being scanned
|
||||||
|
x x
|
||||||
|
col0 col1 col0 col1
|
||||||
|
| | | |
|
||||||
|
x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1)
|
||||||
|
| | | |
|
||||||
|
row1 ---(key2)---(key3) row1 ---(key2)---(key3)
|
||||||
|
|
||||||
|
We can now see that `row0` has an `x`, so has the value of 1. As a whole, the data the firmware receives when `key0` is pressed is:
|
||||||
|
|
||||||
|
col0: 0b01
|
||||||
|
col1: 0b00
|
||||||
|
│└row0
|
||||||
|
└row1
|
||||||
|
|
||||||
|
A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious:
|
||||||
|
|
||||||
|
Column 0 being scanned Column 1 being scanned
|
||||||
|
x x
|
||||||
|
col0 col1 col0 col1
|
||||||
|
| | | |
|
||||||
|
x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1)
|
||||||
|
| | | |
|
||||||
|
x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3)
|
||||||
|
|
||||||
|
Remember that this ^ is still connected to row1
|
||||||
|
|
||||||
|
The data we get from that is:
|
||||||
|
|
||||||
|
col0: 0b11
|
||||||
|
col1: 0b11
|
||||||
|
│└row0
|
||||||
|
└row1
|
||||||
|
|
||||||
|
Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this;
|
||||||
|
|
||||||
|
Column 0 being scanned Column 1 being scanned
|
||||||
|
x x
|
||||||
|
col0 col1 col0 col1
|
||||||
|
│ │ | │
|
||||||
|
(key0) (key1) (key0) (key1)
|
||||||
|
! │ ! │ ! | ! │
|
||||||
|
row0 ─────┴────────┘ │ row0 ─────┴────────┘ │
|
||||||
|
│ │ | │
|
||||||
|
(key2) (key3) (key2) (key3)
|
||||||
|
! ! ! !
|
||||||
|
row1 ─────┴────────┘ row1 ─────┴────────┘
|
||||||
|
|
||||||
|
In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|`
|
||||||
|
|
||||||
|
Now when we press the three keys, invoking what would be a ghosting scenario:
|
||||||
|
|
||||||
|
Column 0 being scanned Column 1 being scanned
|
||||||
|
x x
|
||||||
|
col0 col1 col0 col1
|
||||||
|
│ │ │ │
|
||||||
|
(┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1)
|
||||||
|
! │ ! │ ! │ ! │
|
||||||
|
x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
(key2) (┌─┘3) (key2) (┌─┘3)
|
||||||
|
! ! ! !
|
||||||
|
row1 ─────┴────────┘ x row1 ─────┴────────┘
|
||||||
|
|
||||||
|
Things act as they should! Which will get us the following data:
|
||||||
|
|
||||||
|
col0: 0b01
|
||||||
|
col1: 0b11
|
||||||
|
│└row0
|
||||||
|
└row1
|
||||||
|
|
||||||
|
The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS.
|
||||||
|
|
||||||
|
Further reading:
|
||||||
|
- [Wikipedia article](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit)
|
||||||
|
- [Deskthority article](https://deskthority.net/wiki/Keyboard_matrix)
|
||||||
|
- [Keyboard Matrix Help by Dave Dribin (2000)](https://www.dribin.org/dave/keyboard/one_html/)
|
||||||
|
- [How Key Matrices Works by PCBheaven](http://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (animated examples)
|
||||||
|
- [How keyboards work - QMK documentation](how_keyboards_work.md)
|
||||||
+35
-22
@@ -1,33 +1,46 @@
|
|||||||
# I2C Master Driver
|
# I2C Master Driver :id=i2c-master-driver
|
||||||
|
|
||||||
The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
|
The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs.
|
||||||
|
|
||||||
## Available functions
|
## An important note on I2C Addresses :id=note-on-i2c-addresses
|
||||||
|
|
||||||
|
All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting
|
||||||
|
the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed
|
||||||
|
on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be
|
||||||
|
shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`.
|
||||||
|
|
||||||
|
You can either do this on each call to the functions below, or once in your definition of the address. For example if your device has an address of `0x18`:
|
||||||
|
|
||||||
|
`#define MY_I2C_ADDRESS (0x18 << 1)`
|
||||||
|
|
||||||
|
See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details.
|
||||||
|
|
||||||
|
## Available functions :id=available-functions
|
||||||
|
|
||||||
|Function |Description |
|
|Function |Description |
|
||||||
|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|`void i2c_init(void);` |Initializes the I2C driver. This function should be called once before any transaction is initiated. |
|
|`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, uint16_t timeout);` |Starts an I2C transaction. Address is the 7-bit slave address without the direction bit. |
|
|`i2c_status_t i2c_start(uint8_t address, uint16_t timeout);` |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. |
|
|`i2c_status_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. |
|
|`i2c_status_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. |
|
|`i2c_status_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. |
|
|`i2c_status_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(void);` |Ends an I2C transaction. |
|
|`i2c_status_t i2c_stop(void);` |Ends an I2C transaction. |
|
||||||
|
|
||||||
### Function Return
|
### Function Return :id=function-return
|
||||||
|
|
||||||
All the above functions, except `void i2c_init(void);` return the following truth table:
|
All the above functions, except `void i2c_init(void);` return the following truth table:
|
||||||
|
|
||||||
|Return Value |Description |
|
|Return Constant |Value|Description |
|
||||||
|---------------|---------------------------------------------------|
|
|--------------------|-----|--------------------------------|
|
||||||
|0 |Operation executed successfully. |
|
|`I2C_STATUS_SUCCESS`|0 |Operation executed successfully.|
|
||||||
|-1 |Operation failed. |
|
|`I2C_STATUS_ERROR` |-1 |Operation failed. |
|
||||||
|-2 |Operation timed out. |
|
|`I2C_STATUS_TIMEOUT`|-2 |Operation timed out. |
|
||||||
|
|
||||||
|
|
||||||
## AVR
|
## AVR :id=avr
|
||||||
|
|
||||||
### Configuration
|
### Configuration :id=avr-configuration
|
||||||
|
|
||||||
The following defines can be used to configure the I2C master driver.
|
The following defines can be used to configure the I2C master driver.
|
||||||
|
|
||||||
@@ -37,12 +50,12 @@ The following defines can be used to configure the I2C master driver.
|
|||||||
|
|
||||||
AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required.
|
AVRs usually have set GPIO which turn into I2C pins, therefore no further configuration is required.
|
||||||
|
|
||||||
## ARM
|
## ARM :id=arm
|
||||||
|
|
||||||
For ARM the Chibios I2C HAL driver is under the hood.
|
For ARM the Chibios I2C HAL driver is under the hood.
|
||||||
This section assumes an STM32 MCU.
|
This section assumes an STM32 MCU.
|
||||||
|
|
||||||
### Configuration
|
### Configuration :id=arm-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.
|
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.
|
||||||
|
|
||||||
@@ -77,7 +90,7 @@ The ChibiOS I2C driver configuration depends on STM32 MCU:
|
|||||||
STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1;
|
STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1;
|
||||||
STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2;
|
STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2;
|
||||||
|
|
||||||
#### I2Cv1
|
#### I2Cv1 :id=i2cv1
|
||||||
STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using <https://www.playembedded.org/blog/stm32-i2c-chibios/#I2Cv1_configuration_structure> as a reference:
|
STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using <https://www.playembedded.org/blog/stm32-i2c-chibios/#I2Cv1_configuration_structure> as a reference:
|
||||||
|
|
||||||
| Variable | Default |
|
| Variable | Default |
|
||||||
@@ -86,7 +99,7 @@ STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1.
|
|||||||
| `I2C1_CLOCK_SPEED` | `100000` |
|
| `I2C1_CLOCK_SPEED` | `100000` |
|
||||||
| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` |
|
| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` |
|
||||||
|
|
||||||
#### I2Cv2
|
#### I2Cv2 :id=i2cv2
|
||||||
STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using <https://www.st.com/en/embedded-software/stsw-stm32126.html> as a reference:
|
STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using <https://www.st.com/en/embedded-software/stsw-stm32126.html> as a reference:
|
||||||
|
|
||||||
| Variable | Default |
|
| Variable | Default |
|
||||||
@@ -104,10 +117,10 @@ STM32 MCUs allow for different "alternate function" modes when configuring GPIO
|
|||||||
| `I2C1_SCL_PAL_MODE` | `4` |
|
| `I2C1_SCL_PAL_MODE` | `4` |
|
||||||
| `I2C1_SDA_PAL_MODE` | `4` |
|
| `I2C1_SDA_PAL_MODE` | `4` |
|
||||||
|
|
||||||
#### Other
|
#### Other :id=other
|
||||||
You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function:
|
You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function:
|
||||||
|
|
||||||
```C
|
```c
|
||||||
void i2c_init(void)
|
void i2c_init(void)
|
||||||
{
|
{
|
||||||
setPinInput(B6); // Try releasing special pins for a short time
|
setPinInput(B6); // Try releasing special pins for a short time
|
||||||
|
|||||||
+83
-8
@@ -13,28 +13,68 @@
|
|||||||
<meta property="og:image" content="https://i.imgur.com/svjvIrw.jpg">
|
<meta property="og:image" content="https://i.imgur.com/svjvIrw.jpg">
|
||||||
<meta property="og:url" content="https://docs.qmk.fm">
|
<meta property="og:url" content="https://docs.qmk.fm">
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css" title="light">
|
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css" title="light">
|
||||||
<link rel="stylesheet" href="qmk.css" title="dark" disabled>
|
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css" media="(prefers-color-scheme: dark)">
|
||||||
<link rel="stylesheet" href="sidebar.css" />
|
<link rel="stylesheet" href="//unpkg.com/[email protected]/dist/toc.css">
|
||||||
|
<link rel="stylesheet" href="qmk_custom_light.css">
|
||||||
|
<link rel="stylesheet" href="qmk_custom_dark.css" media="(prefers-color-scheme: dark)">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script>
|
<script>
|
||||||
window.$docsify = {
|
window.$docsify = {
|
||||||
alias : {
|
alias: {
|
||||||
|
// Translation aliases
|
||||||
'/en/(.*)': '/$1',
|
'/en/(.*)': '/$1',
|
||||||
'/en-us/(.*)': '/$1',
|
'/en-us/(.*)': '/$1',
|
||||||
'/en-gb/(.*)': '/$1',
|
'/en-gb/(.*)': '/$1',
|
||||||
'/.*/_langs.md': '/_langs.md',
|
'/.*/_langs.md': '/_langs.md',
|
||||||
|
|
||||||
|
// Moved pages
|
||||||
|
'/adding_a_keyboard_to_qmk': '/hardware_keyboard_guidelines',
|
||||||
|
'/build_environment_setup': '/getting_started_build_tools',
|
||||||
|
'/cli_dev_configuration': '/cli_configuration',
|
||||||
|
'/dynamic_macros': '/feature_dynamic_macros',
|
||||||
|
'/feature_common_shortcuts': '/feature_advanced_keycodes',
|
||||||
|
'/glossary': '/reference_glossary',
|
||||||
|
'/key_lock': '/feature_key_lock',
|
||||||
|
'/make_instructions': '/getting_started_make_guide',
|
||||||
|
'/porting_your_keyboard_to_qmk': '/hardware_avr',
|
||||||
|
'/space_cadet_shift': '/feature_space_cadet_shift',
|
||||||
|
'/getting_started_getting_help': '/support',
|
||||||
|
'/tap_dance': '/feature_tap_dance',
|
||||||
|
'/unicode': '/feature_unicode',
|
||||||
|
'/python_development': '/cli_development',
|
||||||
},
|
},
|
||||||
basePath: '/',
|
basePath: '/',
|
||||||
name: 'QMK Firmware',
|
name: 'QMK Firmware',
|
||||||
nameLink: '/',
|
nameLink: {
|
||||||
|
'/de/': '/#/de/',
|
||||||
|
'/es/': '/#/es/',
|
||||||
|
'/fr-fr/': '/#/fr-fr/',
|
||||||
|
'/he-il/': '/#/he-il/',
|
||||||
|
'/ja/': '/#/ja/',
|
||||||
|
'/pt-br/': '/#/pt-br/',
|
||||||
|
'/ru-ru/': '/#/ru-ru/',
|
||||||
|
'/zh-cn/': '/#/zh-cn/',
|
||||||
|
'/': '/#/'
|
||||||
|
},
|
||||||
repo: 'qmk/qmk_firmware',
|
repo: 'qmk/qmk_firmware',
|
||||||
loadSidebar: '_summary.md',
|
loadSidebar: '_summary.md',
|
||||||
loadNavbar: '_langs.md',
|
loadNavbar: '_langs.md',
|
||||||
mergeNavbar: true,
|
mergeNavbar: true,
|
||||||
auto2top: true,
|
auto2top: true,
|
||||||
|
autoHeader: true,
|
||||||
|
fallbackLanguages: [
|
||||||
|
'de',
|
||||||
|
'es',
|
||||||
|
'fr-fr',
|
||||||
|
'he-il',
|
||||||
|
'ja',
|
||||||
|
'pt-br',
|
||||||
|
'ru-ru',
|
||||||
|
'zh-cn'
|
||||||
|
],
|
||||||
formatUpdated: '{YYYY}/{MM}/{DD} {HH}:{mm}',
|
formatUpdated: '{YYYY}/{MM}/{DD} {HH}:{mm}',
|
||||||
search: {
|
search: {
|
||||||
paths: 'auto',
|
paths: 'auto',
|
||||||
@@ -42,16 +82,48 @@
|
|||||||
'/es/': 'Buscar',
|
'/es/': 'Buscar',
|
||||||
'/zh-cn/': '搜索',
|
'/zh-cn/': '搜索',
|
||||||
'/ja/': '検索',
|
'/ja/': '検索',
|
||||||
|
'/pt-br/': 'Busca',
|
||||||
'/': 'Search'
|
'/': 'Search'
|
||||||
},
|
},
|
||||||
noData: {
|
noData: {
|
||||||
'/es/': '¡Ningún resultado!',
|
'/es/': '¡Ningún resultado!',
|
||||||
'/zh-cn/': '没有结果!',
|
'/zh-cn/': '没有结果!',
|
||||||
'/ja/': '見つかりません!',
|
'/ja/': '見つかりません!',
|
||||||
|
'/pt-br/': 'Nenhum resultado!',
|
||||||
'/': 'No results!'
|
'/': 'No results!'
|
||||||
},
|
},
|
||||||
depth: 6
|
depth: 6
|
||||||
},
|
},
|
||||||
|
markdown: {
|
||||||
|
smartypants: true,
|
||||||
|
smartLists: true,
|
||||||
|
},
|
||||||
|
copyCode: {
|
||||||
|
buttonText: {
|
||||||
|
'/zh-cn/': '点击复制',
|
||||||
|
'/ru/' : 'Скопировать в буфер обмена',
|
||||||
|
'/de-de/': 'Klicken Sie zum Kopieren',
|
||||||
|
'/es/' : 'Haga clic para copiar',
|
||||||
|
'/' : 'Copy to clipboard'
|
||||||
|
},
|
||||||
|
errorText: {
|
||||||
|
'/zh-cn/': '错误',
|
||||||
|
'/ru/' : 'ошибка',
|
||||||
|
'/' : 'Error'
|
||||||
|
},
|
||||||
|
successText: {
|
||||||
|
'/zh-cn/': '复制',
|
||||||
|
'/ru/' : 'Скопировано',
|
||||||
|
'/de-de/': 'Kopiert',
|
||||||
|
'/es/' : 'Copiado',
|
||||||
|
'/' : 'Copied'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toc: {
|
||||||
|
scope: '.markdown-section',
|
||||||
|
headings: 'h1, h2',
|
||||||
|
title: 'Table of Contents',
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
function (hook, vm) {
|
function (hook, vm) {
|
||||||
hook.beforeEach(function (html) {
|
hook.beforeEach(function (html) {
|
||||||
@@ -60,9 +132,9 @@
|
|||||||
.replace('raw.githubusercontent.com', 'github.com')
|
.replace('raw.githubusercontent.com', 'github.com')
|
||||||
.replace(/\/master/, '/blob/master')
|
.replace(/\/master/, '/blob/master')
|
||||||
} else {
|
} else {
|
||||||
url = 'https://github.com/qmk/qmk_firmware/blob/master/docs/' + vm.route.file
|
url = 'https://github.com/qmk/qmk_firmware/edit/master/docs/' + vm.route.file
|
||||||
}
|
}
|
||||||
var editHtml = '[:memo: Edit Document](' + url + ')\n'
|
var editHtml = ':pencil2: [Edit this page](' + url + ')\n'
|
||||||
return html
|
return html
|
||||||
+ '\n\n----\n\n'
|
+ '\n\n----\n\n'
|
||||||
+ editHtml
|
+ editHtml
|
||||||
@@ -74,13 +146,16 @@
|
|||||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></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/search.min.js"></script>
|
||||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
||||||
|
<script src="//unpkg.com/docsify-copy-code@2"></script>
|
||||||
|
<script src="//unpkg.com/[email protected]/dist/toc.js"></script>
|
||||||
<script src="//unpkg.com/prismjs/components/prism-bash.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-c.min.js"></script>
|
||||||
<script src="//unpkg.com/prismjs/components/prism-cpp.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-json.min.js"></script>
|
||||||
<script src="//unpkg.com/prismjs/components/prism-makefile.min.js"></script>
|
<script src="//unpkg.com/prismjs/components/prism-makefile.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Register the offline cache worker
|
// Register the cache worker for offline viewing mode
|
||||||
|
// https://docsify.now.sh/pwa
|
||||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||||
navigator.serviceWorker.register('sw.js')
|
navigator.serviceWorker.register('sw.js')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
# GPIO Control
|
# GPIO Control :id=gpio-control
|
||||||
|
|
||||||
QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms.
|
QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms.
|
||||||
|
|
||||||
## Functions
|
## Functions :id=functions
|
||||||
|
|
||||||
The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
|
The following functions can provide basic control of GPIOs and are found in `quantum/quantum.h`.
|
||||||
|
|
||||||
|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|
|Function |Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|
||||||
|----------------------|------------------------------------------------------------------|------------------------------------------------|-------------------------------------------------|
|
|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------|
|
||||||
|`setPinInput(pin)` |Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
|
| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
|
||||||
|`setPinInputHigh(pin)`|Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
|
| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
|
||||||
|`setPinInputLow(pin)` |Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
|
| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
|
||||||
|`setPinOutput(pin)` |Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|
| `setPinOutput(pin)` | Set pin as output | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
|
||||||
|`writePinHigh(pin)` |Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
|
| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
|
||||||
|`writePinLow(pin)` |Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
|
| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
|
||||||
|`writePin(pin, level)`|Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
|
| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
|
||||||
|`readPin(pin)` |Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
|
| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
|
||||||
|
|
||||||
## Advanced Settings
|
## Advanced Settings :id=advanced-settings
|
||||||
|
|
||||||
Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.
|
Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.
|
||||||
+133
-20
@@ -1,6 +1,14 @@
|
|||||||
# ISP Flashing Guide
|
# ISP Flashing Guide
|
||||||
|
|
||||||
If you're having trouble flashing/erasing your board, and running into cryptic error messages like any of the following:
|
ISP flashing (also known as ICSP flashing) is the process of programming a microcontroller directly. This allows you to replace the bootloader, or change the "fuses" on the controller, which control a number of hardware- and software-related functions, such as the speed of the controller, how it boots, and other options.
|
||||||
|
|
||||||
|
The main use of ISP flashing for QMK is flashing or replacing the bootloader on your AVR-based controller (Pro Micros, or V-USB chips).
|
||||||
|
|
||||||
|
?> This is only for programming AVR based boards, such as the Pro Micro or other ATmega controllers. It is not for Arm controllers, such as the Proton C.
|
||||||
|
|
||||||
|
## Dealing with Corrupted Bootloaders
|
||||||
|
|
||||||
|
If you're having trouble flashing/erasing your board, and running into cryptic error messages like any of the following for a DFU based controller:
|
||||||
|
|
||||||
libusb: warning [darwin_transfer_status] transfer error: timed out
|
libusb: warning [darwin_transfer_status] transfer error: timed out
|
||||||
dfu.c:844: -ETIMEDOUT: Transfer timed out, NAK 0xffffffc4 (-60)
|
dfu.c:844: -ETIMEDOUT: Transfer timed out, NAK 0xffffffc4 (-60)
|
||||||
@@ -19,16 +27,60 @@ If you're having trouble flashing/erasing your board, and running into cryptic e
|
|||||||
Memory write error, use debug for more info.
|
Memory write error, use debug for more info.
|
||||||
commands.c:360: Error writing memory data. (err -4)
|
commands.c:360: Error writing memory data. (err -4)
|
||||||
|
|
||||||
You're likely going to need to ISP flash your board/device to get it working again. Luckily, this process is pretty straight-forward, provided you have any extra programmable keyboard, Pro Micro, or Teensy 2.0/Teensy 2.0++. There are also dedicated ISP flashers available for this, but most cost >$15, and it's assumed that if you are googling this error, this is the first you've heard about ISP flashing, and don't have one readily available (whereas you might have some other AVR board). __We'll be using a Teensy 2.0 or Pro Micro with Windows 10 in this guide__ - if you are comfortable doing this on another system, please consider editing this guide and contributing those instructions!
|
Or, if you see this sort of message for a Pro Micro based controller:
|
||||||
|
|
||||||
|
avrdude: butterfly_recv(): programmer is not responding
|
||||||
|
avrdude: butterfly_recv(): programmer is not responding
|
||||||
|
avrdude: verification error, first mismatch at byte 0x002a
|
||||||
|
0x2b != 0x75
|
||||||
|
avrdude: verification error; content mismatch
|
||||||
|
avrdude: verification error; content mismatch
|
||||||
|
|
||||||
|
|
||||||
|
You're likely going to need to ISP flash your board/device to get it working again.
|
||||||
|
|
||||||
|
## Hardware Needed
|
||||||
|
|
||||||
|
You'll need one of the following to actually perform the ISP flashing (followed by the protocol they use):
|
||||||
|
|
||||||
|
* [SparkFun PocketAVR](https://www.sparkfun.com/products/9825) - (USB Tiny)
|
||||||
|
* [USBtinyISP AVR Programmer Kit](https://www.adafruit.com/product/46) - (USB Tiny)
|
||||||
|
* [Teensy 2.0](https://www.pjrc.com/store/teensy.html) - (avrisp)
|
||||||
|
* [Pro Micro](https://www.sparkfun.com/products/12640) - (avrisp)
|
||||||
|
* [Bus Pirate](https://www.adafruit.com/product/237) - (buspirate)
|
||||||
|
|
||||||
|
There are other devices that can be used to ISP flash, but these are the main ones. Also, all product links are to the official versions. You can source them elsewhere.
|
||||||
|
|
||||||
|
You'll also need something to wire your "ISP Programmer" to the device that you're programming. Some PCBs may have ISP headers that you can use directly, but this often isn't the case, so you'll likely need to solder to the controller itself or to different switches or other components.
|
||||||
|
|
||||||
|
### The ISP Firmware
|
||||||
|
|
||||||
|
The Teensy and Pro Micro controllers will need you to flash the ISP firmware to the controllers before you can use them as an ISP programmer. The rest of the hardware should come preprogrammed. So, for these controllers, download the correct hex file, and flash it first.
|
||||||
|
|
||||||
|
* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`)
|
||||||
|
* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) (`10/B6`)
|
||||||
|
|
||||||
|
Once you've flashed your controller, you won't need this hex file anymore.
|
||||||
|
|
||||||
## Software Needed
|
## Software Needed
|
||||||
|
|
||||||
* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) (if using a Teensy)
|
The QMK Toolbox can be used for most (all) of this.
|
||||||
* QMK Toolbox (flash as usual - be sure to select the correct MCU) or `avrdude` via [WinAVR](http://www.ladyada.net/learn/avr/setup-win.html) (for Teensy & Pro Micro)
|
|
||||||
|
However, you can grab the [Teensy Loader](https://www.pjrc.com/teensy/loader.html) to flash your Teensy 2.0 board, if you are using that. Or you can use `avrdude` (installed as part of `qmk_install.sh`), or [AVRDUDESS](https://blog.zakkemble.net/avrdudess-a-gui-for-avrdude/) (for Windows) to flash the Pro Micro, and the ISP flashing.
|
||||||
|
|
||||||
|
|
||||||
## Wiring
|
## Wiring
|
||||||
|
|
||||||
This is pretty straight-forward - we'll be connecting like-things to like-things in the following manner:
|
This is pretty straight-forward - we'll be connecting like-things to like-things in the following manner.
|
||||||
|
|
||||||
|
### SparkFun Pocket AVR
|
||||||
|
|
||||||
|
PocketAVR RST <-> Keyboard RESET
|
||||||
|
PocketAVR SCLK <-> Keyboard B1 (SCLK)
|
||||||
|
PocketAVR MOSI <-> Keyboard B2 (MOSI)
|
||||||
|
PocketAVR MISO <-> Keyboard B3 (MISO)
|
||||||
|
PocketAVR VCC <-> Keyboard VCC
|
||||||
|
PocketAVR GND <-> Keyboard GND
|
||||||
|
|
||||||
### Teensy 2.0
|
### Teensy 2.0
|
||||||
|
|
||||||
@@ -39,6 +91,8 @@ This is pretty straight-forward - we'll be connecting like-things to like-things
|
|||||||
Teensy VCC <-> Keyboard VCC
|
Teensy VCC <-> Keyboard VCC
|
||||||
Teensy GND <-> Keyboard GND
|
Teensy GND <-> Keyboard GND
|
||||||
|
|
||||||
|
!> Note that the B0 pin on the Teensy is wired to the RESET/RST pin on the keyboard's controller. ***DO NOT*** wire the RESET pin on the Teensy to the RESET on the keyboard.
|
||||||
|
|
||||||
### Pro Micro
|
### Pro Micro
|
||||||
|
|
||||||
Pro Micro 10 (B6) <-> Keyboard RESET
|
Pro Micro 10 (B6) <-> Keyboard RESET
|
||||||
@@ -48,45 +102,61 @@ This is pretty straight-forward - we'll be connecting like-things to like-things
|
|||||||
Pro Micro VCC <-> Keyboard VCC
|
Pro Micro VCC <-> Keyboard VCC
|
||||||
Pro Micro GND <-> Keyboard GND
|
Pro Micro GND <-> Keyboard GND
|
||||||
|
|
||||||
## The ISP Firmware (now pre-compiled)
|
!> Note that the 10/B6 pin on the Pro Micro is wired to the RESET/RST pin on the keyboard's controller. ***DO NOT*** wire the RESET pin on the Pro Micro to the RESET on the keyboard.
|
||||||
|
|
||||||
The only difference between the .hex files below is which pin is connected to RESET. You can use them on other boards as well, as long as you're aware of the pins being used. If for some reason neither of these pins are available, [create an issue](https://github.com/qmk/qmk_firmware/issues/new), and we can generate one for you!
|
|
||||||
|
|
||||||
* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`)
|
## Flashing Your Keyboard
|
||||||
* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) (`B6/10`)
|
|
||||||
|
|
||||||
**Flash your Teenys/Pro Micro with one of these and continue - you won't need the file after flashing your ISP device.**
|
After you have your ISP programmer set up, and wired to your keyboard, it's time to flash your keyboard.
|
||||||
|
|
||||||
## Just the Bootloader File
|
### The Bootloader File
|
||||||
|
|
||||||
If you just want to get things back to normal, you can flash only a bootloader from [`util/` folder](https://github.com/qmk/qmk_firmware/tree/master/util), and use your normal process to flash the firmware afterwards. Be sure to flash the correct bootloader for your chip:
|
The simplest and quickest way to get things back to normal is to flash only a bootloader to the keyboard. Once this is done, you can connect the keyboard normally and flash the keyboard like you normally would.
|
||||||
|
|
||||||
|
You can find the stock bootloaders in the [`util/` folder](https://github.com/qmk/qmk_firmware/tree/master/util). Be sure to flash the correct bootloader for your chip:
|
||||||
|
|
||||||
* [`atmega32u4`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1_0_0.hex) - Most keyboards, Planck Rev 1-5, Preonic Rev 1-2
|
* [`atmega32u4`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1_0_0.hex) - Most keyboards, Planck Rev 1-5, Preonic Rev 1-2
|
||||||
|
* [`Pro Micro`](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro16.hex) - The default bootloader for Pro Micro controllers
|
||||||
* [`at90usb1286`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128x_1_0_1.hex) - Planck Light Rev 1
|
* [`at90usb1286`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128x_1_0_1.hex) - Planck Light Rev 1
|
||||||
* [`atmega32a`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32a_1_0_0.hex) - jj40
|
* [`atmega32a`](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32a_1_0_0.hex) - jj40, and other V-USB/ps2avrGB keyboards
|
||||||
|
|
||||||
If you're not sure what your board uses, look in the `rules.mk` file for the keyboard in QMK. The `MCU =` line will have the value you need. It may differ between different versions of the board.
|
If you're not sure what your board uses, look in the `rules.mk` file for the keyboard in QMK. The `MCU =` line will have the value you need. It may differ between different versions of the board.
|
||||||
|
|
||||||
### Advanced/Production Techniques
|
### Production Techniques
|
||||||
|
|
||||||
If you'd like to flash both the bootloader **and** the regular firmware at the same time, you need to combine the files.
|
If you'd like to flash both the bootloader **and** the regular firmware at the same time, there are two options to do so. Manually, or with the `:production` target when compiling.
|
||||||
|
|
||||||
|
To do this manually:
|
||||||
|
|
||||||
1. Open the original firmware .hex file in a text editor
|
1. Open the original firmware .hex file in a text editor
|
||||||
2. Remove the last line (which should be `:00000001FF` - this is an EOF message)
|
2. Remove the last line (which should be `:00000001FF` - this is an EOF message)
|
||||||
3. Copy the entire bootloader's contents onto a new line (with no empty lines between) and paste it at the end of the original file
|
3. Copy the entire bootloader's contents onto a new line (with no empty lines between) and paste it at the end of the original file
|
||||||
4. Save it as a new file by naming it `<keyboard>_<keymap>_production.hex`
|
4. Save it as a new file by naming it `<keyboard>_<keymap>_production.hex`
|
||||||
|
|
||||||
It's possible to use other bootloaders here in the same way, but __you need a bootloader__, otherwise you'll have to use ISP again to write new firmware to your keyboard.
|
?> It's possible to use other bootloaders here in the same way, but __you need a bootloader__, otherwise you'll have to use ISP again to write new firmware to your keyboard.
|
||||||
|
|
||||||
|
To do this the easy way, you can flash the board using the `:production` target when compiling. This compiles the firmware, then compiles the QMK DFU bootloader, and then creates a combined image. Once this is done, you'll see three files:
|
||||||
|
* `<keyboard>_<keymap>.hex`
|
||||||
|
* `<keyboard>_<keymap>_bootloader.hex`
|
||||||
|
* `<keyboard>_<keymap>_production.hex`
|
||||||
|
|
||||||
|
The QMK DFU bootloader has only really been tested on `atmega32u4` controllers (such as the AVR based Planck boards, and the Pro Micro), and hasn't been tested on other controllers. However, it will definitely not work on V-USB controllers, such as the `atmega32a` or `atmega328p`.
|
||||||
|
|
||||||
|
You can flash either the bootloader or the production firmware file. The production firmware file will take a lot longer to flash, since it's flashing a lot more data.
|
||||||
|
|
||||||
|
?> Note: You should stay with the same bootloader. If you're using DFU already, switching to QMK DFU is fine. But flashing QMK DFU onto a Pro Micro, for instance, has additional steps needed.
|
||||||
|
|
||||||
## Flashing Your Bootloader/Production File
|
## Flashing Your Bootloader/Production File
|
||||||
|
|
||||||
Make sure your keyboard is unplugged from any device, and plug in your Teensy.
|
Make sure your keyboard is unplugged from any device, and plug in your ISP Programmer.
|
||||||
|
|
||||||
|
If you want to change bootloader types, You'll need to use the command line.
|
||||||
|
|
||||||
### QMK Toolbox
|
### QMK Toolbox
|
||||||
|
|
||||||
1. `AVRISP device connected` will show up in yellow
|
1. `AVRISP device connected` or `USB Tiny device connected` will show up in yellow
|
||||||
2. Select the correct bootloader/production .hex file with the `Open` dialog (spaces can't be in the path)
|
2. Select the correct bootloader/production .hex file with the `Open` dialog (spaces can't be in the path)
|
||||||
3. Be sure the correct `Microcontroller` option is selected
|
3. Be sure the correct `Microcontroller` option for the keyboard you're flashing (not the ISP programmer) is selected
|
||||||
4. Hit `Flash`
|
4. Hit `Flash`
|
||||||
5. Wait, as nothing will output for a while, especially with production files
|
5. Wait, as nothing will output for a while, especially with production files
|
||||||
|
|
||||||
@@ -94,7 +164,7 @@ If the verification and fuse checks are ok, you're done! Your board may restart
|
|||||||
|
|
||||||
### Command Line
|
### Command Line
|
||||||
|
|
||||||
Open `cmd` and navigate to your where your modified .hex file is. We'll pretend this file is called `main.hex`, and that your Teensy 2.0 is on the `COM3` port - if you're unsure, you can open your Device Manager, and look for `Ports > USB Serial Device`. Use that COM port here. You can confirm it's the right port with:
|
Open a terminal (`cmd` on Windows, for instance) and navigate to your where your modified .hex file is. We'll pretend this file is called `main.hex`, and that your Teensy 2.0 is on the `COM3` port - if you're unsure, you can open your Device Manager, and look for `Ports > USB Serial Device`. Use that COM port here. You can confirm it's the right port with:
|
||||||
|
|
||||||
avrdude -c avrisp -P COM3 -p atmega32u4
|
avrdude -c avrisp -P COM3 -p atmega32u4
|
||||||
|
|
||||||
@@ -129,4 +199,47 @@ You should see a couple of progress bars, then you should see:
|
|||||||
|
|
||||||
Which means everything should be ok! Your board may restart automatically, otherwise, unplug your Teensy and plug in your keyboard - you can leave your Teensy wired to your keyboard while testing things, but it's recommended that you desolder it/remove the wiring once you're sure everything works.
|
Which means everything should be ok! Your board may restart automatically, otherwise, unplug your Teensy and plug in your keyboard - you can leave your Teensy wired to your keyboard while testing things, but it's recommended that you desolder it/remove the wiring once you're sure everything works.
|
||||||
|
|
||||||
|
If you're using a SparkFun PocketAVR Programmer, or another USB Tiny based ISP programmer, you will want to use something like this:
|
||||||
|
|
||||||
|
avrdude -c usbtiny -P usb -p atmega32u4
|
||||||
|
|
||||||
|
#### Advanced: Changing Fuses
|
||||||
|
|
||||||
|
If you're switching bootloaders, such as flashing QMK DFU on a Pro Micro, you will need to change the fuses, in additional to flashing the bootloader hex file. This is because `caterina` (the Pro Micro bootloader) and `dfu` handle the startup routines differently, and that behavior is controlled by the fuses.
|
||||||
|
|
||||||
|
!> This is one area that it is very important to be careful, as changing fuses is one of the ways that you can permanently brick your controller.
|
||||||
|
|
||||||
|
For this, we are assuming the 5V 16MHz versions of the `atmega32u4` (such as the 5V Pro Micro).
|
||||||
|
|
||||||
|
For DFU on the `atmega32u4`, these are the fuse settings that you want:
|
||||||
|
|
||||||
|
| Fuse | Setting |
|
||||||
|
|----------|------------------|
|
||||||
|
| Low | `0x5E` |
|
||||||
|
| High | `0xD9` or `0x99` |
|
||||||
|
| Extended | `0xC3` |
|
||||||
|
|
||||||
|
The High fuse can be 0xD9 or 0x99. The difference is that 0xD9 disables JTAG, which QMK Firmware disables via software as well, while 0x99 doesn't disable JTAG.
|
||||||
|
|
||||||
|
To set this add `-U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m` to your command. So the final command should look something like:
|
||||||
|
|
||||||
|
avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m
|
||||||
|
|
||||||
|
For Caterina on the `atmega32u4`, these are the fuse settings that you want:
|
||||||
|
|
||||||
|
| Fuse | Setting|
|
||||||
|
|----------|--------|
|
||||||
|
| Low | `0xFF` |
|
||||||
|
| High | `0xD9` |
|
||||||
|
| Extended | `0xC3` |
|
||||||
|
|
||||||
|
To set this add `-U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xC3:m` to your command. So the final command should look something like:
|
||||||
|
|
||||||
|
avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xC3:m
|
||||||
|
|
||||||
|
|
||||||
|
If you are using a different controller or want different configuration, you can use [this AVR Fuse Calculator](http://www.engbedded.com/fusecalc/) to find a better value for you.
|
||||||
|
|
||||||
|
## Help
|
||||||
|
|
||||||
If you have any questions/problems, feel free to [open an issue](https://github.com/qmk/qmk_firmware/issues/new)!
|
If you have any questions/problems, feel free to [open an issue](https://github.com/qmk/qmk_firmware/issues/new)!
|
||||||
Loaded 100 of 4332 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user