forked from mirrors/qmk_firmware
Compare commits
810 Commits
0.13.1
...
python_opt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e293bf243d | ||
|
|
286acfe7fd | ||
|
|
6d20b28354 | ||
|
|
846da06380 | ||
|
|
243fc17e41 | ||
|
|
f394f23ac6 | ||
|
|
0ca53fa307 | ||
|
|
8c361d6c41 | ||
|
|
8d30209260 | ||
|
|
8db1be6420 | ||
|
|
40bf61118e | ||
|
|
90e57b7b0a | ||
|
|
c234341cf6 | ||
|
|
29df3ce83b | ||
|
|
291455098f | ||
|
|
7ab4902543 | ||
|
|
8f36af8409 | ||
|
|
50a312b635 | ||
|
|
25f1c242f8 | ||
|
|
873658a76d | ||
|
|
f80ee5639e | ||
|
|
745f5f6532 | ||
|
|
085db5ec8d | ||
|
|
eb2886369d | ||
|
|
8f1eccc59b | ||
|
|
438eee96e8 | ||
|
|
2cb4301656 | ||
|
|
0624698d33 | ||
|
|
f106f77692 | ||
|
|
88e53ad9ca | ||
|
|
e4c5b1bbbb | ||
|
|
f6ac5abd95 | ||
|
|
dc39d90270 | ||
|
|
18f6ded5fa | ||
|
|
050457818c | ||
|
|
67af692c97 | ||
|
|
1f4e20cfda | ||
|
|
8d9f527081 | ||
|
|
fc749b40e6 | ||
|
|
c835d2e71d | ||
|
|
7e832e46de | ||
|
|
76e856d052 | ||
|
|
d456963177 | ||
|
|
e3030bff5e | ||
|
|
4dddcb4f03 | ||
|
|
5b7cf9fdc8 | ||
|
|
3c790123ce | ||
|
|
1272ecd73c | ||
|
|
7c5ef4060e | ||
|
|
11f66c317a | ||
|
|
6dfe915e26 | ||
|
|
8dc036c2e4 | ||
|
|
4379afca28 | ||
|
|
939ce6a486 | ||
|
|
37fba09021 | ||
|
|
dfcefc2d5d | ||
|
|
8de028f188 | ||
|
|
8694e2d3f0 | ||
|
|
7fefe128cc | ||
|
|
feaf972eb7 | ||
|
|
0311c8036d | ||
|
|
6e132884b3 | ||
|
|
18554d1134 | ||
|
|
9e9e9b3898 | ||
|
|
8e607851fb | ||
|
|
f81cd4696e | ||
|
|
172e6a7030 | ||
|
|
ef92c9ee2c | ||
|
|
e7ddbc394b | ||
|
|
67fa2568fe | ||
|
|
658ab47908 | ||
|
|
89c01970e3 | ||
|
|
d04f7bc160 | ||
|
|
2f08a34394 | ||
|
|
a9c6adb083 | ||
|
|
f9d88da86f | ||
|
|
9956ff4e03 | ||
|
|
2538d341d8 | ||
|
|
83ee79565c | ||
|
|
d59f8d1c02 | ||
|
|
5c3991cb90 | ||
|
|
abee0610ee | ||
|
|
f8d0ea9206 | ||
|
|
9aea0fd52b | ||
|
|
706c8bebca | ||
|
|
42d8ee16e1 | ||
|
|
25004123ce | ||
|
|
403849bff0 | ||
|
|
d150595f29 | ||
|
|
ba35c11807 | ||
|
|
a61c38c7ec | ||
|
|
875bb48a20 | ||
|
|
968e4f96a4 | ||
|
|
03f7bec6c8 | ||
|
|
311cf865dc | ||
|
|
e2c5893405 | ||
|
|
d37900b906 | ||
|
|
4720aa4a34 | ||
|
|
06971da0be | ||
|
|
ed0451bc28 | ||
|
|
2d6fe6eed4 | ||
|
|
22cd151fc3 | ||
|
|
96c8afea2d | ||
|
|
346f4548db | ||
|
|
3966599940 | ||
|
|
ff61df103e | ||
|
|
a0959f1b33 | ||
|
|
b151153211 | ||
|
|
09e22b9cfc | ||
|
|
41ba616463 | ||
|
|
9cf4148aa9 | ||
|
|
d82e5055dd | ||
|
|
c00a9937f2 | ||
|
|
3be3cdafa2 | ||
|
|
d0a3506d0f | ||
|
|
f5c2f7153d | ||
|
|
640f0fc7c6 | ||
|
|
3d546c0853 | ||
|
|
d7ecfa8382 | ||
|
|
a9525d88a3 | ||
|
|
a2a524afbb | ||
|
|
0713797c58 | ||
|
|
8d0a610f6e | ||
|
|
ae45faca26 | ||
|
|
6dc94019e4 | ||
|
|
449b4b8d86 | ||
|
|
fda4149cc3 | ||
|
|
836b8f7d64 | ||
|
|
3d62e1dfbf | ||
|
|
52028ceea1 | ||
|
|
a08486597d | ||
|
|
f8acb1ee10 | ||
|
|
f48bd8cde3 | ||
|
|
dc17180f84 | ||
|
|
c16b7d63e7 | ||
|
|
421fd75541 | ||
|
|
db36e2be9f | ||
|
|
0f226a30be | ||
|
|
0ef145db15 | ||
|
|
641141c519 | ||
|
|
2e90ef0536 | ||
|
|
6fe3943ad3 | ||
|
|
b2fdd48744 | ||
|
|
cfc7ee61c5 | ||
|
|
d684b8cafe | ||
|
|
7a6e630ffd | ||
|
|
32b2ac0a80 | ||
|
|
e21a039901 | ||
|
|
39c8ed32b4 | ||
|
|
ca0070d11c | ||
|
|
a47f482d24 | ||
|
|
5073dc33e9 | ||
|
|
9177e22d2c | ||
|
|
21aa7890cb | ||
|
|
b829a1d264 | ||
|
|
f287597c19 | ||
|
|
cbfa2dba25 | ||
|
|
4dda716712 | ||
|
|
d9add95037 | ||
|
|
9975e17712 | ||
|
|
17d0fad762 | ||
|
|
13defb0bef | ||
|
|
9dcd03b6ca | ||
|
|
84e691717c | ||
|
|
e0acd3e53d | ||
|
|
f3fb3849a2 | ||
|
|
c277ae4768 | ||
|
|
c508da8a8e | ||
|
|
b52b8f1d23 | ||
|
|
9399865b0d | ||
|
|
b7ef959400 | ||
|
|
827e742bd4 | ||
|
|
17e6e04600 | ||
|
|
5e3ec2faf0 | ||
|
|
a0ed583b75 | ||
|
|
2f910e1b2a | ||
|
|
093a89c534 | ||
|
|
f922133d30 | ||
|
|
c1bd8eed76 | ||
|
|
5686a00a9c | ||
|
|
9dffd35762 | ||
|
|
b72f10c635 | ||
|
|
59862d30d0 | ||
|
|
b10728edc1 | ||
|
|
680cc1fab4 | ||
|
|
2e68897a62 | ||
|
|
49fd3c0760 | ||
|
|
415dd21206 | ||
|
|
94e80912a4 | ||
|
|
102442a841 | ||
|
|
7b666245d6 | ||
|
|
fff115c1a4 | ||
|
|
23631de191 | ||
|
|
c7277a1420 | ||
|
|
0374e4c733 | ||
|
|
7e4f01f454 | ||
|
|
56ce0e4e33 | ||
|
|
add10524d6 | ||
|
|
a1e575780d | ||
|
|
7aab06ffdf | ||
|
|
3d3b9807ab | ||
|
|
ab6128e86d | ||
|
|
3e1e64ca19 | ||
|
|
8128c5f822 | ||
|
|
25fffb7da8 | ||
|
|
770a3349be | ||
|
|
c38332a5c7 | ||
|
|
c7c9f3e3cf | ||
|
|
01cb2867db | ||
|
|
e660dcff09 | ||
|
|
17f51fa9df | ||
|
|
6eb18a6ccb | ||
|
|
a6f030fb42 | ||
|
|
af91221ddb | ||
|
|
2344d06475 | ||
|
|
261d94ce34 | ||
|
|
eaa2e0cb24 | ||
|
|
a0cc2dc6d0 | ||
|
|
65fe74fde0 | ||
|
|
b8711b9726 | ||
|
|
9544b41640 | ||
|
|
e5d3e5a989 | ||
|
|
d64a853b55 | ||
|
|
554c36a055 | ||
|
|
5c6c37e3a9 | ||
|
|
c22f4aeb8e | ||
|
|
234d37ec16 | ||
|
|
bc01ee2a6e | ||
|
|
aa923b2034 | ||
|
|
160f9144c2 | ||
|
|
0d74ed3c35 | ||
|
|
a72172a8fd | ||
|
|
7d1194de01 | ||
|
|
e628051505 | ||
|
|
275996f4c1 | ||
|
|
3ea3f32dfe | ||
|
|
d66090af19 | ||
|
|
b963049305 | ||
|
|
5386c4c7b2 | ||
|
|
c1a3060431 | ||
|
|
b769b36202 | ||
|
|
879185a214 | ||
|
|
726368ce67 | ||
|
|
995c9dff49 | ||
|
|
69604e1750 | ||
|
|
06aea834c4 | ||
|
|
e128d45420 | ||
|
|
0717890353 | ||
|
|
cd78ab25a9 | ||
|
|
beaebdf8eb | ||
|
|
a5c2a74b8c | ||
|
|
ebaba80287 | ||
|
|
15e408a6a5 | ||
|
|
1593e78c97 | ||
|
|
452a5216e2 | ||
|
|
769396839b | ||
|
|
17991629c1 | ||
|
|
513f5b0655 | ||
|
|
b158afee93 | ||
|
|
57306fb61c | ||
|
|
d9610120de | ||
|
|
a78964c918 | ||
|
|
f461adbd1d | ||
|
|
cc815c4d83 | ||
|
|
5cecfe8c9b | ||
|
|
57158cc3bc | ||
|
|
8e22da67c1 | ||
|
|
330fe1d1cc | ||
|
|
f5820059e4 | ||
|
|
54c368d3aa | ||
|
|
8f4767d966 | ||
|
|
9ce4bdfd6a | ||
|
|
a0fed0ea17 | ||
|
|
76c23b15ab | ||
|
|
4c1ea0a522 | ||
|
|
c01f873978 | ||
|
|
924c25e702 | ||
|
|
95d2f7c3c5 | ||
|
|
3d49563535 | ||
|
|
ca570947b0 | ||
|
|
31130b9031 | ||
|
|
8e96c5a060 | ||
|
|
81821f0a12 | ||
|
|
e1500ce493 | ||
|
|
4c0d8ae8d7 | ||
|
|
de8fada3a3 | ||
|
|
aeaa209b9d | ||
|
|
6955c5a002 | ||
|
|
82aa9ad4a5 | ||
|
|
068af97b7a | ||
|
|
e756586f41 | ||
|
|
58142f0726 | ||
|
|
6cdc996e0b | ||
|
|
7e06393407 | ||
|
|
b098757a7e | ||
|
|
8508fc8b98 | ||
|
|
6c7450dad7 | ||
|
|
c14fa1e28f | ||
|
|
e6887f4260 | ||
|
|
d8e38ef0b1 | ||
|
|
39b2b2b010 | ||
|
|
fef78c41cd | ||
|
|
de5c30a9ba | ||
|
|
8761e973ec | ||
|
|
433834fb8b | ||
|
|
86422f87c6 | ||
|
|
388c151de7 | ||
|
|
396abb0244 | ||
|
|
7599cd4e50 | ||
|
|
de2294413f | ||
|
|
4e32465f06 | ||
|
|
08ec7618a1 | ||
|
|
2bc35205a7 | ||
|
|
14c0f4e44b | ||
|
|
d6b707403e | ||
|
|
1dca3a8e3a | ||
|
|
75da5e9742 | ||
|
|
36a2297deb | ||
|
|
16014fe31c | ||
|
|
188bcf7636 | ||
|
|
4a5f575ef4 | ||
|
|
8bf7a1452d | ||
|
|
2fcf761f33 | ||
|
|
70bbcdf084 | ||
|
|
178fbdac16 | ||
|
|
5f9906eccc | ||
|
|
16c4590396 | ||
|
|
8d85171f16 | ||
|
|
eeb8ba4e62 | ||
|
|
19810f4a8b | ||
|
|
c48ce4c259 | ||
|
|
75ffb4b7e2 | ||
|
|
929d06a65f | ||
|
|
cbdc3fb81b | ||
|
|
04ab5de73c | ||
|
|
cae9eb4d8d | ||
|
|
f70dc8435a | ||
|
|
673c12fa3b | ||
|
|
008d8a740e | ||
|
|
b4039ec515 | ||
|
|
f8f0ca458d | ||
|
|
40907fa98a | ||
|
|
89a3ef7699 | ||
|
|
1dd6adffbe | ||
|
|
7078d5a5bd | ||
|
|
dbfe2d7e9e | ||
|
|
c24d29ef54 | ||
|
|
2d29ce5de1 | ||
|
|
54a8b5af01 | ||
|
|
bc9cd3e997 | ||
|
|
da0c551692 | ||
|
|
d200e3de8e | ||
|
|
49bc835aa9 | ||
|
|
536df7c240 | ||
|
|
9c80db1fdc | ||
|
|
53075ccc5d | ||
|
|
92fbadeb1b | ||
|
|
07800e82c9 | ||
|
|
6da60d4a5d | ||
|
|
3a1ce81d29 | ||
|
|
4bb00c6a0a | ||
|
|
38d8d5445e | ||
|
|
d84cbc3cec | ||
|
|
3edc43964d | ||
|
|
f41fc6b70c | ||
|
|
0432bde962 | ||
|
|
17586ea7c4 | ||
|
|
069cfb61b8 | ||
|
|
6bb9113e27 | ||
|
|
0e7c66e891 | ||
|
|
911b45ce3b | ||
|
|
cfc6e4bfac | ||
|
|
ffe81cbec1 | ||
|
|
f0b30e0027 | ||
|
|
40d1506527 | ||
|
|
2549b4b082 | ||
|
|
201dc6d024 | ||
|
|
2f367bab98 | ||
|
|
ad1244e2cf | ||
|
|
62c3e3d11f | ||
|
|
12292ba264 | ||
|
|
bfb052db1d | ||
|
|
a0c95cb07e | ||
|
|
7a25dcacff | ||
|
|
d0a3bca9ec | ||
|
|
0e6359bce9 | ||
|
|
767089384f | ||
|
|
3e9f809988 | ||
|
|
a871444743 | ||
|
|
fd5da75bdd | ||
|
|
fca7cc1747 | ||
|
|
992b146bc4 | ||
|
|
5d7b026ce2 | ||
|
|
8c2db395c4 | ||
|
|
c820a5732c | ||
|
|
447bd64013 | ||
|
|
45f710f3ff | ||
|
|
15f4ab6a3f | ||
|
|
65ee9d1b09 | ||
|
|
084d0ae96e | ||
|
|
5d27c772fd | ||
|
|
0ec438289d | ||
|
|
79e86adfb6 | ||
|
|
f5b6bef4b3 | ||
|
|
3c2e69af79 | ||
|
|
e9b0e9286e | ||
|
|
876352a030 | ||
|
|
109b462789 | ||
|
|
fc29068986 | ||
|
|
c05fef752e | ||
|
|
9d5cd52284 | ||
|
|
b481f554a0 | ||
|
|
39bc8163d0 | ||
|
|
d8167779cd | ||
|
|
7409f03cbf | ||
|
|
0a8e37509b | ||
|
|
cd6168ee64 | ||
|
|
d89d341541 | ||
|
|
e95c76aaed | ||
|
|
eea33df1f9 | ||
|
|
3e43a7f044 | ||
|
|
f30637ee11 | ||
|
|
86ab4fcb71 | ||
|
|
a8c0954db5 | ||
|
|
171f3e840b | ||
|
|
54c1548247 | ||
|
|
9cf82fae95 | ||
|
|
5168af9a9b | ||
|
|
61a1915cce | ||
|
|
03db48af75 | ||
|
|
8c12fa2e59 | ||
|
|
3f7350732c | ||
|
|
5b1c3e360a | ||
|
|
412e7a03e4 | ||
|
|
23e70fa857 | ||
|
|
ee26e3df60 | ||
|
|
ab6d07b585 | ||
|
|
891d18d356 | ||
|
|
2a61a500de | ||
|
|
64a9cf18e1 | ||
|
|
19b3aa3a12 | ||
|
|
7718b1598e | ||
|
|
65c9752762 | ||
|
|
f12aea5dfb | ||
|
|
7845cf1fac | ||
|
|
33a5468a60 | ||
|
|
34b63cecb1 | ||
|
|
7748a093cb | ||
|
|
d8f113bf98 | ||
|
|
26b9b3aa23 | ||
|
|
8f5cc8d762 | ||
|
|
6be87836dc | ||
|
|
417803d7ae | ||
|
|
15ff1927db | ||
|
|
d6ab908272 | ||
|
|
5d458c6c8a | ||
|
|
fbc5a6c24b | ||
|
|
15872bde61 | ||
|
|
b09d068bf6 | ||
|
|
f7f8f97e6a | ||
|
|
2927af43e1 | ||
|
|
7795e167ab | ||
|
|
b68ed9ebea | ||
|
|
ed59337239 | ||
|
|
120b15458c | ||
|
|
19887f2d35 | ||
|
|
a9e6dc3629 | ||
|
|
c922fc2cf3 | ||
|
|
3d32cbb0dc | ||
|
|
8da2c48650 | ||
|
|
5aa3fd5ac7 | ||
|
|
6620b6c515 | ||
|
|
e31f210b59 | ||
|
|
39e80a3f5c | ||
|
|
bc66d71dae | ||
|
|
427bff8504 | ||
|
|
cb19c0906e | ||
|
|
b1f48da5ee | ||
|
|
c02137a0d2 | ||
|
|
49efd6abb0 | ||
|
|
663664e48f | ||
|
|
c3d1456615 | ||
|
|
dcb8407ed6 | ||
|
|
230f09ca17 | ||
|
|
d562b4fdc5 | ||
|
|
46318f36ac | ||
|
|
97e7defaae | ||
|
|
56fff80e71 | ||
|
|
42808238c1 | ||
|
|
34df6743f6 | ||
|
|
2c0b3649fb | ||
|
|
0235fc7ab2 | ||
|
|
180a32ec59 | ||
|
|
f65a5d2fb5 | ||
|
|
6e5fd1a210 | ||
|
|
a66947b7d6 | ||
|
|
86ece8e98e | ||
|
|
5632c5db31 | ||
|
|
ca9da27e16 | ||
|
|
54521bd04b | ||
|
|
2e7fd319a1 | ||
|
|
21997e8894 | ||
|
|
ea29874099 | ||
|
|
ca11abc201 | ||
|
|
8ecdc66700 | ||
|
|
9484c46555 | ||
|
|
c2d7ebc3df | ||
|
|
7728b0f966 | ||
|
|
0a9e18fae1 | ||
|
|
924b9fcf05 | ||
|
|
884f8658ef | ||
|
|
99ce84827a | ||
|
|
7f809c013a | ||
|
|
40365f8297 | ||
|
|
1ac030b119 | ||
|
|
e2289ffac0 | ||
|
|
1629c9b71a | ||
|
|
42a57b37fb | ||
|
|
be1b5c5a54 | ||
|
|
53eb35b6cf | ||
|
|
2c0aa27e6c | ||
|
|
19b143688f | ||
|
|
3c08d27abb | ||
|
|
98dd9b6614 | ||
|
|
4ed273699a | ||
|
|
333cd4ec9b | ||
|
|
30f38c4952 | ||
|
|
a28fbcda23 | ||
|
|
ce99f98bb5 | ||
|
|
15f7cc3bde | ||
|
|
a8d64c8b89 | ||
|
|
f5aaecfdfc | ||
|
|
ebdf750cdd | ||
|
|
79bdfc1110 | ||
|
|
90875997ac | ||
|
|
f02af23973 | ||
|
|
c9d7a4af45 | ||
|
|
34323ecd8b | ||
|
|
d5a8431af4 | ||
|
|
2e2dd3113b | ||
|
|
11e5bb2d8a | ||
|
|
29d537ce7b | ||
|
|
688fb1999b | ||
|
|
bcfa3fb9f2 | ||
|
|
58afb87288 | ||
|
|
0a453194e8 | ||
|
|
3190c2f98d | ||
|
|
d4b3d00d88 | ||
|
|
15674d0259 | ||
|
|
52e8875eba | ||
|
|
40c314fe5c | ||
|
|
69bc465ace | ||
|
|
96acb499d2 | ||
|
|
64a0f5a659 | ||
|
|
3ce8c9fc8f | ||
|
|
8428cedc83 | ||
|
|
9bedc6300d | ||
|
|
cc4066189a | ||
|
|
733c861052 | ||
|
|
dd7f18f65f | ||
|
|
e90ec6a474 | ||
|
|
638cc50727 | ||
|
|
1444ebb7f1 | ||
|
|
028a0dcd3d | ||
|
|
655927ab15 | ||
|
|
051e23c782 | ||
|
|
887d0fca0e | ||
|
|
358b040157 | ||
|
|
184c553cab | ||
|
|
fc8495a744 | ||
|
|
428e9e7886 | ||
|
|
d475f04c78 | ||
|
|
39e1b5b962 | ||
|
|
c375ae3ec7 | ||
|
|
f561b857f2 | ||
|
|
8880e89bcd | ||
|
|
4c981953ac | ||
|
|
41723340de | ||
|
|
56560a859b | ||
|
|
65fab0ef5b | ||
|
|
6e531d0ccc | ||
|
|
c1ea97e15d | ||
|
|
da51302345 | ||
|
|
9d3b11d485 | ||
|
|
a8889718aa | ||
|
|
1704eb16cd | ||
|
|
e95a4f4f52 | ||
|
|
c738d60cef | ||
|
|
2ae38e9c43 | ||
|
|
0d1162f180 | ||
|
|
ea472b46c9 | ||
|
|
76f8e84edd | ||
|
|
3d957a33fa | ||
|
|
0eb36b5e9a | ||
|
|
67252c246c | ||
|
|
b05565f368 | ||
|
|
e2b652d95f | ||
|
|
56dee4acc6 | ||
|
|
d0d77e8c60 | ||
|
|
3143846ba4 | ||
|
|
25f1a3d759 | ||
|
|
5a0be4c6d8 | ||
|
|
2df1b124a7 | ||
|
|
f2729e8974 | ||
|
|
aa85b5ee1e | ||
|
|
fd24546787 | ||
|
|
9294c5aa0a | ||
|
|
712c9fc848 | ||
|
|
96a6214316 | ||
|
|
d2b405066d | ||
|
|
ea1ed13bc8 | ||
|
|
6ad0b004fa | ||
|
|
c3483458fe | ||
|
|
ba5aacbb95 | ||
|
|
a2165b38a0 | ||
|
|
e86b7d0c13 | ||
|
|
5bc5921af4 | ||
|
|
76db2bb39b | ||
|
|
a3760c0891 | ||
|
|
a747ef966b | ||
|
|
87f6df0655 | ||
|
|
25b7a5d531 | ||
|
|
c7436e667d | ||
|
|
183dde75de | ||
|
|
8086837f69 | ||
|
|
ff41c22fdc | ||
|
|
2f6236d1ea | ||
|
|
921f1ba4cf | ||
|
|
1bb04ea598 | ||
|
|
600fc8be2b | ||
|
|
c823160d94 | ||
|
|
d6b18ebfe7 | ||
|
|
b515651feb | ||
|
|
0dc0516f0c | ||
|
|
743d6c430b | ||
|
|
87aa3282f0 | ||
|
|
bbc48b0ef5 | ||
|
|
bd18405cf0 | ||
|
|
dd5a732eac | ||
|
|
862b01d4c0 | ||
|
|
9afbbf21fd | ||
|
|
b2cfb629e4 | ||
|
|
34423580e0 | ||
|
|
e6d83644e8 | ||
|
|
fe58770df8 | ||
|
|
00a0c81f8e | ||
|
|
945b7a0613 | ||
|
|
ed28795651 | ||
|
|
9d547a8443 | ||
|
|
c2dc3008b5 | ||
|
|
32f0567ca5 | ||
|
|
6f7466b6dd | ||
|
|
f2715a0593 | ||
|
|
90b1e271a8 | ||
|
|
d97a9fb4ff | ||
|
|
6d050b7282 | ||
|
|
74c89de3e9 | ||
|
|
af5c10ef0c | ||
|
|
4aa57e9e46 | ||
|
|
d0c2f3c403 | ||
|
|
31b657e8ea | ||
|
|
3367705ac2 | ||
|
|
6671344602 | ||
|
|
60837c9d0f | ||
|
|
d4ac56226d | ||
|
|
29589ce832 | ||
|
|
5e7a7c7e2f | ||
|
|
71b38e0cee | ||
|
|
8c00003466 | ||
|
|
33852d14af | ||
|
|
6bc4528776 | ||
|
|
b4b3be4f05 | ||
|
|
6817771df7 | ||
|
|
ed8ffa4bb4 | ||
|
|
3c92142f12 | ||
|
|
c680c84a31 | ||
|
|
da752e5d7d | ||
|
|
cefa23e4eb | ||
|
|
07ea935533 | ||
|
|
1d341ffbb0 | ||
|
|
319031154d | ||
|
|
2defbde5ab | ||
|
|
c12eae0c5e | ||
|
|
56d193c5c8 | ||
|
|
c3a2a7659e | ||
|
|
8b9419aaf7 | ||
|
|
2f59e1c1d9 | ||
|
|
998c58e89b | ||
|
|
35db567c9c | ||
|
|
93929e8d01 | ||
|
|
75867ff164 | ||
|
|
78be537eff | ||
|
|
d036ebeaf6 | ||
|
|
f236395176 | ||
|
|
5590c40b5b | ||
|
|
71bb07d10a | ||
|
|
e83f4e0173 | ||
|
|
0ee473afd1 | ||
|
|
f279f4731b | ||
|
|
d95df57297 | ||
|
|
71f8f5048b | ||
|
|
183c49f352 | ||
|
|
97268662fe | ||
|
|
b113772bb1 | ||
|
|
40c7ecfdea | ||
|
|
2e24cfadb7 | ||
|
|
bb01ea3809 | ||
|
|
25ec655162 | ||
|
|
4496983233 | ||
|
|
7b91af780a | ||
|
|
9155b59e1a | ||
|
|
b0069c5c05 | ||
|
|
7d45b7f269 | ||
|
|
43b47495e3 | ||
|
|
b15288fb87 | ||
|
|
e6e572bf5c | ||
|
|
37d1fa53e0 | ||
|
|
f48d95b415 | ||
|
|
5fb16e3442 | ||
|
|
d170a1c0e2 | ||
|
|
fbd6b28633 | ||
|
|
56d5131715 | ||
|
|
bee226b3ee | ||
|
|
6e19dbc923 | ||
|
|
cde4165097 | ||
|
|
c375a8d75b | ||
|
|
b7f2f40ae5 | ||
|
|
6e938f1f24 | ||
|
|
e1ce619bf7 | ||
|
|
3acb3a09fc | ||
|
|
7ca9604422 | ||
|
|
ebfd555ad1 | ||
|
|
f8f2cf7500 | ||
|
|
cc6cd394e5 | ||
|
|
7e051e0619 | ||
|
|
a71fb6057d | ||
|
|
474cffbc0f | ||
|
|
4fcc709f4e | ||
|
|
01c5ee6f7d | ||
|
|
8f54152fab | ||
|
|
54f6ff3bd5 | ||
|
|
d3092ced99 | ||
|
|
6c3af2670e | ||
|
|
6a4960889e | ||
|
|
064265166c | ||
|
|
9f6ce448bd | ||
|
|
c26344fc93 | ||
|
|
4235160dcf | ||
|
|
73120947cf | ||
|
|
5762bc4a5f | ||
|
|
41933efbf0 | ||
|
|
18a333ec6b | ||
|
|
8f5d2e546e | ||
|
|
4132dd87a4 | ||
|
|
d950b97115 | ||
|
|
cde2859a65 | ||
|
|
967d7c47dc | ||
|
|
4c04c848b5 | ||
|
|
27d2fb88ca | ||
|
|
de585e3109 | ||
|
|
e662de94f6 | ||
|
|
4fedf6efbd | ||
|
|
1beb6b686a | ||
|
|
50290c78b6 | ||
|
|
0e984b6e7e | ||
|
|
86f6f68274 | ||
|
|
93a1d4f156 | ||
|
|
80e8e20a89 | ||
|
|
0efafdd408 | ||
|
|
3718f5149a | ||
|
|
3b8ca5f343 | ||
|
|
b2f5bd7c60 | ||
|
|
5ba4391cf2 | ||
|
|
415a8bc249 | ||
|
|
a3cbc8a004 | ||
|
|
02dc3b6722 | ||
|
|
0f084751b4 | ||
|
|
d57b44153e | ||
|
|
fcf1ec132f | ||
|
|
4a31d0a9c9 | ||
|
|
656c39909a | ||
|
|
70bdf25284 | ||
|
|
15af423d86 | ||
|
|
8428dee47e | ||
|
|
cf8097138e | ||
|
|
c4c3e774cd | ||
|
|
a19363ab25 | ||
|
|
b6a39f61e5 | ||
|
|
13d44a2281 | ||
|
|
fad596a159 | ||
|
|
55d85b89c0 | ||
|
|
43bd843f37 | ||
|
|
85dd0556d7 | ||
|
|
e86e7c351d | ||
|
|
c2f446f40e | ||
|
|
d9d03d5af8 | ||
|
|
b64fd093ad | ||
|
|
bd4b7f8b25 | ||
|
|
93d3cf52ab | ||
|
|
33c7d6eb93 | ||
|
|
9525d5b5ae | ||
|
|
00cb9029f5 | ||
|
|
72abf86870 | ||
|
|
605fd0eda8 | ||
|
|
4db695f932 | ||
|
|
89936c66b0 | ||
|
|
37690f2651 | ||
|
|
6ae72f3980 | ||
|
|
06071dc76d | ||
|
|
c7a7982e23 |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -22,5 +22,6 @@
|
||||
"[markdown]": {
|
||||
"editor.trimAutoWhitespace": false,
|
||||
"files.trimTrailingWhitespace": false
|
||||
}
|
||||
},
|
||||
"python.formatting.provider": "yapf"
|
||||
}
|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@@ -6,7 +6,7 @@ Vagrant.configure(2) do |config|
|
||||
config.vm.define "qmk_firmware"
|
||||
|
||||
# VMware/Virtualbox ( and also Hyperv/Parallels) 64 bit
|
||||
config.vm.box = "generic/debian9"
|
||||
config.vm.box = "generic/debian10"
|
||||
|
||||
config.vm.synced_folder '.', '/vagrant'
|
||||
|
||||
|
||||
1
bin/qmk
1
bin/qmk
@@ -35,6 +35,7 @@ def main():
|
||||
print('Warning: The bin/qmk script is being deprecated. Please install the QMK CLI: python3 -m pip install qmk', file=sys.stderr)
|
||||
|
||||
# Import the subcommands
|
||||
import milc.subcommand.config # noqa
|
||||
import qmk.cli # noqa
|
||||
|
||||
# Execute
|
||||
|
||||
@@ -90,12 +90,16 @@ ifeq ($(strip $(BOOTLOADER)), USBasp)
|
||||
endif
|
||||
ifeq ($(strip $(BOOTLOADER)), lufa-ms)
|
||||
OPT_DEFS += -DBOOTLOADER_MS
|
||||
BOOTLOADER_SIZE = 6144
|
||||
BOOTLOADER_SIZE ?= 8192
|
||||
FIRMWARE_FORMAT = bin
|
||||
$(info LUFA MASS STORAGE Bootloader selected)
|
||||
$(info DO NOT USE THIS BOOTLOADER IN NEW PROJECTS!)
|
||||
$(info It is extremely prone to bricking, and is only included to support existing boards.)
|
||||
$(info )
|
||||
cpfirmware: lufa_warning
|
||||
.INTERMEDIATE: lufa_warning
|
||||
lufa_warning: $(FIRMWARE_FORMAT)
|
||||
$(info @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@)
|
||||
$(info LUFA MASS STORAGE Bootloader selected)
|
||||
$(info DO NOT USE THIS BOOTLOADER IN NEW PROJECTS!)
|
||||
$(info It is extremely prone to bricking, and is only included to support existing boards.)
|
||||
$(info @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@)
|
||||
endif
|
||||
ifdef BOOTLOADER_SIZE
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=$(strip $(BOOTLOADER_SIZE))
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# Look for a json keymap file
|
||||
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.json)","")
|
||||
KEYMAP_C := $(KEYBOARD_OUTPUT)/src/keymap.c
|
||||
KEYMAP_C := $(KEYMAP_OUTPUT)/keymap.c
|
||||
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_5)/keymap.json
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.json)","")
|
||||
KEYMAP_C := $(KEYBOARD_OUTPUT)/src/keymap.c
|
||||
KEYMAP_C := $(KEYMAP_OUTPUT)/keymap.c
|
||||
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_4)/keymap.json
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.json)","")
|
||||
KEYMAP_C := $(KEYBOARD_OUTPUT)/src/keymap.c
|
||||
KEYMAP_C := $(KEYMAP_OUTPUT)/keymap.c
|
||||
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_3)/keymap.json
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.json)","")
|
||||
KEYMAP_C := $(KEYBOARD_OUTPUT)/src/keymap.c
|
||||
KEYMAP_C := $(KEYMAP_OUTPUT)/keymap.c
|
||||
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_2)/keymap.json
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
|
||||
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.json)","")
|
||||
KEYMAP_C := $(KEYBOARD_OUTPUT)/src/keymap.c
|
||||
KEYMAP_C := $(KEYMAP_OUTPUT)/keymap.c
|
||||
KEYMAP_JSON := $(MAIN_KEYMAP_PATH_1)/keymap.json
|
||||
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
|
||||
endif
|
||||
@@ -27,5 +27,5 @@ ifneq ("$(wildcard $(KEYMAP_PATH))", "")
|
||||
endif
|
||||
|
||||
# Generate the keymap.c
|
||||
$(KEYBOARD_OUTPUT)/src/keymap.c: $(KEYMAP_JSON)
|
||||
$(KEYMAP_C): $(KEYMAP_JSON)
|
||||
$(QMK_BIN) json2c --quiet --output $(KEYMAP_C) $(KEYMAP_JSON)
|
||||
|
||||
@@ -103,6 +103,15 @@ MAIN_KEYMAP_PATH_5 := $(KEYBOARD_PATH_5)/keymaps/$(KEYMAP)
|
||||
INFO_RULES_MK = $(shell $(QMK_BIN) generate-rules-mk --quiet --escape --keyboard $(KEYBOARD) --output $(KEYBOARD_OUTPUT)/src/rules.mk)
|
||||
include $(INFO_RULES_MK)
|
||||
|
||||
ifneq ($(FORCE_LAYOUT),)
|
||||
TARGET := $(TARGET)_$(FORCE_LAYOUT)
|
||||
endif
|
||||
|
||||
# Object files and generated keymap directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
|
||||
|
||||
# Check for keymap.json first, so we can regenerate keymap.c
|
||||
include build_json.mk
|
||||
|
||||
@@ -145,10 +154,6 @@ ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes)
|
||||
include platforms/chibios/QMK_PROTON_C/convert_to_proton_c.mk
|
||||
endif
|
||||
|
||||
ifneq ($(FORCE_LAYOUT),)
|
||||
TARGET := $(TARGET)_$(FORCE_LAYOUT)
|
||||
endif
|
||||
|
||||
include quantum/mcu_selection.mk
|
||||
|
||||
# Find all the C source files to be compiled in subfolders.
|
||||
@@ -327,11 +332,6 @@ endif
|
||||
# Disable features that a keyboard doesn't support
|
||||
-include disable_features.mk
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
|
||||
|
||||
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
|
||||
CONFIG_H += $(KEYMAP_PATH)/config.h
|
||||
endif
|
||||
|
||||
@@ -49,6 +49,7 @@ endif
|
||||
|
||||
include common_features.mk
|
||||
include $(TMK_PATH)/common.mk
|
||||
include $(QUANTUM_PATH)/debounce/tests/rules.mk
|
||||
include $(QUANTUM_PATH)/sequencer/tests/rules.mk
|
||||
include $(QUANTUM_PATH)/serial_link/tests/rules.mk
|
||||
ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||
|
||||
@@ -244,7 +244,7 @@ endif
|
||||
endif
|
||||
|
||||
RGB_MATRIX_ENABLE ?= no
|
||||
VALID_RGB_MATRIX_TYPES := IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom
|
||||
VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
|
||||
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
|
||||
@@ -261,6 +261,13 @@ endif
|
||||
CIE1931_CURVE := yes
|
||||
RGB_KEYCODES_ENABLE := yes
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), AW20216)
|
||||
OPT_DEFS += -DAW20216 -DSTM32_SPI -DHAL_USE_SPI=TRUE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/awinic
|
||||
SRC += aw20216.c
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3731)
|
||||
OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/issi
|
||||
@@ -529,7 +536,11 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
||||
|
||||
# Determine which (if any) transport files are required
|
||||
ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
|
||||
QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/transport.c
|
||||
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/transport.c \
|
||||
$(QUANTUM_DIR)/split_common/transactions.c
|
||||
|
||||
OPT_DEFS += -DSPLIT_COMMON_TRANSACTIONS
|
||||
|
||||
# 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.
|
||||
ifeq ($(PLATFORM),AVR)
|
||||
@@ -550,6 +561,11 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
|
||||
COMMON_VPATH += $(QUANTUM_PATH)/split_common
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(CRC_ENABLE)), yes)
|
||||
OPT_DEFS += -DCRC_ENABLE
|
||||
QUANTUM_LIB_SRC += crc.c
|
||||
endif
|
||||
|
||||
HAPTIC_ENABLE ?= no
|
||||
ifneq ($(strip $(HAPTIC_ENABLE)),no)
|
||||
COMMON_VPATH += $(DRIVER_PATH)/haptic
|
||||
@@ -580,6 +596,14 @@ ifeq ($(strip $(OLED_DRIVER_ENABLE)), yes)
|
||||
SRC += oled_driver.c
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(ST7565_ENABLE)), yes)
|
||||
OPT_DEFS += -DST7565_ENABLE
|
||||
COMMON_VPATH += $(DRIVER_PATH)/oled # For glcdfont.h
|
||||
COMMON_VPATH += $(DRIVER_PATH)/lcd
|
||||
QUANTUM_LIB_SRC += spi_master.c
|
||||
SRC += st7565.c
|
||||
endif
|
||||
|
||||
include $(DRIVER_PATH)/qwiic/qwiic.mk
|
||||
|
||||
ifeq ($(strip $(UCIS_ENABLE)), yes)
|
||||
|
||||
@@ -59,8 +59,11 @@
|
||||
'cmm_studio/saka68': {
|
||||
target: 'cmm_studio/saka68/solder'
|
||||
},
|
||||
'crkbd/rev1': {
|
||||
target: 'crkbd/rev1/legacy'
|
||||
'crkbd/rev1/legacy': {
|
||||
target: 'crkbd/rev1'
|
||||
},
|
||||
'crkbd/rev1/common': {
|
||||
target: 'crkbd/rev1'
|
||||
},
|
||||
'doro67/multi': {
|
||||
layouts: {
|
||||
|
||||
@@ -1,34 +1,22 @@
|
||||
{
|
||||
"$id": "qmk.api.keyboard.v1",
|
||||
"allOf": [
|
||||
{ "$ref": "qmk.keyboard.v1" },
|
||||
{"$ref": "qmk.keyboard.v1"},
|
||||
{
|
||||
"$id": "qmk.api.keyboard.v1",
|
||||
"keymaps": {
|
||||
"type": "string"
|
||||
},
|
||||
"parse_errors": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"parse_warnings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"processor_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyboard_folder": {
|
||||
"type": "string"
|
||||
},
|
||||
"platform": {
|
||||
"type": "string"
|
||||
"properties": {
|
||||
"keymaps": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {"type": "string"}
|
||||
}
|
||||
|
||||
},
|
||||
"parse_errors": {"$ref": "qmk.definitions.v1#/string_array"},
|
||||
"parse_warnings": {"$ref": "qmk.definitions.v1#/string_array"},
|
||||
"processor_type": {"type": "string"},
|
||||
"protocol": {"type": "string"},
|
||||
"keyboard_folder": {"type": "string"},
|
||||
"platform": {"type": "string"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
107
data/schemas/definitions.jsonschema
Normal file
107
data/schemas/definitions.jsonschema
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "qmk.definitions.v1",
|
||||
"title": "Common definitions used across QMK's jsonschemas.",
|
||||
"type": "object",
|
||||
"boolean_array": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
},
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^[0-9a-z_]*$"
|
||||
},
|
||||
"hex_number_2d": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9A-F]{2}$"
|
||||
},
|
||||
"hex_number_4d": {
|
||||
"type": "string",
|
||||
"pattern": "^0x[0-9A-F]{4}$"
|
||||
},
|
||||
"text_identifier": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 250
|
||||
},
|
||||
"layout_macro": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": ["LAYOUT", "LAYOUT_planck_1x2uC"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^LAYOUT_[0-9a-z_]*$"
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_unit": {
|
||||
"type": "number",
|
||||
"min": 0.25
|
||||
},
|
||||
"mcu_pin_array": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/mcu_pin"}
|
||||
},
|
||||
"mcu_pin": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^LINE_PIN\\d{1,2}$"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"signed_decimal": {
|
||||
"type": "number"
|
||||
},
|
||||
"signed_int": {
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
}
|
||||
"signed_int_8": {
|
||||
"type": "number",
|
||||
"min": -127,
|
||||
"max": 127,
|
||||
"multipleOf": 1
|
||||
}
|
||||
"string_array": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"string_object": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"unsigned_decimal": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"unsigned_int": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
}
|
||||
"unsigned_int_8": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"max": 255,
|
||||
"multipleOf": 1
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "qmk.keyboard.v1",
|
||||
"title": "Keyboard Information",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyboard_name": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 250
|
||||
},
|
||||
"maintainer": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 250
|
||||
},
|
||||
"manufacturer": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"maxLength": 250
|
||||
},
|
||||
"keyboard_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"maintainer": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"manufacturer": {"$ref": "qmk.definitions.v1#/text_identifier"},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
@@ -40,62 +28,25 @@
|
||||
"type": "string",
|
||||
"enum": ["COL2ROW", "ROW2COL"]
|
||||
},
|
||||
"debounce": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"height": {
|
||||
"type": "number",
|
||||
"min": 0.25
|
||||
},
|
||||
"width": {
|
||||
"type": "number",
|
||||
"min": 0.25
|
||||
},
|
||||
"debounce": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"height": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"width": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"community_layouts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"pattern": "^[0-9a-z_]*$"
|
||||
}
|
||||
},
|
||||
"features": {
|
||||
"type": "object",
|
||||
"additionalProperties": {"type": "boolean"}
|
||||
"items": {"$ref": "qmk.definitions.v1#/filename"}
|
||||
},
|
||||
"features": {"$ref": "qmk.definitions.v1#/boolean_array"},
|
||||
"indicators": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"caps_lock": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"num_lock": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"scroll_lock": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
}
|
||||
"caps_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"num_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"}
|
||||
}
|
||||
},
|
||||
"layout_aliases": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": ["LAYOUT", "LAYOUT_planck_1x2uC"]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^LAYOUT_[0-9a-z_]*$"
|
||||
}
|
||||
]
|
||||
}
|
||||
"additionalProperties": {"$ref": "qmk.definitions.v1#/layout_macro"}
|
||||
},
|
||||
"layouts": {
|
||||
"type": "object",
|
||||
@@ -109,11 +60,7 @@
|
||||
"c_macro": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key_count": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"key_count": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"layout": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -131,34 +78,14 @@
|
||||
"multipleOf": 1
|
||||
}
|
||||
},
|
||||
"h": {
|
||||
"type": "number",
|
||||
"min": 0.25
|
||||
},
|
||||
"r": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"rx": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"ry": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"w": {
|
||||
"type": "number",
|
||||
"min": 0.25
|
||||
},
|
||||
"x": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
}
|
||||
"key_count": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"r": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
||||
"rx": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
||||
"ry": {"$ref": "qmk.definitions.v1#/unsigned_decimal"},
|
||||
"h": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"w": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"x": {"$ref": "qmk.definitions.v1#/key_unit"},
|
||||
"y": {"$ref": "qmk.definitions.v1#/key_unit"}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,61 +98,10 @@
|
||||
"properties": {
|
||||
"direct": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"items": {$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
||||
},
|
||||
"cols": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"multipleOf": 1
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"cols": {"$ref": "qmk.definitions.v1#/mcu_pin_array"},
|
||||
"rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
|
||||
}
|
||||
},
|
||||
"rgblight": {
|
||||
@@ -238,47 +114,19 @@
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"brightness_steps": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"hue_steps": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"led_count": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"max_brightness": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"max": 255,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"pin": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"saturation_steps": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
},
|
||||
"brightness_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"hue_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"led_count": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"max_brightness": {"$ref": "qmk.definitions.v1#/unsigned_int_8"},
|
||||
"pin": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"saturation_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"},
|
||||
"sleep": {"type": "boolean"},
|
||||
"split": {"type": "boolean"},
|
||||
"split_count": {
|
||||
"type": "array",
|
||||
"minLength": 2,
|
||||
"maxLength": 2,
|
||||
"items": {
|
||||
"type": "number",
|
||||
"min": 0,
|
||||
"multipleOf": 1
|
||||
}
|
||||
"items": {"$ref": "qmk.definitions.v1#/unsigned_int"}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -286,40 +134,19 @@
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"device_ver": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9A-F]x[0-9A-F][0-9A-F][0-9A-F][0-9A-F]"
|
||||
},
|
||||
"pid": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9A-F]x[0-9A-F][0-9A-F][0-9A-F][0-9A-F]"
|
||||
},
|
||||
"vid": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9A-F]x[0-9A-F][0-9A-F][0-9A-F][0-9A-F]"
|
||||
}
|
||||
"device_ver": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||
"pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"},
|
||||
"vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"}
|
||||
}
|
||||
},
|
||||
"qmk_lufa_bootloader": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"esc_output": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"esc_input": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"led": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
},
|
||||
"speaker": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-K]\\d{1,2}$"
|
||||
}
|
||||
"esc_output": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"esc_input": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"led": {"$ref": "qmk.definitions.v1#/mcu_pin"},
|
||||
"speaker": {"$ref": "qmk.definitions.v1#/mcu_pin"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
* Hardware Features
|
||||
* Displays
|
||||
* [HD44780 LCD Controller](feature_hd44780.md)
|
||||
* [ST7565 LCD Driver](feature_st7565.md)
|
||||
* [OLED Driver](feature_oled_driver.md)
|
||||
* Lighting
|
||||
* [Backlight](feature_backlight.md)
|
||||
@@ -108,6 +109,7 @@
|
||||
* [Haptic Feedback](feature_haptic_feedback.md)
|
||||
* [Joystick](feature_joystick.md)
|
||||
* [LED Indicators](feature_led_indicators.md)
|
||||
* [MIDI](feature_midi.md)
|
||||
* [Proton C Conversion](proton_c_conversion.md)
|
||||
* [PS/2 Mouse](feature_ps2_mouse.md)
|
||||
* [Split Keyboard](feature_split_keyboard.md)
|
||||
|
||||
@@ -56,7 +56,7 @@ This happens immediately after the previous `develop` branch is merged.
|
||||
* [ ] `git commit -m 'Branch point for <DATE> Breaking Change'`
|
||||
* [ ] `git tag breakpoint_<YYYY>_<MM>_<DD>`
|
||||
* [ ] `git tag <next_version>` # Prevent the breakpoint tag from confusing version incrementing
|
||||
* [ ] `git push origin develop`
|
||||
* [ ] `git push upstream develop`
|
||||
* [ ] `git push --tags`
|
||||
|
||||
## 4 Weeks Before Merge
|
||||
@@ -86,13 +86,21 @@ This happens immediately after the previous `develop` branch is merged.
|
||||
* `qmk_firmware` git commands
|
||||
* [ ] `git checkout develop`
|
||||
* [ ] `git pull --ff-only`
|
||||
* [ ] `git rebase origin/master`
|
||||
* [ ] Edit `readme.md`
|
||||
* [ ] Remove the notes about `develop`
|
||||
* [ ] Roll up the ChangeLog into one file.
|
||||
* [ ] `git commit -m 'Merge point for <DATE> Breaking Change'`
|
||||
* [ ] `git push origin develop`
|
||||
* [ ] `git push upstream develop`
|
||||
* GitHub Actions
|
||||
* [ ] Create a PR for `develop`
|
||||
* [ ] Make sure travis comes back clean
|
||||
* [ ] Merge `develop` PR
|
||||
* [ ] **Turn off 'Automatically delete head branches' for the repository** -- confirm with @qmk/directors that it is done before continuing
|
||||
* `qmk_firmware` git commands
|
||||
* [ ] `git checkout master`
|
||||
* [ ] `git pull --ff-only`
|
||||
* [ ] `git merge --no-ff develop`
|
||||
* [ ] `git push upstream master`
|
||||
|
||||
## Post-merge operations
|
||||
|
||||
* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md)
|
||||
|
||||
56
docs/chibios_upgrade_instructions.md
Normal file
56
docs/chibios_upgrade_instructions.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# ChibiOS Upgrade Procedure
|
||||
|
||||
ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a branch tied to the ChibiOS version in use and should not be mixed with different versions.
|
||||
|
||||
## Getting ChibiOS
|
||||
|
||||
* `svn` Initialisation:
|
||||
* Only needed to be done once
|
||||
* You might need to separately install `git-svn` package in your OS's package manager
|
||||
* `git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/`
|
||||
* `git remote add qmk git@github.com:qmk/ChibiOS.git`
|
||||
* Updating:
|
||||
* `git svn fetch`
|
||||
* First time around this will take several hours
|
||||
* Subsequent updates will be incremental only
|
||||
* Tagging example (work out which version first!):
|
||||
* `git tag -a ver20.3.3 -m ver20.3.3 svn/tags/ver20.3.3`
|
||||
* `git push qmk ver20.3.3`
|
||||
* `git tag -a breaking_YYYY_qN -m breaking_YYYY_qN svn/tags/ver20.3.3`
|
||||
* `git push qmk breaking_YYYY_qN`
|
||||
|
||||
## Getting ChibiOS-Contrib
|
||||
|
||||
* `git` Initialisation:
|
||||
* `git clone git@github.com:qmk/ChibiOS-Contrib`
|
||||
* `git remote add upstream https://github.com/ChibiOS/ChibiOS-Contrib`
|
||||
* `git checkout -b chibios-20.3.x upstream/chibios-20.3.x`
|
||||
* Updating:
|
||||
* `git fetch --all --tags --prune`
|
||||
* `git checkout chibios-20.3.x`
|
||||
* `git pull --ff-only`
|
||||
* `git push origin chibios-20.3.x`
|
||||
* `git tag -a breaking_YYYY_qN -m breaking_YYYY_qN chibios-20.3.x`
|
||||
* `git push origin breaking_YYYY_qN`
|
||||
|
||||
## Updating submodules
|
||||
|
||||
* Update the submodules
|
||||
* `cd $QMK_FIRMWARE`
|
||||
* `git checkout develop`
|
||||
* `git pull --ff-only`
|
||||
* `git checkout -b chibios-version-bump`
|
||||
* `cd lib/chibios`
|
||||
* `git fetch --all --tags --prune`
|
||||
* `git checkout breaking_YYYY_qN`
|
||||
* `cd ../chibios-contrib`
|
||||
* `git fetch --all --tags --prune`
|
||||
* `git checkout breaking_YYYY_qN`
|
||||
* Build everything
|
||||
* `cd $QMK_FIRMWARE`
|
||||
* `qmk multibuild -j4`
|
||||
* Make sure there are no errors
|
||||
* Push to the repo
|
||||
* `git commit -am 'Update ChibiOS to XXXXXXXXX'`
|
||||
* `git push --set-upstream origin chibios-version-bump`
|
||||
* Make a PR to qmk_firmware with the new branch
|
||||
@@ -51,8 +51,10 @@ This is a C header file that is one of the first things included, and will persi
|
||||
* the number of columns in your keyboard's matrix
|
||||
* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }`
|
||||
* pins of the rows, from top to bottom
|
||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
||||
* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }`
|
||||
* pins of the columns, from left to right
|
||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
||||
* `#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 }`
|
||||
@@ -272,7 +274,7 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||
### Other Options
|
||||
|
||||
* `#define USE_I2C`
|
||||
* For using I2C instead of Serial (defaults to serial)
|
||||
* For using I2C instead of Serial (default is serial; serial transport is supported on ARM -- I2C is AVR-only)
|
||||
|
||||
* `#define SOFT_SERIAL_PIN D0`
|
||||
* When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`.
|
||||
@@ -280,6 +282,7 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||
* `#define MATRIX_ROW_PINS_RIGHT { <row pins> }`
|
||||
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
|
||||
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
|
||||
* may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information.
|
||||
|
||||
* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }`
|
||||
* If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`.
|
||||
@@ -300,7 +303,7 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||
* `#define SPLIT_USB_DETECT`
|
||||
* Detect (with timeout) USB connection when delegating master/slave
|
||||
* Default behavior for ARM
|
||||
* Required for AVR Teensy
|
||||
* Required for AVR Teensy (without hardware mods)
|
||||
|
||||
* `#define SPLIT_USB_TIMEOUT 2000`
|
||||
* Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
|
||||
@@ -308,6 +311,28 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||
* `#define SPLIT_USB_TIMEOUT_POLL 10`
|
||||
* Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT`
|
||||
|
||||
* `#define FORCED_SYNC_THROTTLE_MS 100`
|
||||
* Deadline for synchronizing data from master to slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_TRANSPORT_MIRROR`
|
||||
* Mirrors the master-side matrix on the slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_LAYER_STATE_ENABLE`
|
||||
* Ensures the current layer state is available on the slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_LED_STATE_ENABLE`
|
||||
* Ensures the current host indicator state (caps/num/scroll) is available on the slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_MODS_ENABLE`
|
||||
* Ensures the current modifier state (normal, weak, and oneshot) is available on the slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_WPM_ENABLE`
|
||||
* Ensures the current WPM is available on the slave when using the QMK-provided split transport.
|
||||
|
||||
* `#define SPLIT_TRANSACTION_IDS_KB .....`
|
||||
* `#define SPLIT_TRANSACTION_IDS_USER .....`
|
||||
* Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information.
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -144,6 +144,14 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw
|
||||
* Keyboard/Revision: `void matrix_init_kb(void)`
|
||||
* Keymap: `void matrix_init_user(void)`
|
||||
|
||||
### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides
|
||||
|
||||
* GPIO pin initialisation: `void matrix_init_pins(void)`
|
||||
* This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
||||
* `COL2ROW`-based row reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)`
|
||||
* `ROW2COL`-based column reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
|
||||
* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)`
|
||||
* These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override.
|
||||
|
||||
## Keyboard Post Initialization code
|
||||
|
||||
|
||||
@@ -131,12 +131,14 @@ You can override the default songs by doing something like this in your `config.
|
||||
|
||||
```c
|
||||
#ifdef AUDIO_ENABLE
|
||||
#define STARTUP_SONG SONG(STARTUP_SOUND)
|
||||
# define STARTUP_SONG SONG(STARTUP_SOUND)
|
||||
#endif
|
||||
```
|
||||
|
||||
A full list of sounds can be found in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) - feel free to add your own to this list! All available notes can be seen in [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h).
|
||||
|
||||
Additionally, if you with to maintain your own list of songs (such as ones that may be copyrighted) and not have them added to the repo, you can create a `user_song_list.h` file and place it in your keymap (or userspace) folder. This file will be automatically included, it just needs to exist.
|
||||
|
||||
To play a custom sound at a particular time, you can define a song like this (near the top of the file):
|
||||
|
||||
```c
|
||||
@@ -301,8 +303,7 @@ You can configure the default, min and max frequencies, the stepping and built i
|
||||
|
||||
## MIDI Functionality
|
||||
|
||||
This is still a WIP, but check out `quantum/process_keycode/process_midi.c` to see what's happening. Enable from the Makefile.
|
||||
|
||||
See [MIDI](feature_midi.md)
|
||||
|
||||
## Audio Keycodes
|
||||
|
||||
@@ -319,114 +320,3 @@ This is still a WIP, but check out `quantum/process_keycode/process_midi.c` to s
|
||||
|`MU_OFF` | |Turns off Music Mode |
|
||||
|`MU_TOG` | |Toggles Music Mode |
|
||||
|`MU_MOD` | |Cycles through the music modes |
|
||||
|
||||
<!-- FIXME: this formatting needs work
|
||||
|
||||
## Audio
|
||||
|
||||
```c
|
||||
#ifdef AUDIO_ENABLE
|
||||
AU_ON,
|
||||
AU_OFF,
|
||||
AU_TOG,
|
||||
|
||||
// Music mode on/off/toggle
|
||||
MU_ON,
|
||||
MU_OFF,
|
||||
MU_TOG,
|
||||
|
||||
// Music voice iterate
|
||||
MUV_IN,
|
||||
MUV_DE,
|
||||
#endif
|
||||
```
|
||||
|
||||
### Midi
|
||||
|
||||
#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
|
||||
MI_ON, // send midi notes when music mode is enabled
|
||||
MI_OFF, // don't send midi notes when music mode is enabled
|
||||
#endif
|
||||
|
||||
MIDI_TONE_MIN,
|
||||
MIDI_TONE_MAX
|
||||
|
||||
MI_C = MIDI_TONE_MIN,
|
||||
MI_Cs,
|
||||
MI_Db = MI_Cs,
|
||||
MI_D,
|
||||
MI_Ds,
|
||||
MI_Eb = MI_Ds,
|
||||
MI_E,
|
||||
MI_F,
|
||||
MI_Fs,
|
||||
MI_Gb = MI_Fs,
|
||||
MI_G,
|
||||
MI_Gs,
|
||||
MI_Ab = MI_Gs,
|
||||
MI_A,
|
||||
MI_As,
|
||||
MI_Bb = MI_As,
|
||||
MI_B,
|
||||
|
||||
MIDI_TONE_KEYCODE_OCTAVES > 1
|
||||
|
||||
where x = 1-5:
|
||||
MI_C_x,
|
||||
MI_Cs_x,
|
||||
MI_Db_x = MI_Cs_x,
|
||||
MI_D_x,
|
||||
MI_Ds_x,
|
||||
MI_Eb_x = MI_Ds_x,
|
||||
MI_E_x,
|
||||
MI_F_x,
|
||||
MI_Fs_x,
|
||||
MI_Gb_x = MI_Fs_x,
|
||||
MI_G_x,
|
||||
MI_Gs_x,
|
||||
MI_Ab_x = MI_Gs_x,
|
||||
MI_A_x,
|
||||
MI_As_x,
|
||||
MI_Bb_x = MI_As_x,
|
||||
MI_B_x,
|
||||
|
||||
MI_OCT_Nx 1-2
|
||||
MI_OCT_x 0-7
|
||||
MIDI_OCTAVE_MIN = MI_OCT_N2,
|
||||
MIDI_OCTAVE_MAX = MI_OCT_7,
|
||||
MI_OCTD, // octave down
|
||||
MI_OCTU, // octave up
|
||||
|
||||
MI_TRNS_Nx 1-6
|
||||
MI_TRNS_x 0-6
|
||||
MIDI_TRANSPOSE_MIN = MI_TRNS_N6,
|
||||
MIDI_TRANSPOSE_MAX = MI_TRNS_6,
|
||||
MI_TRNSD, // transpose down
|
||||
MI_TRNSU, // transpose up
|
||||
|
||||
MI_VEL_x 1-10
|
||||
MIDI_VELOCITY_MIN = MI_VEL_1,
|
||||
MIDI_VELOCITY_MAX = MI_VEL_9,
|
||||
MI_VELD, // velocity down
|
||||
MI_VELU, // velocity up
|
||||
|
||||
MI_CHx 1-16
|
||||
MIDI_CHANNEL_MIN = MI_CH1
|
||||
MIDI_CHANNEL_MAX = MI_CH16,
|
||||
MI_CHD, // previous channel
|
||||
MI_CHU, // next channel
|
||||
|
||||
MI_ALLOFF, // all notes off
|
||||
|
||||
MI_SUS, // sustain
|
||||
MI_PORT, // portamento
|
||||
MI_SOST, // sostenuto
|
||||
MI_SOFT, // soft pedal
|
||||
MI_LEG, // legato
|
||||
|
||||
MI_MOD, // modulation
|
||||
MI_MODSD, // decrease modulation speed
|
||||
MI_MODSU, // increase modulation speed
|
||||
#endif // MIDI_ADVANCED
|
||||
|
||||
-->
|
||||
|
||||
@@ -121,16 +121,16 @@ DEBOUNCE_TYPE = <name of algorithm>
|
||||
Where name of algorithm is one of:
|
||||
* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed.
|
||||
* This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant.
|
||||
* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
|
||||
* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
|
||||
For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
|
||||
appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
|
||||
* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
|
||||
* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
|
||||
* ```asym_eager_defer_pk``` - debouncing per key. On a key-down state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key-up status change is pushed.
|
||||
|
||||
### A couple algorithms that could be implemented in the future:
|
||||
* ```sym_defer_pr```
|
||||
* ```sym_eager_g```
|
||||
* ```asym_eager_defer_pk```
|
||||
|
||||
### Use your own debouncing code
|
||||
You have the option to implement you own debouncing algorithm. To do this:
|
||||
|
||||
@@ -162,4 +162,28 @@ This will set what sequence HPT_RST will set as the active mode. If not defined,
|
||||
|
||||
### DRV2605L Continuous Haptic Mode
|
||||
|
||||
This mode sets continuous haptic feedback with the option to increase or decrease strength.
|
||||
This mode sets continuous haptic feedback with the option to increase or decrease strength.
|
||||
|
||||
## Haptic Key Exclusion
|
||||
The Haptic Exclusion is implemented as `__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record)` in haptic.c. This allows a re-definition at the required level with the specific requirement / exclusion.
|
||||
|
||||
### NO_HAPTIC_MOD
|
||||
With the entry of `#define NO_HAPTIC_MOD` in config.h, modifiers from Left Control to Right GUI will not trigger a feedback. This also includes modifiers in a Mod Tap configuration.
|
||||
|
||||
### NO_HAPTIC_FN
|
||||
With the entry of `#define NO_HAPTIC_FN` in config.h, layer keys will not rigger a feedback.
|
||||
|
||||
### NO_HAPTIC_ALPHA
|
||||
With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback.
|
||||
|
||||
### NO_HAPTIC_PUNCTUATION
|
||||
With the entry of `#define NO_HAPTIC_PUNCTUATION` in config.h, none of the following keys will trigger a feedback: Enter, ESC, Backspace, Space, Minus, Equal, Left Bracket, Right Bracket, Backslash, Non-US Hash, Semicolon, Quote, Grave, Comma, Slash, Dot, Non-US Backslash.
|
||||
|
||||
### NO_HAPTIC_LOCKKEYS
|
||||
With the entry of `#define NO_HAPTIC_LOCKKEYS` in config.h, none of the following keys will trigger a feedback: Caps Lock, Scroll Lock, Num Lock.
|
||||
|
||||
### NO_HAPTIC_NAV
|
||||
With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home.
|
||||
|
||||
### NO_HAPTIC_NUMERIC
|
||||
With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback.
|
||||
@@ -67,6 +67,8 @@ Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet]
|
||||
|
||||
---
|
||||
|
||||
## Common Configuration :id=common-configuration
|
||||
|
||||
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
|
||||
|
||||
260
docs/feature_midi.md
Normal file
260
docs/feature_midi.md
Normal file
@@ -0,0 +1,260 @@
|
||||
# MIDI
|
||||
|
||||
## Usage
|
||||
|
||||
First, enable MIDI by adding the following to your `rules.mk`:
|
||||
|
||||
```makefile
|
||||
MIDI_ENABLE = yes
|
||||
```
|
||||
|
||||
There are two MIDI systems in QMK: basic and advanced. With basic MIDI you will only be able to send Note On and Note Off messages using the note keycodes, meaning that keycodes like `MI_OCTU` and `MI_OCTD` will not work. Advanced MIDI allows you to do things like octave shifts, channel changes, velocity changes, modulation, and more.
|
||||
|
||||
### Basic MIDI
|
||||
|
||||
To enable basic MIDI, add the following to your `config.h`:
|
||||
|
||||
```c
|
||||
#define MIDI_BASIC
|
||||
```
|
||||
|
||||
### Advanced MIDI
|
||||
|
||||
To enable advanced MIDI, add the following to your `config.h`:
|
||||
|
||||
```c
|
||||
#define MIDI_ADVANCED
|
||||
```
|
||||
|
||||
#### Sending Control Change (CC) Messages
|
||||
|
||||
If you're aiming to emulate the features of something like a Launchpad or other MIDI controller you'll need to access the internal MIDI device directly.
|
||||
|
||||
Because there are so many possible CC messages, not all of them are implemented as keycodes. Additionally, you might need to provide more than just two values that you would get from a keycode (pressed and released) - for example, the analog values from a fader or a potentiometer. So, you will need to implement [custom keycodes](feature_macros.md) if you want to use them in your keymap directly using `process_record_user()`.
|
||||
|
||||
|
||||
For reference of all the possible control code numbers see [MIDI Specification](#midi-specification)
|
||||
|
||||
#### Example code for using Generic On Off Switches as per MIDI Specification.
|
||||
```c
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
extern MidiDevice midi_device;
|
||||
|
||||
// MIDI CC codes for generic on/off switches (80, 81, 82, 83)
|
||||
// Off: 0-63
|
||||
// On: 64-127
|
||||
|
||||
#define MIDI_CC_OFF 0
|
||||
#define MIDI_CC_ON 127
|
||||
|
||||
enum custom_keycodes {
|
||||
MIDI_CC80 = SAFE_RANGE,
|
||||
};
|
||||
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case MIDI_CC80:
|
||||
if (record->event.pressed) {
|
||||
midi_send_cc(&midi_device, midi_config.channel, 80, ON);
|
||||
} else {
|
||||
midi_send_cc(&midi_device, midi_config.channel, 80, OFF);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
LAYOUT(
|
||||
// ...
|
||||
MIDI_CC80,
|
||||
// ...
|
||||
)
|
||||
};
|
||||
```
|
||||
|
||||
### Keycodes
|
||||
|
||||
|Keycode |Aliases |Description |
|
||||
|------------|---------|---------------------------------|
|
||||
|`MI_ON` | |Turn MIDI on |
|
||||
|`MI_OFF` | |Turn MIDI off |
|
||||
|`MI_TOG` | |Toggle MIDI enabled |
|
||||
|`MI_C` | |C octave 0 |
|
||||
|`MI_Cs` |`MI_Db` |C♯/D♭ octave 0 |
|
||||
|`MI_D` | |D octave 0 |
|
||||
|`MI_Ds` |`MI_Eb` |D♯/E♭ octave 0 |
|
||||
|`MI_E` | |E octave 0 |
|
||||
|`MI_F` | |F octave 0 |
|
||||
|`MI_Fs` |`MI_Gb` |F♯/G♭ octave 0 |
|
||||
|`MI_G` | |G octave 0 |
|
||||
|`MI_Gs` |`MI_Gs` |G♯/A♭ octave 0 |
|
||||
|`MI_A` | |A octave 0 |
|
||||
|`MI_As` |`MI_Bb` |A♯/B♭ octave 0 |
|
||||
|`MI_B` | |B octave 0 |
|
||||
|`MI_C_1` | |C octave 1 |
|
||||
|`MI_Cs_1` |`MI_Db_1`|C♯/D♭ octave 1 |
|
||||
|`MI_D_1` | |D octave 1 |
|
||||
|`MI_Ds_1` |`MI_Eb_1`|D♯/E♭ octave 1 |
|
||||
|`MI_E_1` | |E octave 1 |
|
||||
|`MI_F_1` | |F octave 1 |
|
||||
|`MI_Fs_1` |`MI_Gb_1`|F♯/G♭ octave 1 |
|
||||
|`MI_G_1` | |G octave 1 |
|
||||
|`MI_Gs_1` |`MI_Ab_1`|G♯/A♭ octave 1 |
|
||||
|`MI_A_1` | |A octave 1 |
|
||||
|`MI_As_1` |`MI_Bb_1`|A♯/B♭ octave 1 |
|
||||
|`MI_B_1` | |B octave 1 |
|
||||
|`MI_C_2` | |C octave 2 |
|
||||
|`MI_Cs_2` |`MI_Db_2`|C♯/D♭ octave 2 |
|
||||
|`MI_D_2` | |D octave 2 |
|
||||
|`MI_Ds_2` |`MI_Eb_2`|D♯/E♭ octave 2 |
|
||||
|`MI_E_2` | |E octave 2 |
|
||||
|`MI_F_2` | |F octave 2 |
|
||||
|`MI_Fs_2` |`MI_Gb_2`|F♯/G♭ octave 2 |
|
||||
|`MI_G_2` | |G octave 2 |
|
||||
|`MI_Gs_2` |`MI_Ab_2`|G♯/A♭ octave 2 |
|
||||
|`MI_A_2` | |A octave 2 |
|
||||
|`MI_As_2` |`MI_Bb_2`|A♯/B♭ octave 2 |
|
||||
|`MI_B_2` | |B octave 2 |
|
||||
|`MI_C_3` | |C octave 3 |
|
||||
|`MI_Cs_3` |`MI_Db_3`|C♯/D♭ octave 3 |
|
||||
|`MI_D_3` | |D octave 3 |
|
||||
|`MI_Ds_3` |`MI_Eb_3`|D♯/E♭ octave 3 |
|
||||
|`MI_E_3` | |E octave 3 |
|
||||
|`MI_F_3` | |F octave 3 |
|
||||
|`MI_Fs_3` |`MI_Gb_3`|F♯/G♭ octave 3 |
|
||||
|`MI_G_3` | |G octave 3 |
|
||||
|`MI_Gs_3` |`MI_Ab_3`|G♯/A♭ octave 3 |
|
||||
|`MI_A_3` | |A octave 3 |
|
||||
|`MI_As_3` |`MI_Bb_3`|A♯/B♭ octave 3 |
|
||||
|`MI_B_3` | |B octave 3 |
|
||||
|`MI_C_4` | |C octave 4 |
|
||||
|`MI_Cs_4` |`MI_Db_4`|C♯/D♭ octave 4 |
|
||||
|`MI_D_4` | |D octave 4 |
|
||||
|`MI_Ds_4` |`MI_Eb_4`|D♯/E♭ octave 4 |
|
||||
|`MI_E_4` | |E octave 4 |
|
||||
|`MI_F_4` | |F octave 4 |
|
||||
|`MI_Fs_4` |`MI_Gb_4`|F♯/G♭ octave 4 |
|
||||
|`MI_G_4` | |G octave 4 |
|
||||
|`MI_Gs_4` |`MI_Ab_4`|G♯/A♭ octave 4 |
|
||||
|`MI_A_4` | |A octave 4 |
|
||||
|`MI_As_4` |`MI_Bb_4`|A♯/B♭ octave 4 |
|
||||
|`MI_B_4` | |B octave 4 |
|
||||
|`MI_C_5` | |C octave 5 |
|
||||
|`MI_Cs_5` |`MI_Db_5`|C♯/D♭ octave 5 |
|
||||
|`MI_D_5` | |D octave 5 |
|
||||
|`MI_Ds_5` |`MI_Eb_5`|D♯/E♭ octave 5 |
|
||||
|`MI_E_5` | |E octave 5 |
|
||||
|`MI_F_5` | |F octave 5 |
|
||||
|`MI_Fs_5` |`MI_Gb_5`|F♯/G♭ octave 5 |
|
||||
|`MI_G_5` | |G octave 5 |
|
||||
|`MI_Gs_5` |`MI_Ab_5`|G♯/A♭ octave 5 |
|
||||
|`MI_A_5` | |A octave 5 |
|
||||
|`MI_As_5` |`MI_Bb_5`|A♯/B♭ octave 5 |
|
||||
|`MI_B_5` | |B octave 5 |
|
||||
|`MI_OCT_N2` | |Set octave to -2 |
|
||||
|`MI_OCT_N1` | |Set octave to -1 |
|
||||
|`MI_OCT_0` | |Set octave to 0 |
|
||||
|`MI_OCT_1` | |Set octave to 1 |
|
||||
|`MI_OCT_2` | |Set octave to 2 |
|
||||
|`MI_OCT_3` | |Set octave to 3 |
|
||||
|`MI_OCT_4` | |Set octave to 4 |
|
||||
|`MI_OCT_5` | |Set octave to 5 |
|
||||
|`MI_OCT_6` | |Set octave to 6 |
|
||||
|`MI_OCT_7` | |Set octave to 7 |
|
||||
|`MI_OCTD` | |Move down an octave |
|
||||
|`MI_OCTU` | |Move up an octave |
|
||||
|`MI_TRNS_N6`| |Set transposition to -6 semitones|
|
||||
|`MI_TRNS_N5`| |Set transposition to -5 semitones|
|
||||
|`MI_TRNS_N4`| |Set transposition to -4 semitones|
|
||||
|`MI_TRNS_N3`| |Set transposition to -3 semitones|
|
||||
|`MI_TRNS_N2`| |Set transposition to -2 semitones|
|
||||
|`MI_TRNS_N1`| |Set transposition to -1 semitone |
|
||||
|`MI_TRNS_0` | |No transposition |
|
||||
|`MI_TRNS_1` | |Set transposition to +1 semitone |
|
||||
|`MI_TRNS_2` | |Set transposition to +2 semitones|
|
||||
|`MI_TRNS_3` | |Set transposition to +3 semitones|
|
||||
|`MI_TRNS_4` | |Set transposition to +4 semitones|
|
||||
|`MI_TRNS_5` | |Set transposition to +5 semitones|
|
||||
|`MI_TRNS_6` | |Set transposition to +6 semitones|
|
||||
|`MI_TRNSD` | |Decrease transposition |
|
||||
|`MI_TRNSU` | |Increase transposition |
|
||||
|`MI_VEL_0` | |Set velocity to 0 |
|
||||
|`MI_VEL_1` | |Set velocity to 12 |
|
||||
|`MI_VEL_2` | |Set velocity to 25 |
|
||||
|`MI_VEL_3` | |Set velocity to 38 |
|
||||
|`MI_VEL_4` | |Set velocity to 51 |
|
||||
|`MI_VEL_5` | |Set velocity to 64 |
|
||||
|`MI_VEL_6` | |Set velocity to 76 |
|
||||
|`MI_VEL_7` | |Set velocity to 89 |
|
||||
|`MI_VEL_8` | |Set velocity to 102 |
|
||||
|`MI_VEL_9` | |Set velocity to 114 |
|
||||
|`MI_VEL_10` | |Set velocity to 127 |
|
||||
|`MI_VELD` | |Decrease velocity |
|
||||
|`MI_VELU` | |Increase velocity |
|
||||
|`MI_CH1` | |Set channel to 1 |
|
||||
|`MI_CH2` | |Set channel to 2 |
|
||||
|`MI_CH3` | |Set channel to 3 |
|
||||
|`MI_CH4` | |Set channel to 4 |
|
||||
|`MI_CH5` | |Set channel to 5 |
|
||||
|`MI_CH6` | |Set channel to 6 |
|
||||
|`MI_CH7` | |Set channel to 7 |
|
||||
|`MI_CH8` | |Set channel to 8 |
|
||||
|`MI_CH9` | |Set channel to 9 |
|
||||
|`MI_CH10` | |Set channel to 10 |
|
||||
|`MI_CH11` | |Set channel to 11 |
|
||||
|`MI_CH12` | |Set channel to 12 |
|
||||
|`MI_CH13` | |Set channel to 13 |
|
||||
|`MI_CH14` | |Set channel to 14 |
|
||||
|`MI_CH15` | |Set channel to 15 |
|
||||
|`MI_CH16` | |Set channel to 16 |
|
||||
|`MI_CHD` | |Decrease channel |
|
||||
|`MI_CHU` | |Increase channel |
|
||||
|`MI_ALLOFF` | |Stop all notes |
|
||||
|`MI_SUS` | |Sustain |
|
||||
|`MI_PORT` | |Portmento |
|
||||
|`MI_SOST` | |Sostenuto |
|
||||
|`MI_SOFT` | |Soft Pedal |
|
||||
|`MI_LEG` | |Legato |
|
||||
|`MI_MOD` | |Modulation |
|
||||
|`MI_MODSD` | |Decrease modulation speed |
|
||||
|`MI_MODSU` | |Increase modulation speed |
|
||||
|`MI_BENDD` | |Bend pitch down |
|
||||
|`MI_BENDU` | |Bend pitch up |
|
||||
|
||||
### Configuration
|
||||
|
||||
Certain values are stored in the `midi_config` struct. This configuration is not persisted to EEPROM. By default, these values are:
|
||||
|
||||
|Configuration |Value|Comments |
|
||||
|-------------------|-----|-------------------------|
|
||||
|Octave |`4` |Corresponds to `MI_OCT_2`|
|
||||
|Transposition |`0` | |
|
||||
|Velocity |`127`| |
|
||||
|Channel |`0` | |
|
||||
|Modulation Interval|`8` | |
|
||||
|
||||
For the above, the `MI_C` keycode will produce a C3 (note number 48), and so on.
|
||||
|
||||
### References
|
||||
#### MIDI Specification
|
||||
|
||||
* [MIDI.org](https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message)
|
||||
* [CMU MIDI Programmer's Reference](https://www.cs.cmu.edu/~music/cmsip/readings/MIDI%20tutorial%20for%20programmers.html)
|
||||
#### QMK C Files
|
||||
|
||||
* `quantum/process_keycode/process_midi.c`
|
||||
* `quantum/quantum_keycodes.h`
|
||||
* `tmk_core/protocol/midi.h`
|
||||
* `tmk_core/protocol/midi.c`
|
||||
* `tmk_core/protocol/qmk_midi.c`
|
||||
* `tmk_core/protocol/midi_device.h`
|
||||
|
||||
<!--
|
||||
#### QMK Internals (Autogenerated)
|
||||
|
||||
* [Internals/MIDI Device Setup Process](internals_midi_device_setup_process.md)
|
||||
* [Internals/MIDI Device](internals_midi_device.md)
|
||||
* [Internals/MIDI Util](internals_midi_util.md)
|
||||
-->
|
||||
@@ -263,11 +263,25 @@ void oled_write(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
|
||||
// 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);
|
||||
|
||||
// Returns a pointer to the requested start index in the buffer plus remaining
|
||||
// buffer length as struct
|
||||
oled_buffer_reader_t oled_read_raw(uint16_t start_index);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
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);
|
||||
|
||||
// Sets a specific pixel on or off
|
||||
// Coordinates start at top-left and go right and down for positive x and y
|
||||
void oled_write_pixel(uint8_t x, uint8_t y, bool on);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Remapped to call 'void oled_write(const char *data, bool invert);' on ARM
|
||||
@@ -279,23 +293,9 @@ void oled_write_P(const char *data, bool invert);
|
||||
// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM
|
||||
void oled_write_ln_P(const char *data, bool invert);
|
||||
|
||||
// Returns a pointer to the requested start index in the buffer plus remaining
|
||||
// buffer length as struct
|
||||
oled_buffer_reader_t oled_read_raw(uint16_t start_index);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
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
|
||||
void oled_write_raw_P(const char *data, uint16_t size);
|
||||
|
||||
// Sets a specific pixel on or off
|
||||
// Coordinates start at top-left and go right and down for positive x and y
|
||||
void oled_write_pixel(uint8_t x, uint8_t y, bool on);
|
||||
|
||||
// Can be used to manually turn on the screen if it is off
|
||||
// Returns true if the screen was on or turns on
|
||||
bool oled_on(void);
|
||||
@@ -346,6 +346,10 @@ bool oled_scroll_left(void);
|
||||
// Returns true if the screen was not scrolling or stops scrolling
|
||||
bool oled_scroll_off(void);
|
||||
|
||||
// Inverts the display
|
||||
// Returns true if the screen was or is inverted
|
||||
bool oled_invert(bool invert);
|
||||
|
||||
// Returns the maximum number of characters that will fit on a line
|
||||
uint8_t oled_max_chars(void);
|
||||
|
||||
|
||||
@@ -228,6 +228,76 @@ Configure the hardware via your `config.h`:
|
||||
```
|
||||
|
||||
---
|
||||
### AW20216 :id=aw20216
|
||||
There is basic support for addressable RGB matrix lighting with the SPI AW20216 RGB controller. To enable it, add this to your `rules.mk`:
|
||||
|
||||
```makefile
|
||||
RGB_MATRIX_ENABLE = yes
|
||||
RGB_MATRIX_DRIVER = AW20216
|
||||
```
|
||||
|
||||
You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `DRIVER_1_CS` | (Required) MCU pin connected to first RGB driver chip select line | B13 |
|
||||
| `DRIVER_2_CS` | (Optional) MCU pin connected to second RGB driver chip select line | |
|
||||
| `DRIVER_1_EN` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 |
|
||||
| `DRIVER_2_EN` | (Optional) MCU pin connected to second RGB driver hardware enable line | |
|
||||
| `DRIVER_1_LED_TOTAL` | (Required) How many RGB lights are connected to first RGB driver | |
|
||||
| `DRIVER_2_LED_TOTAL` | (Optional) How many RGB lights are connected to second RGB driver | |
|
||||
| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
|
||||
| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
|
||||
| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
|
||||
| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
|
||||
|
||||
Here is an example using 2 drivers.
|
||||
|
||||
```c
|
||||
#define DRIVER_1_CS B13
|
||||
#define DRIVER_2_CS B14
|
||||
// Hardware enable lines may be connected to the same pin
|
||||
#define DRIVER_1_EN C13
|
||||
#define DRIVER_2_EN C13
|
||||
|
||||
#define DRIVER_COUNT 2
|
||||
#define DRIVER_1_LED_TOTAL 66
|
||||
#define DRIVER_2_LED_TOTAL 32
|
||||
#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
|
||||
```
|
||||
|
||||
!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
|
||||
|
||||
Define these arrays listing all the LEDs in your `<keyboard>.c`:
|
||||
|
||||
```c
|
||||
const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
|
||||
/* Each AW20216 channel is controlled by a register at some offset between 0x00
|
||||
* and 0xD7 inclusive.
|
||||
* See drivers/awinic/aw20216.h for the mapping between register offsets and
|
||||
* driver pin locations.
|
||||
* driver
|
||||
* | R location
|
||||
* | | G location
|
||||
* | | | B location
|
||||
* | | | | */
|
||||
{ 0, CS1_SW1, CS2_SW1, CS3_SW1 },
|
||||
{ 0, CS4_SW1, CS5_SW1, CS6_SW1 },
|
||||
{ 0, CS7_SW1, CS8_SW1, CS9_SW1 },
|
||||
{ 0, CS10_SW1, CS11_SW1, CS12_SW1 },
|
||||
{ 0, CS13_SW1, CS14_SW1, CS15_SW1 },
|
||||
...
|
||||
{ 1, CS1_SW1, CS2_SW1, CS3_SW1 },
|
||||
{ 1, CS13_SW1, CS14_SW1, CS15_SW1 },
|
||||
{ 1, CS16_SW1, CS17_SW1, CS18_SW1 },
|
||||
{ 1, CS4_SW2, CS5_SW2, CS6_SW2 },
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Configuration :id=common-configuration
|
||||
|
||||
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:
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ QMK Firmware has a generic implementation that is usable by any board, as well a
|
||||
|
||||
For this, we will mostly be talking about the generic implementation used by the Let's Split and other keyboards.
|
||||
|
||||
!> ARM is not yet fully supported for Split Keyboards and has many limitations. Progress is being made, but we have not yet reached 100% feature parity.
|
||||
|
||||
!> ARM split supports most QMK subsystems when using the 'serial' and 'serial_usart' drivers. I2C slave is currently unsupported.
|
||||
|
||||
## Compatibility Overview
|
||||
|
||||
@@ -60,6 +59,7 @@ The 3 wires of the TRS/TRRS cable need to connect GND, VCC, and D0/D1/D2/D3 (aka
|
||||
The 4 wires of the TRRS cable need to connect GND, VCC, and SCL and SDA (aka PD0/pin 3 and PD1/pin 2, respectively) between the two Pro Micros.
|
||||
|
||||
The pull-up resistors may be placed on either half. If you wish to use the halves independently, it is also possible to use 4 resistors and have the pull-ups in both halves.
|
||||
Note that the total resistance for the connected system should be within spec at 2.2k-10kOhm, with an 'ideal' at 4.7kOhm, regardless of the placement and number.
|
||||
|
||||
<img alt="sk-i2c-connection-mono" src="https://user-images.githubusercontent.com/2170248/92297182-92b98580-ef77-11ea-9d7d-d6033914af43.JPG" width="50%"/>
|
||||
|
||||
@@ -168,7 +168,7 @@ Because not every split keyboard is identical, there are a number of additional
|
||||
#define USE_I2C
|
||||
```
|
||||
|
||||
This enables I<sup>2</sup>C support for split keyboards. This isn't strictly for communication, but can be used for OLED or other I<sup>2</sup>C-based devices.
|
||||
This configures the use of I<sup>2</sup>C support for split keyboard transport (AVR only).
|
||||
|
||||
```c
|
||||
#define SOFT_SERIAL_PIN D0
|
||||
@@ -192,20 +192,115 @@ If you're having issues with serial communication, you can change this value, as
|
||||
* **`5`**: about 20kbps
|
||||
|
||||
```c
|
||||
#define SPLIT_MODS_ENABLE
|
||||
#define FORCED_SYNC_THROTTLE_MS 100
|
||||
```
|
||||
|
||||
This enables transmitting modifier state (normal, weak and oneshot) to the non
|
||||
primary side of the split keyboard. This adds a few bytes of data to the split
|
||||
communication protocol and may impact the matrix scan speed when enabled.
|
||||
The purpose of this feature is to support cosmetic use of modifer state (e.g.
|
||||
displaying status on an OLED screen).
|
||||
This sets the maximum number of milliseconds before forcing a synchronization of data from master to slave. Under normal circumstances this sync occurs whenever the data _changes_, for safety a data transfer occurs after this number of milliseconds if no change has been detected since the last sync.
|
||||
|
||||
```c
|
||||
#define SPLIT_TRANSPORT_MIRROR
|
||||
```
|
||||
|
||||
This mirrors the master side matrix to the slave side for features that react or require knowledge of master side key presses on the slave side. This adds a few bytes of data to the split communication protocol and may impact the matrix scan speed when enabled. The purpose of this feature is to support cosmetic use of key events (e.g. RGB reacting to Keypresses).
|
||||
This mirrors the master side matrix to the slave side for features that react or require knowledge of master side key presses on the slave side. The purpose of this feature is to support cosmetic use of key events (e.g. RGB reacting to keypresses). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
|
||||
|
||||
```c
|
||||
#define SPLIT_LAYER_STATE_ENABLE
|
||||
```
|
||||
|
||||
This enables syncing of the layer state between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the currently active layer. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
|
||||
|
||||
```c
|
||||
#define SPLIT_LED_STATE_ENABLE
|
||||
```
|
||||
|
||||
This enables syncing of the Host LED status (caps lock, num lock, etc) between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the Host LED status. This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
|
||||
|
||||
```c
|
||||
#define SPLIT_MODS_ENABLE
|
||||
```
|
||||
|
||||
This enables transmitting modifier state (normal, weak and oneshot) to the non primary side of the split keyboard. The purpose of this feature is to support cosmetic use of modifer state (e.g. displaying status on an OLED screen). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
|
||||
|
||||
```c
|
||||
#define SPLIT_WPM_ENABLE
|
||||
```
|
||||
|
||||
This enables transmitting the current WPM to the slave side of the split keyboard. The purpose of this feature is to support cosmetic use of WPM (e.g. displaying the current value on an OLED screen). This adds overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled.
|
||||
|
||||
### Custom data sync between sides :id=custom-data-sync
|
||||
|
||||
QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master.
|
||||
|
||||
To leverage this, a keyboard or user/keymap can define a comma-separated list of _transaction IDs_:
|
||||
|
||||
```c
|
||||
// for keyboard-level data sync:
|
||||
#define SPLIT_TRANSACTION_IDS_KB KEYBOARD_SYNC_A, KEYBOARD_SYNC_B
|
||||
// or, for user:
|
||||
#define SPLIT_TRANSACTION_IDS_USER USER_SYNC_A, USER_SYNC_B, USER_SYNC_C
|
||||
```
|
||||
|
||||
These _transaction IDs_ then need a slave-side handler function to be registered with the split transport, for example:
|
||||
|
||||
```c
|
||||
typedef struct _master_to_slave_t {
|
||||
int m2s_data;
|
||||
} master_to_slave_t;
|
||||
|
||||
typedef struct _slave_to_master_t {
|
||||
int s2m_data;
|
||||
} slave_to_master_t;
|
||||
|
||||
void user_sync_a_slave_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
|
||||
const master_to_slave_t *m2s = (const master_to_slave_t*)in_data;
|
||||
slave_to_master_t *s2m = (slave_to_master_t*)out_data;
|
||||
s2m->s2m_data = m2s->m2s_data + 5; // whatever comes in, add 5 so it can be sent back
|
||||
}
|
||||
|
||||
void keyboard_post_init_user(void) {
|
||||
transaction_register_rpc(USER_SYNC_A, user_sync_a_slave_handler);
|
||||
}
|
||||
```
|
||||
|
||||
The master side can then invoke the slave-side handler - for normal keyboard functionality to be minimally affected, any keyboard- or user-level code attempting to sync data should be throttled:
|
||||
|
||||
```c
|
||||
void housekeeping_task_user(void) {
|
||||
if (is_keyboard_master()) {
|
||||
// Interact with slave every 500ms
|
||||
static uint32_t last_sync = 0;
|
||||
if (timer_elapsed32(last_sync) > 500) {
|
||||
master_to_slave_t m2s = {6};
|
||||
slave_to_master_t s2m = {0};
|
||||
if(transaction_rpc_exec(USER_SYNC_A, sizeof(m2s), &m2s, sizeof(s2m), &s2m)) {
|
||||
last_sync = timer_read32();
|
||||
dprintf("Slave value: %d\n", s2m.s2m_data); // this will now be 11, as the slave adds 5
|
||||
} else {
|
||||
dprint("Slave sync failed!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!> It is recommended that any data sync between halves happens during the master side's _housekeeping task_. This ensures timely retries should failures occur.
|
||||
|
||||
If only one-way data transfer is needed, helper methods are provided:
|
||||
|
||||
```c
|
||||
bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer);
|
||||
bool transaction_rpc_send(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer);
|
||||
bool transaction_rpc_recv(int8_t transaction_id, uint8_t target2initiator_buffer_size, void *target2initiator_buffer);
|
||||
```
|
||||
|
||||
By default, the inbound and outbound data is limited to a maximum of 32 bytes each. The sizes can be altered if required:
|
||||
|
||||
```c
|
||||
// Master to slave:
|
||||
#define RPC_M2S_BUFFER_SIZE 48
|
||||
// Slave to master:
|
||||
#define RPC_S2M_BUFFER_SIZE 48
|
||||
```
|
||||
|
||||
### Hardware Configuration Options
|
||||
|
||||
|
||||
274
docs/feature_st7565.md
Normal file
274
docs/feature_st7565.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# ST7565 LCD Driver
|
||||
|
||||
## Supported Hardware
|
||||
|
||||
LCD modules using ST7565 driver IC, communicating over SPI.
|
||||
|
||||
|Module |IC |Size |Notes |
|
||||
|------------------------------|-------|------|----------------------------------------------------------|
|
||||
|Newhaven Display NHD-C12832A1Z|ST7565R|128x32|Used by Ergodox Infinity; primary consumer of this feature|
|
||||
|Zolentech ZLE12864B |ST7565P|128x64|Requires contrast adjustment |
|
||||
|
||||
## Usage
|
||||
|
||||
To enable the feature, there are three steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`:
|
||||
|
||||
```make
|
||||
ST7565_ENABLE = yes
|
||||
```
|
||||
|
||||
Then in your `keymap.c` file, implement the ST7565 task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`:
|
||||
|
||||
```c
|
||||
#ifdef ST7565_ENABLE
|
||||
void st7565_task_user(void) {
|
||||
// Host Keyboard Layer Status
|
||||
st7565_write_P(PSTR("Layer: "), false);
|
||||
|
||||
switch (get_highest_layer(layer_state)) {
|
||||
case _QWERTY:
|
||||
st7565_write_P(PSTR("Default\n"), false);
|
||||
break;
|
||||
case _FN:
|
||||
st7565_write_P(PSTR("FN\n"), false);
|
||||
break;
|
||||
case _ADJ:
|
||||
st7565_write_P(PSTR("ADJ\n"), false);
|
||||
break;
|
||||
default:
|
||||
// Or use the write_ln shortcut over adding '\n' to the end of your string
|
||||
st7565_write_ln_P(PSTR("Undefined"), false);
|
||||
}
|
||||
|
||||
// Host Keyboard LED Status
|
||||
led_t led_state = host_keyboard_led_state();
|
||||
st7565_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
|
||||
st7565_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
|
||||
st7565_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false);
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
## Logo Example
|
||||
|
||||
In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the screen, use the following code example:
|
||||
|
||||
```c
|
||||
static void render_logo(void) {
|
||||
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,
|
||||
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, 0x00
|
||||
};
|
||||
|
||||
st7565_write_P(qmk_logo, false);
|
||||
}
|
||||
```
|
||||
|
||||
## Buffer Read Example
|
||||
For some purposes, you may need to read the current state of the display buffer. The `st7565_read_raw` function can be used to safely read bytes from the buffer.
|
||||
|
||||
In this example, calling `fade_display` in the `st7565_task_user` function will slowly fade away whatever is on the screen by turning random pixels off over time.
|
||||
```c
|
||||
//Setup some mask which can be or'd with bytes to turn off pixels
|
||||
const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254};
|
||||
|
||||
static void fade_display(void) {
|
||||
//Define the reader structure
|
||||
display_buffer_reader_t reader;
|
||||
uint8_t buff_char;
|
||||
if (random() % 30 == 0) {
|
||||
srand(timer_read());
|
||||
// Fetch a pointer for the buffer byte at index 0. The return structure
|
||||
// will have the pointer and the number of bytes remaining from this
|
||||
// index position if we want to perform a sequential read by
|
||||
// incrementing the buffer pointer
|
||||
reader = st7565_read_raw(0);
|
||||
//Loop over the remaining buffer and erase pixels as we go
|
||||
for (uint16_t i = 0; i < reader.remaining_element_count; i++) {
|
||||
//Get the actual byte in the buffer by dereferencing the pointer
|
||||
buff_char = *reader.current_element;
|
||||
if (buff_char != 0) {
|
||||
st7565_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i);
|
||||
}
|
||||
//increment the pointer to fetch a new byte during the next loop
|
||||
reader.current_element++;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Other Examples
|
||||
|
||||
In split keyboards, it is very common to have two 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
|
||||
#ifdef ST7565_ENABLE
|
||||
display_rotation_t st7565_init_user(display_rotation_t rotation) {
|
||||
if (!is_keyboard_master()) {
|
||||
return DISPLAY_ROTATION_180; // flips the display 180 degrees if offhand
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void st7565_task_user(void) {
|
||||
if (is_keyboard_master()) {
|
||||
render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
|
||||
} else {
|
||||
render_logo(); // Renders a static logo
|
||||
}
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
## Basic Configuration
|
||||
|
||||
|Define |Default |Description |
|
||||
|------------------------|--------------|-----------------------------------------------------------------------------------------------------|
|
||||
|`ST7565_A0_PIN` |*Not defined* |(Required) The GPIO connected to the display's A0 (data/command) pin |
|
||||
|`ST7565_RST_PIN` |*Not defined* |(Required) The GPIO connected to the display's reset pin |
|
||||
|`ST7565_SS_PIN` |*Not defined* |(Required) The GPIO connected to the display's slave select pin |
|
||||
|`ST7565_SPI_CLK_DIVISOR`|`4` |The SPI clock divisor to use |
|
||||
|`ST7565_FONT_H` |`"glcdfont.c"`|The font code file to use for custom fonts |
|
||||
|`ST7565_FONT_START` |`0` |The starting character index for custom fonts |
|
||||
|`ST7565_FONT_END` |`223` |The ending character index for custom fonts |
|
||||
|`ST7565_FONT_WIDTH` |`6` |The font width |
|
||||
|`ST7565_FONT_HEIGHT` |`8` |The font height (untested) |
|
||||
|`ST7565_TIMEOUT` |`60000` |Turns off the screen after 60000ms of keyboard inactivity. Helps reduce burn-in. Set to 0 to disable.|
|
||||
|`ST7565_COLUMN_OFFSET` |`0` |Shift output to the right this many pixels. |
|
||||
|`ST7565_CONTRAST` |`32` |The default contrast level of the display, from 0 to 255. |
|
||||
|`ST7565_UPDATE_INTERVAL`|`0` |Set the time interval for updating the display in ms. This will improve the matrix scan rate. |
|
||||
|
||||
## Custom sized displays
|
||||
|
||||
The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind.
|
||||
|
||||
|Define |Default |Description |
|
||||
|-----------------------|----------|-----------------------------------------------------------------------------------------------------------|
|
||||
|`ST7565_DISPLAY_WIDTH` |`128` |The width of the display. |
|
||||
|`ST7565_DISPLAY_HEIGHT`|`32` |The height of the display. |
|
||||
|`ST7565_MATRIX_SIZE` |`512` |The local buffer size to allocate.<br>`(ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH)`. |
|
||||
|`ST7565_BLOCK_TYPE` |`uint16_t`|The unsigned integer type to use for dirty rendering. |
|
||||
|`ST7565_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.<br>`(sizeof(ST7565_BLOCK_TYPE) * 8)`.|
|
||||
|`ST7565_BLOCK_SIZE` |`32` |The size of each block for dirty rendering<br>`(ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)`. |
|
||||
|
||||
## API
|
||||
|
||||
```c
|
||||
// Rotation enum values are flags
|
||||
typedef enum {
|
||||
DISPLAY_ROTATION_0,
|
||||
DISPLAY_ROTATION_180
|
||||
} display_rotation_t;
|
||||
|
||||
// Initialize the display, rotating the rendered output based on the define passed in.
|
||||
// Returns true if the was initialized successfully
|
||||
bool st7565_init(display_rotation_t rotation);
|
||||
|
||||
// Called at the start of st7565_init, weak function overridable by the user
|
||||
// rotation - the value passed into st7565_init
|
||||
// Return new display_rotation_t if you want to override default rotation
|
||||
display_rotation_t st7565_init_user(display_rotation_t rotation);
|
||||
|
||||
// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
|
||||
void st7565_clear(void);
|
||||
|
||||
// Renders the dirty chunks of the buffer to display
|
||||
void st7565_render(void);
|
||||
|
||||
// Moves cursor to character position indicated by column and line, wraps if out of bounds
|
||||
// Max column denoted by 'st7565_max_chars()' and max lines by 'st7565_max_lines()' functions
|
||||
void st7565_set_cursor(uint8_t col, uint8_t line);
|
||||
|
||||
// Advances the cursor to the next page, writing ' ' if true
|
||||
// Wraps to the begining when out of bounds
|
||||
void st7565_advance_page(bool clearPageRemainder);
|
||||
|
||||
// Moves the cursor forward 1 character length
|
||||
// Advance page if there is not enough room for the next character
|
||||
// Wraps to the begining when out of bounds
|
||||
void st7565_advance_char(void);
|
||||
|
||||
// Writes a single character to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Main handler that writes character data to the display buffer
|
||||
void st7565_write_char(const char data, bool invert);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
void st7565_write(const char *data, bool invert);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||
void st7565_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
|
||||
void st7565_pan(bool left);
|
||||
|
||||
// Returns a pointer to the requested start index in the buffer plus remaining
|
||||
// buffer length as struct
|
||||
display_buffer_reader_t st7565_read_raw(uint16_t start_index);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
void st7565_write_raw(const char *data, uint16_t size);
|
||||
|
||||
// Writes a single byte into the buffer at the specified index
|
||||
void st7565_write_raw_byte(const char data, uint16_t index);
|
||||
|
||||
// Sets a specific pixel on or off
|
||||
// Coordinates start at top-left and go right and down for positive x and y
|
||||
void st7565_write_pixel(uint8_t x, uint8_t y, bool on);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Remapped to call 'void st7565_write(const char *data, bool invert);' on ARM
|
||||
void st7565_write_P(const char *data, bool invert);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||
// Remapped to call 'void st7565_write_ln(const char *data, bool invert);' on ARM
|
||||
void st7565_write_ln_P(const char *data, bool invert);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
void st7565_write_raw_P(const char *data, uint16_t size);
|
||||
|
||||
// Can be used to manually turn on the screen if it is off
|
||||
// Returns true if the screen was on or turns on
|
||||
bool st7565_on(void);
|
||||
|
||||
// Called when st7565_on() turns on the screen, weak function overridable by the user
|
||||
// Not called if the screen is already on
|
||||
void st7565_on_user(void);
|
||||
|
||||
// Can be used to manually turn off the screen if it is on
|
||||
// Returns true if the screen was off or turns off
|
||||
bool st7565_off(void);
|
||||
|
||||
// Called when st7565_off() turns off the screen, weak function overridable by the user
|
||||
// Not called if the screen is already off
|
||||
void st7565_off_user(void);
|
||||
|
||||
// Returns true if the screen is currently on, false if it is
|
||||
// not
|
||||
bool st7565_is_on(void);
|
||||
|
||||
// Basically it's st7565_render, but with timeout management and st7565_task_user calling!
|
||||
void st7565_task(void);
|
||||
|
||||
// Called at the start of st7565_task, weak function overridable by the user
|
||||
void st7565_task_user(void);
|
||||
|
||||
// Inverts the display
|
||||
// Returns true if the screen was or is inverted
|
||||
bool st7565_invert(bool invert);
|
||||
|
||||
// Returns the maximum number of characters that will fit on a line
|
||||
uint8_t st7565_max_chars(void);
|
||||
|
||||
// Returns the maximum number of lines that will fit on the display
|
||||
uint8_t st7565_max_lines(void);
|
||||
```
|
||||
@@ -155,6 +155,7 @@
|
||||
* [QMK への貢献](ja/contributing.md)
|
||||
* [QMK ドキュメントの翻訳](ja/translating.md)
|
||||
* [設定オプション](ja/config_options.md)
|
||||
* [データ駆動型コンフィギュレーション](ja/data_driven_config.md)
|
||||
* [Make ドキュメント](ja/getting_started_make_guide.md)
|
||||
* [ドキュメント ベストプラクティス](ja/documentation_best_practices.md)
|
||||
* [ドキュメント テンプレート](ja/documentation_templates.md)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# キーボードの挙動をカスタマイズする方法
|
||||
|
||||
<!---
|
||||
original document: 0.10.52:docs/custom_quantum_functions.md
|
||||
git diff 0.10.52 HEAD -- docs/custom_quantum_functions.md | cat
|
||||
original document: 0.12.41:docs/custom_quantum_functions.md
|
||||
git diff 0.12.41 HEAD -- docs/custom_quantum_functions.md | cat
|
||||
-->
|
||||
|
||||
多くの人にとって、カスタムキーボードはボタンの押下をコンピュータに送信するだけではありません。単純なボタンの押下やマクロよりも複雑なことを実行できるようにしたいでしょう。QMK にはコードを挿入したり、機能を上書きしたり、様々な状況でキーボードの挙動をカスタマイズできるフックがあります。
|
||||
@@ -190,6 +190,14 @@ void keyboard_post_init_user(void) {
|
||||
|
||||
カスタムマトリックススキャンコードが必要な場合は、この関数を使う必要があります。また、カスタムステータス出力 (LED あるいはディスプレイなど)や、ユーザが入力していない場合でも定期的にトリガーするその他の機能のために使うことができます。
|
||||
|
||||
# キーボードハウスキーピング :id=keyboard-housekeeping
|
||||
|
||||
* キーボード/リビジョン: `void housekeeping_task_kb(void)`
|
||||
* キーマップ: `void housekeeping_task_user(void)`
|
||||
|
||||
この関数は、全ての QMK 処理の最後に、次の繰り返しを開始する前に呼び出されます。`housekeeping_task_*` の関数が呼び出された時点で、QMK が最後のマトリックススキャンを処理したと、安全に見なすことができます -- レイヤーの状態が更新され、USB レポートが送信され、LED が更新され、表示が描画されています。
|
||||
|
||||
`matrix_scan_*` と同様に、これらは MCU が処理できる頻度で呼び出されます。キーボードの応答性を維持するために、これらの関数の呼び出し中にできるだけ何もしないことをお勧めします。実際に何か特別なものを実装する必要がある場合に動作を停止させる可能性があります。
|
||||
|
||||
# キーボードアイドリング/ウェイクコード
|
||||
|
||||
|
||||
123
docs/ja/data_driven_config.md
Normal file
123
docs/ja/data_driven_config.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# データ駆動型コンフィギュレーション
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.12.7:docs/data_driven_config.md
|
||||
git diff 0.12.7 HEAD -- docs/data_driven_config.md | cat
|
||||
-->
|
||||
|
||||
このページでは、QMK のデータ駆動型 JSON コンフィギュレーションシステムがどのように動作するかを説明します。これは、QMK 自体に取り組みたい開発者を対象としています。
|
||||
|
||||
## ヒストリー
|
||||
|
||||
これまで、QMK は、`rules.mk` と `config.h` の2つのメカニズムを組み合わせてコンフィギュレーションされてきました。
|
||||
この方法は、QMK がほんの一握りのキーボードをサポートしていたときは上手く機能していましたが、今では、サポートするキーボードは1500近くまで成長しました。
|
||||
`keyboards` の下だけで6000個の設定ファイルがあることが推定されます。
|
||||
これらのファイルの自由形式の性質と、重複を避けるために人々が使用してきたユニークなパターンが継続的なメンテナンスを困難にしており、また、多くのキーボードが時代遅れで時には理解が難しいパターンに従っています。
|
||||
|
||||
また、CLI に慣れていない人に QMK のパワーを提供することにも取り組んでおり、VIA などの他のプロジェクトでは、プログラムをインストールするのと同じくらい簡単に QMK を使用できるように取り組んでいます。
|
||||
これらのツールには、ユーザーが QMK を最大限に活用できるように、キーボードのレイアウト方法や使用可能なピンと機能に関する情報が必要です。
|
||||
その第一歩として `info.json` を導入しました。
|
||||
QMK API は、これら3つの情報源(`config.h`、` rules.mk`、および `info.json`)を、エンドユーザーツールが使用できる信頼できる単一の情報源に結合するための取り組みです。
|
||||
|
||||
これで、`info.json`から `rules.mk` と `config.h` の値を生成することがサポートされ、信頼できる単一の情報源を持つことができます。
|
||||
これにより、自動化されたツールを使用してキーボードを保守できるため、時間と保守作業を大幅に節約できます。
|
||||
|
||||
## 概要
|
||||
|
||||
C 側では何も変わりません。
|
||||
新しいルールを作成したり、定義したりする必要がある場合は、同じプロセスに従います。
|
||||
|
||||
1. `docs/config_options.md` に追加します。
|
||||
1. 適切なコアファイルにデフォルトを設定します。
|
||||
1. 必要に応じて ifdef 文を追加します。
|
||||
|
||||
次に、新しい構成のサポートを `info.json` に追加する必要があります。
|
||||
基本的なプロセスは次のとおりです。
|
||||
|
||||
1. `data/schemas/keyboards.jsonschema` のスキーマに追加します
|
||||
1. `data/maps` にマッピングを追加します
|
||||
1. (オプションおよび非推奨)構成を抽出/生成するコードを追加します。
|
||||
* `lib/python/qmk/info.py`
|
||||
* `lib/python/qmk/cli/generate/config_h.py`
|
||||
* `lib/python/qmk/cli/generate/rules_mk.py`
|
||||
|
||||
## info.json にオプションを追加する
|
||||
|
||||
このセクションでは、info.json に `config.h`/`rules.mk` の値のサポートを追加することについて説明します。
|
||||
|
||||
### スキーマに追加する
|
||||
|
||||
QMK では、[jsonschema](https:json-schema.org) のファイルを `data/schemas` に保持しています。
|
||||
キーボード固有の `info.json` ファイルに入る値は `keyboard.jsonschema` に保持されています。
|
||||
エンドユーザーが編集できるようにしたい値はすべてここに入れなければなりません。
|
||||
|
||||
場合によっては、新しいトップレベルキーを追加するだけで済みます。
|
||||
従うべきいくつかの例は、 `keyboard_name`、`maintainer`、 `processor`、および `url` です。
|
||||
これは、オプションが自己完結型で、他のオプションと直接関係がない場合に適しています。
|
||||
|
||||
その他の場合、1つの `object` の中に、似ているオプションを集める必要があります。
|
||||
これは、機能のサポートを追加する場合に特に当てはまります。
|
||||
このために従うべきいくつかの例は、`indicators`、`matrix_pins`、および `rgblight` です。
|
||||
新しいオプションを統合する方法がわからない場合は、[問題を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=)か、[Discord で #cli に参加](https://discord.gg/heQPAgy)して、そこで会話を始めてください。
|
||||
|
||||
### マッピングを追加する
|
||||
|
||||
ほとんどの場合、単純なマッピングを追加することができます。
|
||||
これらは `data/mappings/info_config.json` と `data/mappings/info_rules.json` に JSON ファイルとして保持され、それぞれ `config.h` と `rules.mk` のマッピングを制御します。
|
||||
各マッピングは `config.h` または `rules.mk` 変数名をキーとし、値は以下のキーを持つハッシュです。
|
||||
|
||||
* `info_key`: (必須)この値の `info.json` 内の場所。 下記参照。
|
||||
* `value_type`: (オプション)デフォルトは `str`。 この変数の値の形式。 下記参照。
|
||||
* `to_json`: (オプション)デフォルトは `true`。 このマッピングを info.json から除外するには、`false` に設定します
|
||||
* `to_c`: (オプション)デフォルトは `true`。 このマッピングを config.h から除外するには、`false` に設定します
|
||||
* `warn_duplicate`: (オプション)デフォルトは `true`。 値が両方の場所に存在する場合に警告をオフにするには、`false` に設定します
|
||||
|
||||
#### Info Key
|
||||
|
||||
info.json 内の変数をアドレス指定するために JSON ドット表記を使用します。
|
||||
たとえば、`info_json["rgblight"]["split_count"]` にアクセスするには、`rgblight.split_count` を指定します。
|
||||
これにより、深くネストされたキーを単純な文字列でアドレス指定できます。
|
||||
|
||||
内部では [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/) を使用しています。これらの文字列がオブジェクトアクセスに変換される方法についてはそのドキュメントを参照してください。
|
||||
|
||||
#### Value Types
|
||||
|
||||
デフォルトでは、すべての値を単純な文字列として扱います。
|
||||
値がより複雑な場合は、次のいずれかのタイプを使用してデータをインテリジェントに解析できます。
|
||||
|
||||
* `array`: 文字列のコンマ区切りの配列
|
||||
* `array.int`: 整数のコンマ区切り配列
|
||||
* `int`: 整数
|
||||
* `hex`: 16進数としてフォーマットされた数値
|
||||
* `list`: 文字列のスペース区切りの配列
|
||||
* `mapping`: キーと値のペアのハッシュ
|
||||
|
||||
### 抽出するコードを追加する
|
||||
|
||||
ほとんどのユースケースは、上記のマッピングファイルによって解決できます。
|
||||
できない場合は、代わりに設定値を抽出するコードを書くことができます。
|
||||
|
||||
QMK が完全な `info.json` を生成するときはいつでも、`config.h` と `rules.mk` から情報を抽出します。
|
||||
あなたの新しい設定値のためのコードを `lib/python/qmk/info.py` に追加する必要があります。
|
||||
通常、これは、新しい `_extract_<feature>()` 関数を追加してから、 `_extract_config_h()` または `_extract_rules_mk()` のいずれかで関数を呼び出すことを意味します。
|
||||
|
||||
このファイルの編集方法がわからない場合、または Python に慣れていない場合は、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=)か [Discord で #cli に参加](https://discord.gg/heQPAgy)すると、この部分を誰かが手伝ってくれるでしょう。
|
||||
|
||||
### 生成するコードを追加する
|
||||
|
||||
パズルの最後のピースは、ビルドシステムに新しいオプションを提供することです。
|
||||
これは、2つのファイルを生成することによって行われます。
|
||||
|
||||
* `.build/obj_<keyboard>/src/info_config.h`
|
||||
* `.build/obj_<keyboard>/src/rules.mk`
|
||||
|
||||
この2つのファイルは、次のコードによって生成されます。
|
||||
|
||||
* `lib/python/qmk/cli/generate/config_h.py`
|
||||
* `lib/python/qmk/cli/generate/rules_mk.py`
|
||||
|
||||
`config.h`値の場合、ルール用の関数を記述し、その関数を `generate_config_h()` で呼び出す必要があります。
|
||||
|
||||
`rules.mk` の新しいトップレベルの `info.json` キーがある場合は、`lib/python/qmk/cli/generate/rules_mk.py` の上部にある `info_to_rules` にキーを追加するだけです。
|
||||
それ以外の場合は、`generate_rules_mk()` で機能の新しい if ブロックを作成する必要があります。
|
||||
@@ -1,8 +1,8 @@
|
||||
# よくあるビルドの質問
|
||||
|
||||
<!---
|
||||
original document: 0.10.33:docs/faq_build.md
|
||||
git diff 0.10.33 HEAD -- docs/faq_build.md | cat
|
||||
original document: 0.12.43:docs/faq_build.md
|
||||
git diff 0.12.43 HEAD -- docs/faq_build.md | cat
|
||||
-->
|
||||
|
||||
このページは QMK のビルドに関する質問を説明します。まだビルドをしていない場合は、[ビルド環境のセットアップ](ja/getting_started_build_tools.md) および [Make 手順](ja/getting_started_make_guide.md)ガイドを読むべきです。
|
||||
@@ -22,73 +22,9 @@
|
||||
|
||||
`make` を `sudo` で実行することは一般的には良い考えでは***なく***、可能であれば前者の方法のいずれかを使うべきです。
|
||||
|
||||
### Linux の `udev` ルール
|
||||
### Linux の `udev` ルール :id=linux-udev-rules
|
||||
|
||||
Linux では、ブートローダデバイスと通信するには適切な権限が必要です。ファームウェアを書き込む時に `sudo` を使うか、`/etc/udev/rules.d/` にこのファイルを配置することで、通信することができます。
|
||||
|
||||
**/etc/udev/rules.d/50-qmk.rules:**
|
||||
```
|
||||
# Atmel DFU
|
||||
### ATmega16U2
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FEF", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
### ATmega32U2
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF0", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
### ATmega16U4
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF3", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
### ATmega32U4
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF4", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
### AT90USB64
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FF9", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
### AT90USB128
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="2FFB", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
|
||||
# Input Club
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1C11", ATTRS{idProduct}=="B007", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
|
||||
# STM32duino
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1EAF", ATTRS{idProduct}=="0003", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
# STM32 DFU
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="DF11", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
|
||||
# BootloadHID
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16C0", ATTRS{idProduct}=="05DF", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
|
||||
# USBAspLoader
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16C0", ATTRS{idProduct}=="05DC", TAG+="uaccess", RUN{builtin}+="uaccess"
|
||||
|
||||
# ModemManager should ignore the following devices
|
||||
# Atmel SAM-BA (Massdrop)
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="03EB", ATTRS{idProduct}=="6124", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
|
||||
# Caterina (Pro Micro)
|
||||
## Spark Fun Electronics
|
||||
### Pro Micro 3V3/8MHz
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9203", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### Pro Micro 5V/16MHz
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9205", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### LilyPad 3V3/8MHz (and some Pro Micro clones)
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1B4F", ATTRS{idProduct}=="9207", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
## Pololu Electronics
|
||||
### A-Star 32U4
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1FFB", ATTRS{idProduct}=="0101", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
## Arduino SA
|
||||
### Leonardo
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0036", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### Micro
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="0037", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
## Adafruit Industries LLC
|
||||
### Feather 32U4
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000C", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### ItsyBitsy 32U4 3V3/8MHz
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000D", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### ItsyBitsy 32U4 5V/16MHz
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="239A", ATTRS{idProduct}=="000E", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
## dog hunter AG
|
||||
### Leonardo
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2A03", ATTRS{idProduct}=="0036", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
### Micro
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2A03", ATTRS{idProduct}=="0037", TAG+="uaccess", RUN{builtin}+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
```
|
||||
Linux では、ブートローダデバイスと通信するには適切な権限が必要です。ファームウェアを書き込む時に `sudo` を使うか(非推奨)、`/etc/udev/rules.d/` に[このファイル](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules)を配置することで、通信することができます。
|
||||
|
||||
追加が完了したら、以下を実行します:
|
||||
|
||||
@@ -129,9 +65,9 @@ https://github.com/tmk/tmk_keyboard/issues/150
|
||||
- https://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1
|
||||
|
||||
### キーボードに書き込んだが何も起こらない、あるいはキーの押下が登録されない - ARM (rev6 planck、clueboard 60、hs60v2 など) でも同じ (Feb 2019)
|
||||
ARM ベースのチップ上での EEPROM の動作によって、保存された設定が無効になる場合があります。これはデフォルトレイヤに影響し、まだ調査中の特定の環境下でキーボードが使えなくなる*しれません*。EEPROM のリセットでこれが修正されます。
|
||||
ARM ベースのチップ上での EEPROM の動作によって、保存された設定が無効になる場合があります。これはデフォルトレイヤに影響し、まだ調査中の特定の環境下でキーボードが使えなくなるかも*しれません*。EEPROM のリセットでこれが修正されます。
|
||||
|
||||
[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) を使って eeprom のリセットを強制することができます。このイメージを書き込んだ後で、通常のファームウェアを書き込むと、キーボードが_通常_ の動作順序に復元されます。
|
||||
[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) を使って eeprom のリセットを強制することができます。このイメージを書き込んだ後で、通常のファームウェアを書き込むと、キーボードが _通常_ の動作順序に復元されます。
|
||||
[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin)
|
||||
|
||||
いずれかの形式でブートマジックが有効になっている場合は、これも実行できるはずです (実行方法の詳細については、[ブートマジックドキュメント](ja/feature_bootmagic.md)とキーボード情報を見てください)。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# 触覚フィードバック
|
||||
|
||||
<!---
|
||||
original document: 0.8.123:docs/feature_haptic_feedback.md
|
||||
git diff 0.8.123 HEAD -- docs/feature_haptic_feedback.md | cat
|
||||
original document: 0.12.41:docs/feature_haptic_feedback.md
|
||||
git diff 0.12.41 HEAD -- docs/feature_haptic_feedback.md | cat
|
||||
-->
|
||||
|
||||
## 触覚フィードバック の rules.mk オプション
|
||||
@@ -31,7 +31,7 @@
|
||||
| `HPT_TOG` | 触覚フィードバックのオン/オフを切り替え |
|
||||
| `HPT_RST` | 触覚フィードバック設定をデフォルトに戻す |
|
||||
| `HPT_FBK` | キー押下またはリリースまたはその両方でフィードバックを切り替え |
|
||||
| `HPT_BUZ` | ソレノイドの振動のオン/オフを切り替え |
|
||||
| `HPT_BUZ` | ソレノイドのブザー音のオン/オフを切り替え |
|
||||
| `HPT_MODI` | 次の DRV2605L 波形に移動 |
|
||||
| `HPT_MODD` | 前の DRV2605L 波形に移動 |
|
||||
| `HPT_CONT` | 連続触覚モードのオン/オフを切り替え |
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
ほとんどの MCU はソレノイドのコイルを駆動するために必要な電流を供給できないため、最初に MOSFET を介してソレノイドを駆動する回路を構築する必要があります。
|
||||
|
||||
[Adafruit が提供する配線図](https://playground.arduino.cc/uploads/Learning/solenoid_driver.pdf)
|
||||
[Adafruit が提供する配線図](https://cdn-shop.adafruit.com/product-files/412/412_solenoid_driver.pdf)
|
||||
|
||||
|
||||
| 設定 | デフォルト | 説明 |
|
||||
@@ -53,8 +53,15 @@
|
||||
| `SOLENOID_DEFAULT_DWELL` | `12` ms | ソレノイドのデフォルトの滞留時間を設定する。 |
|
||||
| `SOLENOID_MIN_DWELL` | `4` ms | 滞留時間の下限を設定する。 |
|
||||
| `SOLENOID_MAX_DWELL` | `100` ms | 滞留時間の上限を設定する。 |
|
||||
| `SOLENOID_DWELL_STEP_SIZE` | `1` ms | `HPT_DWL*` キーコードが送信される時に使われるステップサイズ |
|
||||
| `SOLENOID_DEFAULT_BUZZ` | `0` (無効) | HPT_RST では、この値が "1" の場合、ブザー音が "on" に設定されます |
|
||||
| `SOLENOID_BUZZ_ACTUATED` | `SOLENOID_MIN_DWELL` | ソレノイドがブザー音モードの場合の動作時間 |
|
||||
| `SOLENOID_BUZZ_NONACTUATED` | `SOLENOID_MIN_DWELL` | ソレノイドがブザー音モードの場合の非動作時間 |
|
||||
|
||||
?> 滞留時間とは、「プランジャー」が作動したままになる時間です。滞留時間により、ソレノイドの音が変わります。
|
||||
* ソレノイドのブザー音がオフの場合、滞留時間は「プランジャー」が作動したままになる時間です。滞留時間により、ソレノイドの音が変わります。
|
||||
* ソレノイドのブザー音がオンの場合、滞留時間は振動の長さを設定しますが、`SOLENOID_BUZZ_ACTUATED` と `SOLENOID_BUZZ_NONACTUATED` はブザー音の間の(非)動作時間を設定します。
|
||||
* 現在の実装では、上記の時間設定のいずれについても、設定の精度はキーボードがマトリックスをスキャンできる速度によって影響を受ける可能性があります。
|
||||
したがって、キーボードのスキャンルーチンが遅い場合は、`SOLENOID_DWELL_STEP_SIZE` をキーボードのスキャンに掛かる時間よりもわずかに小さい値に設定することをお勧めします。
|
||||
|
||||
ブートローダ実行中に一部のピンが給電されているかもしれず (例えば、STM32F303 チップ上の A13)、そうすると書き込みプロセスの間ずっとソレノイドがオン状態になることに注意してください。これはソレノイドを加熱し損傷を与えるかもしれません。ソレノイドが接続されているピンがブートローダ/DFU 実行中にソレノイドをオンにしていることが分かった場合は、他のピンを選択してください。
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# レイヤー :id=layers
|
||||
|
||||
<!---
|
||||
original document: 0.9.43:docs/feature_layers.md
|
||||
git diff 0.9.43 HEAD -- docs/feature_layers.md | cat
|
||||
original document: 0.12.41:docs/feature_layers.md
|
||||
git diff 0.12.41 HEAD -- docs/feature_layers.md | cat
|
||||
-->
|
||||
|
||||
QMK ファームウェアの最も強力で良く使われている機能の一つは、レイヤーを使う機能です。ほとんどの人にとって、これはラップトップやタブレットキーボードにあるのと同じように、様々なキーを可能にするファンクションキーに相当します。
|
||||
@@ -24,12 +24,10 @@ QMK ファームウェアの最も強力で良く使われている機能の一
|
||||
|
||||
### 注意事項 :id=caveats
|
||||
|
||||
現在のところ、`LT()` と `MT()` は[基本的なキーコードセット](ja/keycodes_basic.md)に制限されています。つまり、`LCTL()`、`KC_TILD` あるいは `0xFF` より大きなキーコードを使うことができません。特に、`LT` と `MT` のような二重の機能キーは16ビットキーコードを使います。4ビットは機能の識別のために使われ、次の12ビットはパラメータに分かれます。レイヤータップはレイヤーに4ビットを使います(実はレイヤータップがレイヤー 0-15 に制限されている理由です)。モッドタップも同じですが、識別子に4ビット、モッドのために4ビットが使われ、全体でキーコードに8ビットを使います。このため、使用されるキーコードは `0xFF` (0-255) に制限され、基本的なキーコードのみです。
|
||||
現在のところ、`LT()` の `layer` 引数はレイヤー 0-15 に制限され、`kc` 引数は[基本的なキーコードセット](ja/keycodes_basic.md)に制限されています。つまり、`LCTL()`、`KC_TILD` あるいは `0xFF` より大きなキーコードを使うことができません。これは、QMK が16ビットのキーコードを使うためです。4ビットは機能の識別のために使われ、4ビットはレイヤーのために使われ、キーコードには8ビットしか残されていません。
|
||||
|
||||
これを拡張してもせいぜい複雑になるだけでしょう。32ビットキーコードに移行すると、これの多くが解決されますが、キーマップマトリックスが使用する領域が2倍になります。また、問題が起きる可能性もあります。タップしたキーコードにモディファイアを適用する必要がある場合は、[タップダンス](ja/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys)を使うことができます。
|
||||
|
||||
さらに、モッドタップあるいはレイヤータップで少なくとも1つの右手用のモディファイアが指定された場合、指定された全てのモディファイアが右手用になるため、2つをうまく組み合わせて一致させることはできません。
|
||||
|
||||
## レイヤーとの連携 :id=working-with-layers
|
||||
|
||||
レイヤーを切り替える時は注意してください。(キーボードを取り外さずに)そのレイヤーを非アクティブにすることができずレイヤーから移動できなくなる可能性があります。最も一般的な問題を避けるためのガイドラインを作成しました。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# ポインティングデバイス :id=pointing-device
|
||||
|
||||
<!---
|
||||
original document: 0.9.43:docs/feature_pointing_device.md
|
||||
git diff 0.9.43 HEAD -- docs/feature_pointing_device.md | cat
|
||||
original document: 0.12.41:docs/feature_pointing_device.md
|
||||
git diff 0.12.41 HEAD -- docs/feature_pointing_device.md | cat
|
||||
-->
|
||||
|
||||
ポインティングデバイスは汎用的な機能の総称です: システムポインタを移動します。マウスキーのような他のオプションも確かにありますが、これは簡単に変更可能で軽量であることを目指しています。機能を制御するためにカスタムキーを実装したり、他の周辺機器から情報を収集してここに直接挿入したりできます - QMK に処理を任せてください。
|
||||
@@ -24,7 +24,7 @@ report_mouse_t (ここでは "mouseReport") が以下のプロパティを持つ
|
||||
* `mouseReport.y` - これは、y軸の動き(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。
|
||||
* `mouseReport.v` - これは、垂直スクロール(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。
|
||||
* `mouseReport.h` - これは、水平スクロール(+ 右へ、- 左へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。
|
||||
* `mouseReport.buttons` - これは uint8_t で、上位の5ビットを使っています。これらのビットはマウスボタンの状態を表します - ビット 3 はマウスボタン 5、ビット 7 はマウスボタン 1 です。
|
||||
* `mouseReport.buttons` - これは uint8_t で、8ビット全てを使っています。これらのビットはマウスボタンの状態を表します - ビット 0 はマウスボタン 1、ビット 7 はマウスボタン 8 です。
|
||||
|
||||
マウスレポートに必要な変更を行ったら、それを送信する必要があります:
|
||||
|
||||
@@ -32,6 +32,10 @@ report_mouse_t (ここでは "mouseReport") が以下のプロパティを持つ
|
||||
|
||||
マウスレポートが送信されると、x、y、v、h のいずれの値も 0 に設定されます (これは `pointing_device_send()` で行われます。この挙動を回避するためにオーバーライドすることができます)。このように、ボタンの状態は持続しますが、動きは1度だけ起こります。さらにカスタマイズするために、`pointing_device_init` と `pointing_device_task` のどちらもオーバーライドすることができます。
|
||||
|
||||
さらに、デフォルトでは、`pointing_device_send()` はレポートが実際に変更された場合のみレポートを送信します。これにより、マウスレポートが継続的に送信されてホストシステムが起動されたままになることを防ぎます。この動作は、独自の `pointing_device_send()` 関数を作成することで変更できます。
|
||||
|
||||
また、`has_mouse_report_changed(new, old)` 関数を使って、レポートが変更されたかどうかを確認できます。(訳注:独自の `pointing_device_send()` 関数を作成する場合でも、その中で `has_mouse_report_changed(new, old)` 関数でチェックして、デフォルトの `pointing_device_send()` と類似の無駄なレポートの抑制をして、ホストシステムがスリープ状態に入れる余地を残すようにしておくのが良いでしょう。)
|
||||
|
||||
以下の例では、カスタムキーを使ってマウスをクリックし垂直および水平方向に127単位スクロールし、リリースされた時にそれを全て元に戻します - なぜならこれは完全に便利な機能だからです。いいですか、以下はひとつの例です:
|
||||
|
||||
```c
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Raw HID
|
||||
|
||||
<!---
|
||||
original document: 0.10.47:docs/feature_rawhid.md
|
||||
git diff 0.10.47 HEAD -- docs/feature_rawhid.md | cat
|
||||
original document: 0.12.41:docs/feature_rawhid.md
|
||||
git diff 0.12.41 HEAD -- docs/feature_rawhid.md | cat
|
||||
-->
|
||||
|
||||
Raw HID は、HID インタフェースを介して QMK とホストコンピュータ間の双方向通信を可能にします。これには、キーマップをその場で切り替えたり、RGB LED の色とモードを変更したりなど、多くの潜在的な使用方法があります。
|
||||
@@ -34,7 +34,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
|
||||
}
|
||||
```
|
||||
|
||||
`raw_hid_receive` はホストから最大長 `RAW_EPSIZE` の可変サイズのパケットを受信することができます。一方、`raw_hid_send` はパケットを厳密に `RAW_EPSIZE` の長さで送信するため、長さ `RAW_EPSIZE` のデータを使う必要があります。
|
||||
これら2つの関数は、ホストとの間で長さ `RAW_EPSIZE` バイトのパケットを送受信します (LUFA/ChibiOS/V-USB では 32、ATSAM では 64)。
|
||||
|
||||
ホスト側での作業を進める前に、raw 対応のファームウェアを書き込むようにしてください。
|
||||
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# Docker クイックスタート
|
||||
|
||||
<!---
|
||||
original document: 0.9.32:docs/getting_started_docker.md
|
||||
git diff 0.9.32 HEAD -- docs/getting_started_docker.md | cat
|
||||
original document: 0.12.43:docs/getting_started_docker.md
|
||||
git diff 0.12.43 HEAD -- docs/getting_started_docker.md | cat
|
||||
-->
|
||||
|
||||
このプロジェクトは、プライマリオペレーティングシステムに大きな変更を加えることなくキーボードの新しいファームウェアを非常に簡単に構築することができる Docker ワークフローを含みます。これは、あなたがプロジェクトをクローンしビルドを実行した時に、他の人とまったく同じ環境と QMK ビルド基盤を持つことも保証します。これにより、人々はあなたが遭遇した問題の解決をより簡単に行えるようになります。
|
||||
|
||||
## 必要事項
|
||||
|
||||
主な前提条件は動作する `docker` がインストールされていることです。
|
||||
主な前提条件は動作する `docker` または `podman` がインストールされていることです。
|
||||
* [Docker CE](https://docs.docker.com/install/#supported-platforms)
|
||||
* [Podman](https://podman.io/getting-started/installation)
|
||||
|
||||
## 使い方
|
||||
|
||||
@@ -29,7 +30,7 @@ util/docker_build.sh <keyboard>:<keymap>
|
||||
|
||||
これは目的のキーボード/キーマップをコンパイルし、結果として書き込み用に `.hex` あるいは `.bin` ファイルを QMK ディレクトリの中に残します。`:keymap` が省略された場合は全てのキーマップが使われます。パラメータの形式は、`make` を使ってビルドする時と同じであることに注意してください。
|
||||
|
||||
`target` を指定して Docker から直接キーボードをビルドし、_かつ_書き込むためのサポートもあります。
|
||||
`target` を指定して Docker から直接キーボードをビルドし、_かつ_ 書き込むためのサポートもあります。
|
||||
|
||||
```bash
|
||||
util/docker_build.sh keyboard:keymap:target
|
||||
@@ -43,10 +44,17 @@ util/docker_build.sh
|
||||
# パラメータを入力として読み込みます (空白にすると全てのキーボード/キーマップ)
|
||||
```
|
||||
|
||||
`RUNTIME` 環境変数にコンテナランタイム名やパスを設定することで、使用したいコンテナランタイムを手動で設定できます。
|
||||
デフォルトでは docker や podman は自動的に検出され、podman より docker が優先されます。
|
||||
|
||||
```bash
|
||||
RUNTIME="podman" util/docker_build.sh keyboard:keymap:target
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### なぜ Windows/macOS 上で書き込めないのですか?
|
||||
|
||||
Windows と macOS では、実行するために [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) が必要です。これはセットアップが面倒なので、お勧めではありません: 代わりに [QMK Toolbox](https://github.com/qmk/qmk_toolbox) を使ってください。
|
||||
|
||||
!> Docker for Windows は[Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) を有効にする必要があります。これは、Windows 7、Windows 8 および **Windows 10 Home** のような Hyper-V を搭載していない Windows のバージョンでは機能しないことを意味します。
|
||||
!> Docker for Windows は [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) を有効にする必要があります。これは、Windows 7、Windows 8 および **Windows 10 Home** のような Hyper-V を搭載していない Windows のバージョンでは機能しないことを意味します。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# QMK で GitHub を使う方法
|
||||
|
||||
<!---
|
||||
original document: 0.9.43:docs/getting_started_github.md
|
||||
git diff 0.9.43 HEAD -- docs/getting_started_github.md | cat
|
||||
original document: 0.12.43:docs/getting_started_github.md
|
||||
git diff 0.12.43 HEAD -- docs/getting_started_github.md | cat
|
||||
-->
|
||||
|
||||
GitHub は慣れていない人には少し注意が必要です - このガイドは、QMK におけるフォーク、クローン、プルリクエストのサブミットの各ステップについて説明します。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# より詳細な `make` 手順
|
||||
|
||||
<!---
|
||||
original document: 0.10.33:docs/getting_started_make_guide.md
|
||||
git diff 0.10.33 HEAD -- docs/getting_started_make_guide.md | cat
|
||||
original document: 0.12.43:docs/getting_started_make_guide.md
|
||||
git diff 0.12.43 HEAD -- docs/getting_started_make_guide.md | cat
|
||||
-->
|
||||
|
||||
`make` コマンドの完全な構文は `<keyboard_folder>:<keymap>:<target>` です:
|
||||
@@ -19,16 +19,32 @@
|
||||
`<target>` は以下を意味します
|
||||
* target が指定されない場合は、以下の `all` と同じです
|
||||
* `all` は指定されたキーボード/リビジョン/キーマップの可能な全ての組み合わせのコンパイルを行います。例えば、`make planck/rev4:default` は1つの .hex を生成しますが、`make planck/rev4:all` は planck で利用可能な全てのキーマップについて hex を生成します。
|
||||
* `flash`、`dfu`、`teensy`、`avrdude`、`dfu-util` または `bootloadHID` はファームウェアをコンパイルし、キーボードにアップロードします。コンパイルが失敗すると、何もアップロードされません。使用するプログラマはキーボードに依存します。ほとんどのキーボードでは `dfu` ですが、ChibiOS キーボードについては `dfu-util` 、標準的な Teensy については `teensy` を使います。キーボードに使うコマンドを見つけるには、キーボード固有の readme をチェックしてください。
|
||||
* **注意**: 一部のオペレーティングシステムではこれらのコマンドが機能するためには root アクセスが必要です。その場合、例えば `sudo make planck/rev4:default:flash` を実行する必要があります。
|
||||
* `flash`、`dfu`、`teensy`、`avrdude`、`dfu-util`、`bootloadHID` はファームウェアをコンパイルし、キーボードにアップロードします。コンパイルが失敗すると、何もアップロードされません。使用するプログラマはキーボードに依存します。ほとんどのキーボードでは `dfu` ですが、ChibiOS キーボードについては `dfu-util` 、標準的な Teensy については `teensy` を使います。キーボードに使うコマンドを見つけるには、キーボード固有の readme をチェックしてください。
|
||||
利用可能なブートローダの詳細は[ファームウェアの書き込み](ja/flashing.md)ガイドを参照してください。
|
||||
* **Note**: 一部のオペレーティングシステムでは、これらのコマンドが機能するためには特権アクセスが必要です。これは、root アクセスなしでこれらにアクセスするために [`udev ルール`](ja/faq_build.md#linux-udev-rules) を設定するか、あるいは root アクセスでコマンドを実行する (`sudo make planck/rev4:default:flash`) 必要があるかもしれないことを意味します。
|
||||
* `clean` は、全てをゼロからビルドするためにビルド出力フォルダを掃除します。説明できない問題がある場合は、通常のコンパイルの前にこれを実行してください。
|
||||
* `distclean` は、.hex ファイルと .bin ファイルを削除します。
|
||||
|
||||
次のターゲットは開発者向けです:
|
||||
|
||||
* `show_path` ソースとオブジェクトファイルのパスを表示します。
|
||||
* `dump_vars` makefile 変数をダンプします。
|
||||
* `objs-size` 個々のオブジェクトファイルのサイズを表示します。
|
||||
* `show_build_options` 'rules.mk' のオプションセットを表示します。
|
||||
* `check-md5` 生成されたバイナリファイルの md5 チェックサムを表示します。
|
||||
|
||||
make コマンドの最後、つまり target の後に追加のオプションを追加することもできます
|
||||
|
||||
* `make COLOR=false` - カラー出力をオフ
|
||||
* `make SILENT=true` - エラー/警告以外の出力をオフ
|
||||
* `make VERBOSE=true` - 全ての gcc のものを出力 (デバッグする必要が無い限り面白くありません)
|
||||
* `make EXTRAFLAGS=-E` - コンパイルせずにコードを前処理 (#define コマンドをデバッグしようとする場合に便利)
|
||||
* `make VERBOSE_LD_CMD=yes` - -v オプションを指定して ld コマンドを実行します。
|
||||
* `make VERBOSE_AS_CMD=yes` - -v オプションを指定して as コマンドを実行します。
|
||||
* `make VERBOSE_C_CMD=<c_source_file>` - 指定された C ソースファイルをコンパイルするときに -v オプションを追加します。
|
||||
* `make DUMP_C_MACROS=<c_source_file>` - 指定された C ソースファイルをコンパイルするときにプリプロセッサマクロをダンプします。
|
||||
* `make DUMP_C_MACROS=<c_source_file> > <logfile>` - 指定された C ソースファイルをコンパイルするときにプリプロセッサマクロを `<logfile>` にダンプします。
|
||||
* `make VERBOSE_C_INCLUDE=<c_source_file>` - 指定された C ソースファイルをコンパイルするときにインクルードされるファイル名をダンプします。
|
||||
* `make VERBOSE_C_INCLUDE=<c_source_file> 2> <logfile>` - 指定された C ソースファイルをコンパイルするときにインクルードされるファイル名を `<logfile>` にダンプします。
|
||||
|
||||
make コマンド自体にもいくつかの追加オプションがあります。詳細は `make --help` を入力してください。最も有用なのはおそらく `-jx` です。これは複数の CPU を使ってコンパイルしたいことを指定し、`x` は使用したい CPU の数を表します。設定すると、特に多くのキーボード/キーマップをコンパイルしている場合は、コンパイル時間を大幅に短縮することができます。通常は、コンパイル中に他の作業を行うための余裕をもたせるために、持っている CPU の数より1つ少ない値に設定します。全てのオペレーティングシステムと make バージョンがオプションをサポートしているわけではないことに注意してください。
|
||||
|
||||
@@ -104,7 +120,7 @@ make コマンド自体にもいくつかの追加オプションがあります
|
||||
|
||||
これにより、送信したい文字に対応するニーモニックを入力することで Unicode 文字を送信することができます。キーマップファイル内にマッピングテーブルを保持する必要があります。可能な全てのコードポイント( `0x10FFFF` まで)がサポートされます。
|
||||
|
||||
詳細と制限については、[Unicode ページ](ja/feature_unicode.md) を見てください。
|
||||
詳細と制限については、[Unicode ページ](ja/feature_unicode.md)を見てください。
|
||||
|
||||
`AUDIO_ENABLE`
|
||||
|
||||
@@ -116,11 +132,11 @@ C6 ピン(抽象化が必要)でオーディオ出力できます。詳細は[
|
||||
|
||||
`API_SYSEX_ENABLE`
|
||||
|
||||
これにより Quantum SYSEX API を使って文字列を送信することができます (どこに?)
|
||||
これにより Quantum SYSEX API を使って文字列を(どこかに?)送信することができます
|
||||
|
||||
`KEY_LOCK_ENABLE`
|
||||
|
||||
これは [キーロック](ja/feature_key_lock.md) を有効にします。
|
||||
これは[キーロック](ja/feature_key_lock.md)を有効にします。
|
||||
|
||||
`SPLIT_KEYBOARD`
|
||||
|
||||
@@ -132,7 +148,7 @@ ARM ベースの分割キーボード用の標準分割通信ドライバはま
|
||||
|
||||
`CUSTOM_MATRIX`
|
||||
|
||||
デフォルトのマトリックス走査ルーチンを独自のコードで置き換えます。詳細については、[カスタムマトリックスページ](ja/custom_matrix.md) を見てください。
|
||||
デフォルトのマトリックス走査ルーチンを独自のコードで置き換えます。詳細については、[カスタムマトリックスページ](ja/custom_matrix.md)を見てください。
|
||||
|
||||
`DEBOUNCE_TYPE`
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Vagrant クイックスタート
|
||||
|
||||
<!---
|
||||
original document: 0.9.10:docs/getting_started_vagrant.md
|
||||
git diff 0.9.10 HEAD -- docs/getting_started_vagrant.md | cat
|
||||
original document: 0.12.43:docs/getting_started_vagrant.md
|
||||
git diff 0.12.43 HEAD -- docs/getting_started_vagrant.md | cat
|
||||
-->
|
||||
|
||||
このプロジェクトは、プライマリオペレーティングシステムに大きな変更を加えることなくキーボードの新しいファームウェアを非常に簡単に構築することができる `Vagrantfile` を含みます。これは、あなたがプロジェクトをクローンしビルドを実行した時に、ビルドのために Vagrantfile を使っている他のユーザと全く同じ環境を持つことも保証します。これにより、人々はあなたが遭遇した問題の解決をより簡単に行えるようになります。
|
||||
@@ -12,16 +12,16 @@
|
||||
このリポジトリ内の `Vagrantfile` を使うには、[Vagrant](https://www.vagrantup.com/) およびサポートされるプロバイダがインストールされている必要があります:
|
||||
|
||||
* [VirtualBox](https://www.virtualbox.org/) (バージョン 5.0.12 以降)
|
||||
* 'Vagrant を使うために最もアクセスしやすいプラットフォーム' として販売
|
||||
* 「Vagrant を使うために最もアクセスしやすいプラットフォーム」とうたわれています。
|
||||
* [VMware Workstation](https://www.vmware.com/products/workstation) および [Vagrant VMware プラグイン](https://www.vagrantup.com/vmware)
|
||||
* (有料) VMware プラグインには、ライセンスされた VMware Workstation/Fusion のコピーが必要です。
|
||||
* [Docker](https://www.docker.com/)
|
||||
|
||||
Vagrant 以外に、適切なプロバイダがインストールされ、その後におそらくコンピュータを再起動すると、このプロジェクトをチェックアウトしたフォルダ内の任意の場所で 'vagrant up' を単純に実行することができ、このプロジェクトをビルドするのに必要な全てのツールが含まれる環境(仮想マシンあるいはコンテナ)が開始されます。Vagrant をうまく始めるためのヒントの投稿がありますが、それ以外に、以下のビルドドキュメントを参照することもできます。
|
||||
Vagrant 以外に、適切なプロバイダがインストールされ、その後におそらくコンピュータを再起動すると、このプロジェクトをチェックアウトしたフォルダ内の任意の場所で 'vagrant up' を単純に実行することができ、このプロジェクトをビルドするのに必要な全てのツールが含まれる環境(仮想マシンあるいはコンテナ)が開始されます。Vagrant 起動時にうまく始めるためのヒントが表示されますが、それ以外に、以下のビルドドキュメントを参照することもできます。
|
||||
|
||||
## ファームウェアの書き込み
|
||||
|
||||
ファームウェアを書き込む"簡単"な方法は、ホスト OS からツールを使うことです:
|
||||
ファームウェアを書き込む「簡単な」方法は、ホスト OS からツールを使うことです:
|
||||
|
||||
* [QMK Toolbox](https://github.com/qmk/qmk_toolbox) (推奨)
|
||||
* [Teensy ローダー](https://www.pjrc.com/teensy/loader.html)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.10.33:docs/hardware_avr.md
|
||||
git diff 0.10.33 HEAD -- docs/hardware_avr.md | cat
|
||||
original document: 0.12.41:docs/hardware_avr.md
|
||||
git diff 0.12.41 HEAD -- docs/hardware_avr.md | cat
|
||||
-->
|
||||
|
||||
このページでは QMK における AVR マイコンのサポートについて説明します。AVR マイコンには、Atmel 社製の atmega32u4、atmega32u2、at90usb1286 やその他のマイコンを含みます。AVR マイコンは、簡単に動かせるよう設計された8ビットの MCU です。キーボードでよく使用される AVR マイコンには USB 機能や大きなキーボードマトリックスのためのたくさんの GPIO を搭載しています。これらは、現在、キーボードで使われる最も一般的な MCU です。
|
||||
@@ -83,7 +83,7 @@ or open the directory in your favourite text editor.
|
||||
#define PRODUCT my_awesome_keyboard
|
||||
```
|
||||
|
||||
?> Windows や macOS では、`MANUFACTURER` と `PRODUCT` が USBデバイスのリストに表示されます。Linux 上の `lsusb` では、代わりにデフォルトで [USB ID Repository](http://www.linux-usb.org/usb-ids.html) によって維持されているリストからこれらを取得します。`lsusb -v` を使用するとデバイスから示された値を表示します。また、接続したときのカーネルログにも表示されます。
|
||||
?> Windows や macOS では、`MANUFACTURER` と `PRODUCT` が USBデバイスのリストに表示されます。Linux 上の `lsusb` では、代わりに [USB ID Repository](http://www.linux-usb.org/usb-ids.html) によって維持されているリストの値を優先します。デフォルトでは、リストに `VENDOR_ID` / `PRODUCT_ID` を含まない場合にのみ、`MANUFACTURER` と `PRODUCT` を使います。`sudo lsusb -v` を使用するとデバイスから示された値を表示します。また、接続したときのカーネルログにも表示されます。
|
||||
|
||||
### キーボードマトリックスの設定
|
||||
|
||||
|
||||
@@ -2,12 +2,31 @@
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.10.33:docs/hardware_keyboard_guidelines.md
|
||||
git diff 0.10.33 HEAD -- docs/hardware_keyboard_guidelines.md | cat
|
||||
original document: 0.12.41:docs/hardware_keyboard_guidelines.md
|
||||
git diff 0.12.41 HEAD -- docs/hardware_keyboard_guidelines.md | cat
|
||||
-->
|
||||
|
||||
QMK は開始以来、コミュニティにおけるキーボードの作成や保守に貢献しているあなたのような人たちのおかげで飛躍的に成長しました。私たちが成長するにつれて、うまくやるためのいくつかのパターンを発見しました。他の人たちがあなたの苦労の恩恵を受けやすくするため、それにあわせてもらえるようお願いします。
|
||||
|
||||
## QMK Lint を使う
|
||||
|
||||
キーボードの問題をチェックできるツール、`qmk lint` を提供しています。キーボードとキーマップで作業をしている間は、頻繁に使うことをお勧めします。
|
||||
|
||||
チェックに合格した例:
|
||||
|
||||
```
|
||||
$ qmk lint -kb rominronin/katana60/rev2
|
||||
Ψ Lint check passed!
|
||||
```
|
||||
|
||||
チェックに失敗した例:
|
||||
|
||||
```
|
||||
$ qmk lint -kb clueboard/66/rev3
|
||||
☒ Missing keyboards/clueboard/66/rev3/readme.md
|
||||
☒ Lint check failed!
|
||||
```
|
||||
|
||||
## あなたのキーボード/プロジェクトの名前を決める
|
||||
|
||||
キーボードの名前は全て小文字で、アルファベット、数字、アンダースコア(`_`)のみで構成されています。アンダースコア(`_`)で始めてはいけません。スラッシュ(`/`)はサブフォルダの区切り文字として使用されます。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# モッドタップ
|
||||
|
||||
<!---
|
||||
original document: 0.9.34:docs/mod_tap.md
|
||||
git diff 0.9.34 HEAD -- docs/mod_tap.md | cat
|
||||
original document: 0.10.36:docs/mod_tap.md
|
||||
git diff 0.10.36 HEAD -- docs/mod_tap.md | cat
|
||||
-->
|
||||
|
||||
モッドタップキー `MT(mod, kc)` は、押したままの時にモディファイアのように機能し、タップされた時に通常のキーのように振舞います。別の言い方をすると、タップした時に Escape を送信しますが、押したままの時に Control あるいは Shift キーとして機能するキーを持つことができます。
|
||||
@@ -32,23 +32,26 @@ MT(MOD_LCTL | MOD_LSFT, KC_ESC)
|
||||
|
||||
便利なように、QMK はキーマップで一般的な組み合わせをよりコンパクトにするためのモッドタップショートカットを含んでいます:
|
||||
|
||||
| キー | エイリアス | 説明 |
|
||||
|--------------|-----------------------------|-------------------------------------------------------------|
|
||||
| `LCTL_T(kc)` | `CTL_T(kc)` | 押したままの場合は左 Control、タップした場合は `kc` |
|
||||
| `LSFT_T(kc)` | `SFT_T(kc)` | 押したままの場合は左 Shift、タップした場合は `kc` |
|
||||
| `LALT_T(kc)` | `LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` | 押したままの場合は左 Alt、タップした場合は `kc` |
|
||||
| `LGUI_T(kc)` | `LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)` | 押したままの場合は左 GUI、タップした場合は `kc` |
|
||||
| `RCTL_T(kc)` | | 押したままの場合は右 Control、タップした場合は `kc` |
|
||||
| `RSFT_T(kc)` | | 押したままの場合は右 Shift、タップした場合は `kc` |
|
||||
| `RALT_T(kc)` | `ROPT_T(kc)`, `ALGR_T(kc)` | 押したままの場合は右 Alt、タップした場合は `kc` |
|
||||
| `RGUI_T(kc)` | `RCMD_T(kc)`, `RWIN_T(kc)` | 押したままの場合は右 GUI、タップした場合は `kc` |
|
||||
| `SGUI_T(kc)` | `SCMD_T(kc)`, `SWIN_T(kc)` | 押したままの場合は左 Shift と左 GUI、タップした場合は `kc` |
|
||||
| `LCA_T(kc)` | | 押したままの場合は左 Control と左 Alt、タップした場合は `kc` |
|
||||
| `LCAG_T(kc)` | | 押したままの場合は左 Control、左 Alt と左 GUI、タップした場合は `kc` |
|
||||
| `RCAG_T(kc)` | | 押したままの場合は右 Control、右 Alt と右 GUI、タップした場合は `kc` |
|
||||
| `C_S_T(kc)` | | 押したままの場合は左 Control と左 Shift、タップした場合は `kc` |
|
||||
| `MEH_T(kc)` | | 押したままの場合は左 Control、左 Shift と左 Alt、タップした場合は `kc` |
|
||||
| `HYPR_T(kc)` | `ALL_T(kc)` | 押したままの場合は左 Control、左 Shift、左 Alt と左 GUI、タップした場合は `kc` - より詳しくは[ここ](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)を見てください |
|
||||
| キー | エイリアス | 説明 |
|
||||
| ------------ | ----------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `LCTL_T(kc)` | `CTL_T(kc)` | 押したままの場合は左 Control、タップした場合は `kc` |
|
||||
| `LSFT_T(kc)` | `SFT_T(kc)` | 押したままの場合は左 Shift、タップした場合は `kc` |
|
||||
| `LALT_T(kc)` | `LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` | 押したままの場合は左 Alt、タップした場合は `kc` |
|
||||
| `LGUI_T(kc)` | `LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)` | 押したままの場合は左 GUI、タップした場合は `kc` |
|
||||
| `RCTL_T(kc)` | | 押したままの場合は右 Control、タップした場合は `kc` |
|
||||
| `RSFT_T(kc)` | | 押したままの場合は右 Shift、タップした場合は `kc` |
|
||||
| `RALT_T(kc)` | `ROPT_T(kc)`, `ALGR_T(kc)` | 押したままの場合は右 Alt、タップした場合は `kc` |
|
||||
| `RGUI_T(kc)` | `RCMD_T(kc)`, `RWIN_T(kc)` | 押したままの場合は右 GUI、タップした場合は `kc` |
|
||||
| `SGUI_T(kc)` | `SCMD_T(kc)`, `SWIN_T(kc)` | 押したままの場合は左 Shift と左 GUI、タップした場合は `kc` |
|
||||
| `LCA_T(kc)` | | 押したままの場合は左 Control と左 Alt、タップした場合は `kc` |
|
||||
| `LSA_T(kc)` | | 押したままの場合は左 Shift と Alt、タップした場合は `kc` |
|
||||
| `RSA_T(kc)` | `SAGR_T(kc)` | 押したままの場合は右 Shift と Alt (AltGr)、タップした場合は `kc` |
|
||||
| `RCS_T(kc)` | | 押したままの場合は右 Control と Shift、タップした場合は `kc` |
|
||||
| `LCAG_T(kc)` | | 押したままの場合は左 Control、左 Alt と左 GUI、タップした場合は `kc` |
|
||||
| `RCAG_T(kc)` | | 押したままの場合は右 Control、右 Alt と右 GUI、タップした場合は `kc` |
|
||||
| `C_S_T(kc)` | | 押したままの場合は左 Control と左 Shift、タップした場合は `kc` |
|
||||
| `MEH_T(kc)` | | 押したままの場合は左 Control、左 Shift と左 Alt、タップした場合は `kc` |
|
||||
| `HYPR_T(kc)` | `ALL_T(kc)` | 押したままの場合は左 Control、左 Shift、左 Alt と左 GUI、タップした場合は `kc` - より詳しくは[ここ](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)を見てください |
|
||||
|
||||
## 注意事項
|
||||
|
||||
@@ -57,3 +60,7 @@ MT(MOD_LCTL | MOD_LSFT, KC_ESC)
|
||||
さらに、Windows でリモートデスクトップ接続を使う場合に、問題が発生する場合があります。これらのコードはシフトを非常に高速に送信するため、リモートデスクトップはコードを見逃すかもしれません。
|
||||
|
||||
これを修正するには、リモートデスクトップ接続を開き、「オプションの表示」を開き、「ローカル リソース」タブを開きます。キーボードセクションで、ドロップダウンを「このコンピューター」に変更します。これにより問題が修正され、キャラクタが正しく動作するようになります。
|
||||
|
||||
## 他のリソース
|
||||
|
||||
モッドタップの動作を調整する追加フラグについては、[タップホールド設定オプション](ja/tap_hold.md)を参照してください。
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# QMK 初心者ガイド
|
||||
# QMK チュートリアル
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.9.0:docs/newbs.md
|
||||
git diff 0.9.0 HEAD -- docs/newbs.md | cat
|
||||
original document: 0.12.45:docs/newbs.md
|
||||
git diff 0.12.45 HEAD -- docs/newbs.md | cat
|
||||
-->
|
||||
|
||||
キーボードには、コンピュータ入っているものと似たようなプロセッサが入っています。
|
||||
@@ -19,20 +19,16 @@ QMK は、簡単なことは簡単に、そして、難しいことを可能な
|
||||
QMK は[多くの趣味のキーボード](https://qmk.fm/keyboards/)をサポートしています。
|
||||
現在使用しているキーボードが QMK を実行できない場合、QMK を実行できるキーボードの選択肢はたくさんあります。
|
||||
|
||||
## このガイドは私のためにあるのでしょうか?
|
||||
|
||||
このガイドは、ソースコードを使ってキーボードのファームウェアを構築したいと考えている人に適しています。
|
||||
もしあなたがすでにプログラマーであれば、このプロセスはとても身近で簡単に理解できるでしょう。
|
||||
もし、プログラミングの考え方に抵抗があるのであれば、代わりに[私たちのオンラインGUI](ja/newbs_building_firmware_configurator.md)を見てみてください。
|
||||
?> **このガイドは私のためにあるのでしょうか?**<br>
|
||||
もし、プログラミングの考え方に抵抗があるのであれば、代わりに[私たちのオンライン GUI](ja/newbs_building_firmware_configurator.md) を見てみてください。
|
||||
|
||||
## 概要
|
||||
|
||||
このガイドには4つの主要なセクションがあります。
|
||||
このガイドは、ソースコードを使ってキーボードのファームウェアを構築したいと考えている人に適しています。 もしあなたがすでにプログラマーであれば、このプロセスはとても身近で簡単に理解できるでしょう。このガイドには3つの主要なセクションがあります:
|
||||
|
||||
1. [環境設定](ja/newbs_getting_started.md)
|
||||
2. [コマンドラインを使用して初めてのファームウェアを構築する](ja/newbs_building_firmware.md)
|
||||
3. [ファームウェアを書きこむ](ja/newbs_flashing.md)
|
||||
4. [テストとデバッグ](ja/newbs_testing_debugging.md)
|
||||
|
||||
このガイドは、これまでソフトウェアをコンパイルしたことがない人を支援することに特化しています。
|
||||
その観点から選択と推奨を行います。
|
||||
@@ -41,8 +37,4 @@ QMK は[多くの趣味のキーボード](https://qmk.fm/keyboards/)をサポ
|
||||
|
||||
## 追加のリソース
|
||||
|
||||
このガイドの他にも、QMK の学習に役立つリソースがいくつかあります。[学習リソース](ja/newbs_learn_more_resources.md)のページにまとめました。
|
||||
|
||||
## オープンソース
|
||||
|
||||
QMKは GNU General Public License でリリースされているオープンソース・ソフトウェアです。
|
||||
このガイドの他にも、QMK の学習に役立つリソースがいくつかあります。[シラバス](ja/syllabus.md)と[学習リソース](ja/newbs_learn_more_resources.md)のページにまとめました。
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.9.0:docs/newbs_building_firmware_configurator.md
|
||||
git diff 0.9.0 HEAD -- docs/newbs_building_firmware_configurator.md | cat
|
||||
original document: 0.12.45:docs/newbs_building_firmware_configurator.md
|
||||
git diff 0.12.45 HEAD -- docs/newbs_building_firmware_configurator.md | cat
|
||||
-->
|
||||
|
||||
[](https://config.qmk.fm/)
|
||||
|
||||
[QMK Configurator](https://config.qmk.fm) は、QMKファームウェアの hex ファイルを生成するオンライングラフィカルユーザーインターフェイスです。
|
||||
[QMK Configurator](https://config.qmk.fm) は、QMKファームウェアの `.hex` や `.bin` ファイルを生成するオンライングラフィカルユーザーインターフェイスです。
|
||||
|
||||
[ビデオチュートリアル](https://www.youtube.com/watch?v=-imgglzDMdY) を見てください。
|
||||
多くの人は、それが自分のキーボードのプログラミングを始めるのに十分な情報であることに気づくでしょう。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# ファームウェアを書きこむ
|
||||
# ファームウェアを書き込む
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.9.44:docs/newbs_flashing.md
|
||||
git diff 0.9.44 HEAD -- docs/newbs_flashing.md | cat
|
||||
original document: 0.12.45:docs/newbs_flashing.md
|
||||
git diff 0.12.45 HEAD -- docs/newbs_flashing.md | cat
|
||||
-->
|
||||
|
||||
カスタムファームウェアは出来たので、キーボードに書き込みたくなるでしょう/フラッシュしたくなるでしょう。
|
||||
カスタムファームウェアは出来たので、いよいよキーボードへの書き込み(フラッシュ)です。
|
||||
|
||||
## キーボードを DFU (Bootloader) モードにする
|
||||
|
||||
@@ -50,18 +50,22 @@ Finder またはエクスプローラーでファームウェアのファイル
|
||||
|
||||
Windows か macOS を使用している場合、現在のフォルダをエクスプローラーか Finder で簡単に開くためのコマンドがあります。
|
||||
|
||||
#### Windows
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### ** Windows **
|
||||
|
||||
```
|
||||
start .
|
||||
```
|
||||
|
||||
#### macOS
|
||||
#### ** macOS **
|
||||
|
||||
```
|
||||
open .
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
ファームウェアファイルは常に以下の命名形式に従っています:
|
||||
|
||||
```
|
||||
@@ -117,11 +121,13 @@ QMK Toolbox の `Flash` ボタンをクリックします。次のような出
|
||||
|
||||
WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time.
|
||||
|
||||
この場合、あなたは明示的にブートローダを指定する方法を使わなければなりません。詳細は、[ファームウェアのフラッシュ](ja/flashing.md) ガイドを参照してください。
|
||||
この場合、あなたは明示的にブートローダを指定する方法を使わなければなりません。詳細は、[ファームウェアのフラッシュ](ja/flashing.md)ガイドを参照してください。
|
||||
|
||||
## テストしましょう!
|
||||
|
||||
おめでとうございます! カスタムファームウェアがキーボードにプログラムされました!
|
||||
おめでとうございます!カスタムファームウェアがキーボードにプログラムされ、テストする準備ができました!
|
||||
|
||||
使ってみて、すべてがあなたの望むように動作するかどうか確認してください。
|
||||
この初心者ガイドを完全なものにするために [テストとデバッグ](ja/newbs_testing_debugging.md) を書いたので、ファームウェアの検証とカスタム機能のトラブルシューティング方法について学ぶには、こちらをご覧ください。
|
||||
少し運が良ければ全てが完璧に機能しますが、そうでない場合は何が問題なのかを理解するのに役立つ手順があります。
|
||||
通常、キーボードのテストは非常に簡単です。全てのキーをひとつずつ押して、期待するキーが送信されることを確認します。例え QMK で動作していない場合でも、[QMK Configurator](https://config.qmk.fm/#/test/) のテストモードを使用すると、キーボードをチェックできます。
|
||||
|
||||
まだ動作しませんか?詳細については FAQ トピックを参照するか、[Discord でチャット](https://discord.gg/Uq7gcHh)してください。
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
<!---
|
||||
grep --no-filename "^[ ]*git diff" docs/ja/*.md | sh
|
||||
original document: 0.9.0:docs/newbs_learn_more_resources.md
|
||||
git diff 0.9.0 HEAD -- docs/newbs_learn_more_resources.md | cat
|
||||
original document: 0.12.45:docs/newbs_learn_more_resources.md
|
||||
git diff 0.12.45 HEAD -- docs/newbs_learn_more_resources.md | cat
|
||||
-->
|
||||
|
||||
これらのリソースは、QMK コミュニティの新しいメンバーに、初心者向けドキュメントで提供されている情報に対する理解を深めることを目的としています。
|
||||
|
||||
## QMK に関するリソース:
|
||||
## QMK に関するリソース
|
||||
|
||||
### 英語 :id=english-resources-qmk
|
||||
|
||||
@@ -18,17 +18,35 @@
|
||||
|
||||
_日本語のリソース情報を募集中です。_
|
||||
|
||||
## コマンドラインに関するリソース:
|
||||
## コマンドラインに関するリソース :id=command-line-resources
|
||||
|
||||
### 英語 :id=english-resources-cli
|
||||
|
||||
* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line)
|
||||
* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)<br>
|
||||
* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html)
|
||||
|
||||
### 日本語 :id=japanese-resources-cli
|
||||
|
||||
_日本語のリソース情報を募集中です。_
|
||||
|
||||
## Git に関するリソース:
|
||||
## テキストエディタに関するリソース :id=text-editor-resources
|
||||
|
||||
どのテキストエディタを使えば良いか分かりませんか?
|
||||
|
||||
### 英語 :id=english-resources-text-editor
|
||||
|
||||
* [a great introduction to the subject](https://learntocodewith.me/programming/basics/text-editors/)
|
||||
|
||||
### 日本語 :id=japanese-resources-text-editor
|
||||
|
||||
_日本語のリソース情報を募集中です。_
|
||||
|
||||
コーディング用に特別に作成されたエディタ:
|
||||
* [Sublime Text](https://www.sublimetext.com/)
|
||||
* [VS Code](https://code.visualstudio.com/)
|
||||
|
||||
## Git に関するリソース
|
||||
|
||||
### 英語 :id=english-resources-git
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# ワンショットキー
|
||||
|
||||
<!---
|
||||
original document: 0.9.34:docs/one_shot_keys.md
|
||||
git diff 0.9.34 HEAD -- docs/one_shot_keys.md | cat
|
||||
original document: 0.12.41:docs/one_shot_keys.md
|
||||
git diff 0.12.41 HEAD -- docs/one_shot_keys.md | cat
|
||||
-->
|
||||
|
||||
ワンショットキーは次のキーが押されるまでアクティブのままになり、そのあと放されるキーです。これにより一度に1つ以上のキーを押すことなく、キーボードの組み合わせを入力することができます。これらのキーは通常「スティッキーキー」あるいは「デッドキー」と呼ばれます。
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
ワンショットレイヤーについては、キーを押した時に `set_oneshot_layer(LAYER, ONESHOT_START)` を呼び出し、キーを放した時に `clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED)` を呼び出す必要があります。ワンショットをキャンセルする場合は、`reset_oneshot_layer()` を呼び出してください。
|
||||
|
||||
ワンショットモッドについては、設定するためには `set_oneshot_mods(MOD)` を呼び出し、キャンセルするためには `clear_oneshot_mods()` を呼び出す必要があります。
|
||||
ワンショットモッドについては、設定するためには `set_oneshot_mods(MOD_BIT(KC_*))` を呼び出し、キャンセルするためには `clear_oneshot_mods()` を呼び出す必要があります。
|
||||
|
||||
!> リモートデスクトップ接続で OSM 変換に問題がある場合は、設定を開いて「ローカル リソース」タブに移動し、キーボードセクションでドロップダウンを「このコンピューター」に変更することで修正することができます。これにより問題が修正され、OSM がリモートデスクトップ上で適切に動作するようになります。
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# キーボードをより良くするための便利なコア関数のリスト
|
||||
|
||||
<!---
|
||||
original document: 0.10.33:docs/ref_functions.md
|
||||
git diff 0.10.33 HEAD -- docs/ref_functions.md | cat
|
||||
original document: 0.12.41:docs/ref_functions.md
|
||||
git diff 0.12.41 HEAD -- docs/ref_functions.md | cat
|
||||
-->
|
||||
|
||||
QMK には、信じられないほど便利な、またはあなたが望んでいた機能を少し追加する、隠された関数がたくさんあります。特定の機能に固有の関数はそれぞれの機能のページにあるため、ここには含まれていません。
|
||||
@@ -98,7 +98,7 @@ layer_state_t layer_state_set_user(layer_state_t state) {
|
||||
|
||||
## EEPROM (永続ストレージ)の消去
|
||||
|
||||
オーディオ、RGB アンダーグロー、バックライト、キーの動作に問題がある場合は、EEPROM (永続的な設定のストレージ)をリセットすることができます。ブートマジックはこれを行う方法の1つですが、有効になっていない場合はカスタムマクロを使って行うことができます。
|
||||
オーディオ、RGB アンダーグロー、バックライト、キーの動作に問題がある場合は、EEPROM (永続的な設定のストレージ)をリセットすることができます。EEPROM を強制的にリセットするには、[`EEP_RST` キーコード](ja/quantum_keycodes.md)あるいは[ブートマジック](ja/feature_bootmagic.md)機能を使います。それらのいずれも選択肢にない場合は、カスタムマクロを使って行うことができます。
|
||||
|
||||
EEPROM を消去するには、関数またはマクロから `eeconfig_init()` を実行し、ほとんどの設定をデフォルトにリセットします。
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# タップホールド設定オプション
|
||||
|
||||
<!---
|
||||
original document: 0.10.33:docs/tap_hold.md
|
||||
git diff 0.10.33 HEAD -- docs/tap_hold.md | cat
|
||||
original document: 0.12.41:docs/tap_hold.md
|
||||
git diff 0.12.41 HEAD -- docs/tap_hold.md | cat
|
||||
-->
|
||||
|
||||
タップホールドオプションは素晴らしいものですが、問題が無いわけではありません。デフォルト設定を適切なものにしようとしましたが、一部の人にとってまだ問題を引き起こすかもしれません。
|
||||
@@ -92,7 +92,7 @@ bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
|
||||
#define IGNORE_MOD_TAP_INTERRUPT
|
||||
```
|
||||
|
||||
許容ホールドと同様に、これは高速なタイピストのためのファームウェアの処理方法を変更します。モッドタップキーを押し、他のキーを押し、モッドタップキーを放し、通常のキーを放すと、通常は両方のキーのタッピング機能が出力されます。これはローリングコンボキーには望ましくないかもしれません。
|
||||
許容ホールドと同様に、これは高速なタイピストのためのファームウェアの処理方法を変更します。モッドタップキーを押し、他のキーを押し、モッドタップキーを放し、通常のキーを放すと、`TAPPING_TERM` 内で押された場合でも、通常はモッドと通常のキーが出力されます。これは、ローリングコンボキーや、頻繁に使用するキー(例えば、`RCTL_T(KC_QUOT)`)にモッドタップを使う高速なタイピストには望ましくない場合があります。
|
||||
|
||||
`モッドタップ割り込みの無視`を設定するには、両方のキーを `TAPPING_TERM` の間ホールドすると、(その修飾キーの)ホールド機能を実行する必要があります。
|
||||
|
||||
@@ -103,7 +103,7 @@ bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
|
||||
- `SFT_T(KC_A)` を放す
|
||||
- `KC_X` を放す
|
||||
|
||||
通常、これは `X` (`SHIFT`+`x`) を送信します。`モッドタップ割り込みの無視` を有効にすると、ホールドアクションを登録するには、両方のキーを `TAPPING_TERM` の間ホールドする必要があります。この場合、素早いタップは `ax` を送信しますが、両方をホールドすると、`X` (`SHIFT`+`x`) を出力します。
|
||||
通常、これは大文字の `X` (`SHIFT`+`x`)、またはモッド + キーを送信します。`モッドタップ割り込みの無視` を有効にすると、ホールドアクションを登録するには、両方のキーを `TAPPING_TERM` の間ホールドする必要があります。この場合、素早いタップは `ax` を送信しますが、両方をホールドすると、大文字の `X` (`SHIFT`+`x`) を出力します。
|
||||
|
||||
|
||||
?> __注意__: これはモディファイアにのみ関係し、レイヤー切り替えキーには関係しません。
|
||||
@@ -137,8 +137,7 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
|
||||
#define TAPPING_FORCE_HOLD
|
||||
```
|
||||
|
||||
タップの後でユーザがキーをホールドすると、ホールド機能がアクティブになるのではなく、デフォルトでタッピング機能が繰り返されます。これにより、デュアルロールキーのタッピング機能を自動繰り返しする機能を維持することができます。
|
||||
`TAPPING_FORCE_HOLD` は、デュアルロールキーをタップした後ホールドした場合、ユーザがホールド機能をアクティブにする機能を削除します。
|
||||
タップの後でユーザがキーをホールドすると、ホールド機能がアクティブになるのではなく、デフォルトでタッピング機能が繰り返されます。これにより、デュアルロールキーのタッピング機能を自動繰り返しする機能を維持することができます。`TAPPING_FORCE_HOLD` は、デュアルロールキーをタップした後ホールドした場合、ユーザがホールド機能をアクティブにする機能を削除します。
|
||||
|
||||
例:
|
||||
|
||||
@@ -185,6 +184,25 @@ bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
例えば、他のキーを押すことなく `LT(2, KC_SPACE)` を押したり放したりしても何も起こりません。これを有効にすると、代わりに `KC_SPACE` を送信します。
|
||||
|
||||
この機能をより細かく制御するために、以下を `config.h` に追加することができます:
|
||||
|
||||
```c
|
||||
#define RETRO_TAPPING_PER_KEY
|
||||
```
|
||||
|
||||
そして、以下の関数をキーマップに追加します:
|
||||
|
||||
```c
|
||||
bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case LT(2, KC_SPACE):
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## キー別の関数にキーレコードを含めるのはなぜですか?
|
||||
|
||||
「キー別」の関数全てにキーレコードを含んでいることに気付いたかもしれません。そしてなぜそうしたのか不思議に思っているかもしれません。
|
||||
|
||||
@@ -381,26 +381,29 @@ See also: [Mouse Keys](feature_mouse_keys.md)
|
||||
|
||||
See also: [Modifier Keys](feature_advanced_keycodes.md#modifier-keys)
|
||||
|
||||
|Key |Aliases |Description |
|
||||
|----------|-------------------------------|------------------------------------------------------|
|
||||
|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` |
|
||||
|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` |
|
||||
|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` |
|
||||
|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` |
|
||||
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|
||||
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
|
||||
|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt (AltGr) and press `kc` |
|
||||
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` |
|
||||
|`SGUI(kc)`|`SCMD(kc)`, `SWIN(kc)` |Hold Left Shift and GUI and press `kc` |
|
||||
|`LCA(kc)` | |Hold Left Control and Alt and press `kc` |
|
||||
|`LSA(kc)` | |Hold Left Shift and Left Alt and press `kc` |
|
||||
|`RSA(kc)` |`SAGR(kc)` |Hold Right Shift and Right Alt (AltGr) and press `kc` |
|
||||
|`RCS(kc)` | |Hold Right Control and Right Shift and press `kc` |
|
||||
|`LCAG(kc)`| |Hold Left Control, Alt and GUI and press `kc` |
|
||||
|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` |
|
||||
|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc` |
|
||||
|`KC_MEH` | |Left Control, Shift and Alt |
|
||||
|`KC_HYPR` | |Left Control, Shift, Alt and GUI |
|
||||
|Key |Aliases |Description |
|
||||
|----------|----------------------------------|------------------------------------------------------|
|
||||
|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` |
|
||||
|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` |
|
||||
|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` |
|
||||
|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)` |Hold Left GUI and press `kc` |
|
||||
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|
||||
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
|
||||
|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt (AltGr) and press `kc` |
|
||||
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` |
|
||||
|`LSG(kc)` |`SGUI(kc)`, `SCMD(kc)`, `SWIN(kc)`|Hold Left Shift and Left GUI and press `kc` |
|
||||
|`LAG(kc)` | |Hold Left Alt and Left GUI and press `kc` |
|
||||
|`RSG(kc)` | |Hold Right Shift and Right GUI and press `kc` |
|
||||
|`RAG(kc)` | |Hold Right Alt and Right GUI and press `kc` |
|
||||
|`LCA(kc)` | |Hold Left Control and Alt and press `kc` |
|
||||
|`LSA(kc)` | |Hold Left Shift and Left Alt and press `kc` |
|
||||
|`RSA(kc)` |`SAGR(kc)` |Hold Right Shift and Right Alt (AltGr) and press `kc` |
|
||||
|`RCS(kc)` | |Hold Right Control and Right Shift and press `kc` |
|
||||
|`LCAG(kc)`| |Hold Left Control, Alt and GUI and press `kc` |
|
||||
|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` |
|
||||
|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc` |
|
||||
|`KC_MEH` | |Left Control, Shift and Alt |
|
||||
|`KC_HYPR` | |Left Control, Shift, Alt and GUI |
|
||||
|
||||
## Mod-Tap Keys :id=mod-tap-keys
|
||||
|
||||
@@ -417,7 +420,10 @@ See also: [Mod-Tap](mod_tap.md)
|
||||
|`RSFT_T(kc)` | |Right Shift when held, `kc` when tapped |
|
||||
|`RALT_T(kc)` |`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt (AltGr) 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 |
|
||||
|`LSG_T(kc)` |`SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|
||||
|`LAG_T(kc)` | |Left Alt and GUI when held, `kc` when tapped |
|
||||
|`RSG_T(kc)` | |Right Shift and GUI when held, `kc` when tapped |
|
||||
|`RAG_T(kc)` | |Right Alt and GUI when held, `kc` when tapped |
|
||||
|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped |
|
||||
|`LSA_T(kc)` | |Left Shift and Left Alt when held, `kc` when tapped |
|
||||
|`RSA_T(kc)` |`SAGR_T(kc)` |Right Shift and Right Alt (AltGr) when held, `kc` when tapped |
|
||||
|
||||
@@ -37,7 +37,10 @@ For convenience, QMK includes some Mod-Tap shortcuts to make common combinations
|
||||
|`RSFT_T(kc)`| |Right Shift when held, `kc` when tapped |
|
||||
|`RALT_T(kc)`|`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt when held, `kc` when tapped |
|
||||
|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped |
|
||||
|`SGUI_T(kc)`|`SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|
||||
|`LSG_T(kc)` |`SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped |
|
||||
|`LAG_T(kc)` | |Left Alt and GUI when held, `kc` when tapped |
|
||||
|`RSG_T(kc)` | |Right Shift and GUI when held, `kc` when tapped |
|
||||
|`RAG_T(kc)` | |Right Alt and GUI when held, `kc` when tapped |
|
||||
|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped |
|
||||
|`LSA_T(kc)` | |Left Shift and Alt when held, `kc` when tapped |
|
||||
|`RSA_T(kc)` |`SAGR_T(kc)` |Right Shift and Right Alt (AltGr) when held, `kc` when tapped |
|
||||
|
||||
@@ -23,7 +23,7 @@ You can control the behavior of one shot keys by defining these in `config.h`:
|
||||
|
||||
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 `clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED)` on key up. If you want to cancel the oneshot, call `reset_oneshot_layer()`.
|
||||
For one shot layers, you need to call `set_oneshot_layer(LAYER, ONESHOT_START)` on key down, and `clear_oneshot_layer_state(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_BIT(KC_*))` to set it, or `clear_oneshot_mods()` to cancel it.
|
||||
|
||||
|
||||
@@ -28,8 +28,14 @@
|
||||
# define F_SCL 400000UL // SCL frequency
|
||||
#endif
|
||||
|
||||
#ifndef I2C_START_RETRY_COUNT
|
||||
# define I2C_START_RETRY_COUNT 20
|
||||
#endif // I2C_START_RETRY_COUNT
|
||||
|
||||
#define TWBR_val (((F_CPU / F_SCL) - 16) / 2)
|
||||
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
|
||||
void i2c_init(void) {
|
||||
TWSR = 0; /* no prescaler */
|
||||
TWBR = (uint8_t)TWBR_val;
|
||||
@@ -47,7 +53,7 @@ void i2c_init(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
|
||||
static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
|
||||
// reset TWI control register
|
||||
TWCR = 0;
|
||||
// transmit START condition
|
||||
@@ -86,6 +92,17 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
|
||||
return I2C_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
|
||||
// Retry i2c_start_impl a bunch times in case the remote side has interrupts disabled.
|
||||
uint16_t timeout_timer = timer_read();
|
||||
uint16_t time_slice = MAX(1, (timeout == (I2C_TIMEOUT_INFINITE)) ? 5 : (timeout / (I2C_START_RETRY_COUNT))); // if it's infinite, wait 1ms between attempts, otherwise split up the entire timeout into the number of retries
|
||||
i2c_status_t status;
|
||||
do {
|
||||
status = i2c_start_impl(address, time_slice);
|
||||
} while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) < timeout)));
|
||||
return status;
|
||||
}
|
||||
|
||||
i2c_status_t i2c_write(uint8_t data, uint16_t timeout) {
|
||||
// load data into data register
|
||||
TWDR = data;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* GitHub repository: https://github.com/g4lvanix/I2C-slave-lib
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/twi.h>
|
||||
#include <avr/interrupt.h>
|
||||
@@ -24,6 +25,12 @@
|
||||
|
||||
#include "i2c_slave.h"
|
||||
|
||||
#if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
# include "transactions.h"
|
||||
|
||||
static volatile bool is_callback_executor = false;
|
||||
#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
|
||||
volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT];
|
||||
|
||||
static volatile uint8_t buffer_address;
|
||||
@@ -48,11 +55,14 @@ ISR(TWI_vect) {
|
||||
case TW_SR_SLA_ACK:
|
||||
// The device is now a slave receiver
|
||||
slave_has_register_set = false;
|
||||
#if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
is_callback_executor = false;
|
||||
#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
break;
|
||||
|
||||
case TW_SR_DATA_ACK:
|
||||
// This device is a slave receiver and has received data
|
||||
// First byte is the location then the bytes will be writen in buffer with auto-incriment
|
||||
// First byte is the location then the bytes will be writen in buffer with auto-increment
|
||||
if (!slave_has_register_set) {
|
||||
buffer_address = TWDR;
|
||||
|
||||
@@ -60,10 +70,25 @@ ISR(TWI_vect) {
|
||||
ack = 0;
|
||||
buffer_address = 0;
|
||||
}
|
||||
slave_has_register_set = true; // address has been receaved now fill in buffer
|
||||
slave_has_register_set = true; // address has been received now fill in buffer
|
||||
|
||||
#if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
// Work out if we're attempting to execute a callback
|
||||
is_callback_executor = buffer_address == split_transaction_table[I2C_EXECUTE_CALLBACK].initiator2target_offset;
|
||||
#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
} else {
|
||||
i2c_slave_reg[buffer_address] = TWDR;
|
||||
buffer_address++;
|
||||
|
||||
#if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
// If we're intending to execute a transaction callback, do so, as we've just received the transaction ID
|
||||
if (is_callback_executor) {
|
||||
split_transaction_desc_t *trans = &split_transaction_table[split_shmem->transaction_id];
|
||||
if (trans->slave_callback) {
|
||||
trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans));
|
||||
}
|
||||
}
|
||||
#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -22,7 +22,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define I2C_SLAVE_REG_COUNT 30
|
||||
#ifndef I2C_SLAVE_REG_COUNT
|
||||
|
||||
# if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
# include "transport.h"
|
||||
# define I2C_SLAVE_REG_COUNT sizeof(split_shared_memory_t)
|
||||
# else // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
# define I2C_SLAVE_REG_COUNT 30
|
||||
# endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS)
|
||||
|
||||
#endif // I2C_SLAVE_REG_COUNT
|
||||
|
||||
_Static_assert(I2C_SLAVE_REG_COUNT < 256, "I2C target registers must be single byte");
|
||||
|
||||
extern volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT];
|
||||
|
||||
|
||||
@@ -224,15 +224,8 @@
|
||||
# define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY / 2)
|
||||
|
||||
# define SLAVE_INT_WIDTH_US 1
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
# define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY
|
||||
# else
|
||||
# define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
# define SLAVE_INT_ACK_WIDTH 4
|
||||
# endif
|
||||
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
# define SLAVE_INT_ACK_WIDTH_UNIT 2
|
||||
# define SLAVE_INT_ACK_WIDTH 4
|
||||
|
||||
inline static void serial_delay(void) ALWAYS_INLINE;
|
||||
inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); }
|
||||
@@ -259,16 +252,12 @@ inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); }
|
||||
inline static void serial_high(void) ALWAYS_INLINE;
|
||||
inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); }
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
void soft_serial_initiator_init(void) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
void soft_serial_target_init(void) {
|
||||
serial_input_with_pullup();
|
||||
|
||||
// Enable INT0-INT7
|
||||
@@ -395,19 +384,14 @@ static inline uint8_t nibble_bits_count(uint8_t bits) {
|
||||
|
||||
// interrupt handle to be used by the target device
|
||||
ISR(SERIAL_PIN_INTERRUPT) {
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_low();
|
||||
serial_output();
|
||||
SSTD_t *trans = Transaction_table;
|
||||
# else
|
||||
// recive transaction table index
|
||||
uint8_t tid, bits;
|
||||
uint8_t pecount = 0;
|
||||
sync_recv();
|
||||
bits = serial_read_chunk(&pecount, 7);
|
||||
bits = serial_read_chunk(&pecount, 8);
|
||||
tid = bits >> 3;
|
||||
bits = (bits & 7) != nibble_bits_count(tid);
|
||||
if (bits || pecount > 0 || tid > Transaction_table_size) {
|
||||
bits = (bits & 7) != (nibble_bits_count(tid) & 7);
|
||||
if (bits || pecount > 0 || tid > NUM_TOTAL_TRANSACTIONS) {
|
||||
return;
|
||||
}
|
||||
serial_delay_half1();
|
||||
@@ -415,18 +399,22 @@ ISR(SERIAL_PIN_INTERRUPT) {
|
||||
serial_high(); // response step1 low->high
|
||||
serial_output();
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH);
|
||||
SSTD_t *trans = &Transaction_table[tid];
|
||||
split_transaction_desc_t *trans = &split_transaction_table[tid];
|
||||
serial_low(); // response step2 ack high->low
|
||||
# endif
|
||||
|
||||
// If the transaction has a callback, we can execute it now
|
||||
if (trans->slave_callback) {
|
||||
trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans));
|
||||
}
|
||||
|
||||
// target send phase
|
||||
if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size);
|
||||
if (trans->target2initiator_buffer_size > 0) serial_send_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size);
|
||||
// target switch to input
|
||||
change_sender2reciver();
|
||||
|
||||
// target recive phase
|
||||
if (trans->initiator2target_buffer_size > 0) {
|
||||
if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size)) {
|
||||
if (serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) {
|
||||
*trans->status = TRANSACTION_ACCEPTED;
|
||||
} else {
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
@@ -448,14 +436,12 @@ ISR(SERIAL_PIN_INTERRUPT) {
|
||||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
SSTD_t *trans = Transaction_table;
|
||||
# else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
# endif
|
||||
if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR;
|
||||
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
|
||||
|
||||
if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered
|
||||
|
||||
cli();
|
||||
|
||||
// signal to the target that we want to start a transaction
|
||||
@@ -463,27 +449,11 @@ int soft_serial_transaction(int sstd_index) {
|
||||
serial_low();
|
||||
_delay_us(SLAVE_INT_WIDTH_US);
|
||||
|
||||
# ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
// wait for the target response
|
||||
serial_input_with_pullup();
|
||||
_delay_us(SLAVE_INT_RESPONSE_TIME);
|
||||
|
||||
// check if the target is present
|
||||
if (serial_read_pin()) {
|
||||
// target failed to pull the line low, assume not present
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_NO_RESPONSE;
|
||||
sei();
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
}
|
||||
|
||||
# else
|
||||
// send transaction table index
|
||||
int tid = (sstd_index << 3) | (7 & nibble_bits_count(sstd_index));
|
||||
sync_send();
|
||||
_delay_sub_us(TID_SEND_ADJUST);
|
||||
serial_write_chunk(tid, 7);
|
||||
serial_write_chunk(tid, 8);
|
||||
serial_delay_half1();
|
||||
|
||||
// wait for the target response (step1 low->high)
|
||||
@@ -504,12 +474,11 @@ int soft_serial_transaction(int sstd_index) {
|
||||
}
|
||||
_delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT);
|
||||
}
|
||||
# endif
|
||||
|
||||
// initiator recive phase
|
||||
// if the target is present syncronize with it
|
||||
if (trans->target2initiator_buffer_size > 0) {
|
||||
if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, trans->target2initiator_buffer_size)) {
|
||||
if (!serial_recive_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
*trans->status = TRANSACTION_DATA_ERROR;
|
||||
@@ -523,7 +492,7 @@ int soft_serial_transaction(int sstd_index) {
|
||||
|
||||
// initiator send phase
|
||||
if (trans->initiator2target_buffer_size > 0) {
|
||||
serial_send_packet((uint8_t *)trans->initiator2target_buffer, trans->initiator2target_buffer_size);
|
||||
serial_send_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// always, release the line when not in use
|
||||
@@ -534,9 +503,8 @@ int soft_serial_transaction(int sstd_index) {
|
||||
return TRANSACTION_END;
|
||||
}
|
||||
|
||||
# ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index) {
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
|
||||
cli();
|
||||
int retval = *trans->status;
|
||||
*trans->status = 0;
|
||||
@@ -544,8 +512,6 @@ int soft_serial_get_and_clean_status(int sstd_index) {
|
||||
sei();
|
||||
return retval;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
// Helix serial.c history
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Need Soft Serial defines in config.h
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// ex.
|
||||
// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
|
||||
// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
|
||||
// // 1: about 137kbps (default)
|
||||
// // 2: about 75kbps
|
||||
// // 3: about 39kbps
|
||||
// // 4: about 26kbps
|
||||
// // 5: about 20kbps
|
||||
//
|
||||
// //// USE simple API (using signle-type transaction function)
|
||||
// /* nothing */
|
||||
// //// USE flexible API (using multi-type transaction function)
|
||||
// #define SERIAL_USE_MULTI_TRANSACTION
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Soft Serial Transaction Descriptor
|
||||
typedef struct _SSTD_t {
|
||||
uint8_t *status;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t *initiator2target_buffer;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t *target2initiator_buffer;
|
||||
} SSTD_t;
|
||||
#define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t))
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
// target is interrupt accept side
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
|
||||
// initiator resullt
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void);
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
#endif
|
||||
|
||||
// target status
|
||||
// *SSTD_t.status has
|
||||
// initiator:
|
||||
// TRANSACTION_END
|
||||
// or TRANSACTION_NO_RESPONSE
|
||||
// or TRANSACTION_DATA_ERROR
|
||||
// target:
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
#endif
|
||||
@@ -14,10 +14,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "quantum.h"
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
typedef int16_t spi_status_t;
|
||||
|
||||
|
||||
166
drivers/awinic/aw20216.c
Normal file
166
drivers/awinic/aw20216.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/* Copyright 2021 Jasper Chan
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "aw20216.h"
|
||||
#include "spi_master.h"
|
||||
|
||||
/* The AW20216 appears to be somewhat similar to the IS31FL743, although quite
|
||||
* a few things are different, such as the command byte format and page ordering.
|
||||
* The LED addresses start from 0x00 instead of 0x01.
|
||||
*/
|
||||
#define AWINIC_ID 0b1010 << 4
|
||||
|
||||
#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
|
||||
#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
|
||||
#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
|
||||
#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
|
||||
#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
|
||||
|
||||
#define AW_WRITE 0
|
||||
#define AW_READ 1
|
||||
|
||||
#define AW_REG_CONFIGURATION 0x00 // PG0
|
||||
#define AW_REG_GLOBALCURRENT 0x01 // PG0
|
||||
|
||||
// Default value of AW_REG_CONFIGURATION
|
||||
// D7:D4 = 1011, SWSEL (SW1~SW12 active)
|
||||
// D3 = 0?, reserved (apparently this should be 1 but it doesn't seem to matter)
|
||||
// D2:D1 = 00, OSDE (open/short detection enable)
|
||||
// D0 = 0, CHIPEN (write 1 to enable LEDs when hardware enable pulled high)
|
||||
#define AW_CONFIG_DEFAULT 0b10110000
|
||||
#define AW_CHIPEN 1
|
||||
|
||||
#ifndef AW_SCALING_MAX
|
||||
# define AW_SCALING_MAX 150
|
||||
#endif
|
||||
|
||||
#ifndef AW_GLOBAL_CURRENT_MAX
|
||||
# define AW_GLOBAL_CURRENT_MAX 150
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_1_CS
|
||||
# define DRIVER_1_CS B13
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_1_EN
|
||||
# define DRIVER_1_EN C13
|
||||
#endif
|
||||
|
||||
uint8_t g_spi_transfer_buffer[20] = {0};
|
||||
aw_led g_pwm_buffer[DRIVER_LED_TOTAL];
|
||||
bool g_pwm_buffer_update_required[DRIVER_LED_TOTAL];
|
||||
|
||||
bool AW20216_write_register(pin_t slave_pin, uint8_t page, uint8_t reg, uint8_t data) {
|
||||
// Do we need to call spi_stop() if this fails?
|
||||
if (!spi_start(slave_pin, false, 0, 16)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE);
|
||||
g_spi_transfer_buffer[1] = reg;
|
||||
g_spi_transfer_buffer[2] = data;
|
||||
|
||||
if (spi_transmit(g_spi_transfer_buffer, 3) != SPI_STATUS_SUCCESS) {
|
||||
spi_stop();
|
||||
return false;
|
||||
}
|
||||
spi_stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AW20216_init_scaling(void) {
|
||||
// Set constant current to the max, control brightness with PWM
|
||||
aw_led led;
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
led = g_aw_leds[i];
|
||||
if (led.driver == 0) {
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
|
||||
}
|
||||
#ifdef DRIVER_2_CS
|
||||
else if (led.driver == 1) {
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AW20216_soft_enable(void) {
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
|
||||
#ifdef DRIVER_2_CS
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void AW20216_update_pwm(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
aw_led led = g_aw_leds[index];
|
||||
if (led.driver == 0) {
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.r, red);
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.g, green);
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.b, blue);
|
||||
}
|
||||
#ifdef DRIVER_2_CS
|
||||
else if (led.driver == 1) {
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.r, red);
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.g, green);
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.b, blue);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void AW20216_init(void) {
|
||||
// All LEDs should start with all scaling and PWM registers as off
|
||||
setPinOutput(DRIVER_1_EN);
|
||||
writePinHigh(DRIVER_1_EN);
|
||||
AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX);
|
||||
#ifdef DRIVER_2_EN
|
||||
setPinOutput(DRIVER_2_EN);
|
||||
writePinHigh(DRIVER_2_EN);
|
||||
AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX);
|
||||
#endif
|
||||
AW20216_init_scaling();
|
||||
AW20216_soft_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
|
||||
g_pwm_buffer[index].r = red;
|
||||
g_pwm_buffer[index].g = green;
|
||||
g_pwm_buffer[index].b = blue;
|
||||
g_pwm_buffer_update_required[index] = true;
|
||||
return;
|
||||
}
|
||||
void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
AW20216_set_color(i, red, green, blue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void AW20216_update_pwm_buffers(void) {
|
||||
for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
|
||||
if (g_pwm_buffer_update_required[i]) {
|
||||
AW20216_update_pwm(i, g_pwm_buffer[i].r, g_pwm_buffer[i].g, g_pwm_buffer[i].b);
|
||||
g_pwm_buffer_update_required[i] = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
251
drivers/awinic/aw20216.h
Normal file
251
drivers/awinic/aw20216.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/* Copyright 2021 Jasper Chan (Gigahawk)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct aw_led {
|
||||
uint8_t driver : 2;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} aw_led;
|
||||
|
||||
extern const aw_led g_aw_leds[DRIVER_LED_TOTAL];
|
||||
|
||||
void AW20216_init(void);
|
||||
void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
|
||||
void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void AW20216_update_pwm_buffers(void);
|
||||
|
||||
#define CS1_SW1 0x00
|
||||
#define CS2_SW1 0x01
|
||||
#define CS3_SW1 0x02
|
||||
#define CS4_SW1 0x03
|
||||
#define CS5_SW1 0x04
|
||||
#define CS6_SW1 0x05
|
||||
#define CS7_SW1 0x06
|
||||
#define CS8_SW1 0x07
|
||||
#define CS9_SW1 0x08
|
||||
#define CS10_SW1 0x09
|
||||
#define CS11_SW1 0x0A
|
||||
#define CS12_SW1 0x0B
|
||||
#define CS13_SW1 0x0C
|
||||
#define CS14_SW1 0x0D
|
||||
#define CS15_SW1 0x0E
|
||||
#define CS16_SW1 0x0F
|
||||
#define CS17_SW1 0x10
|
||||
#define CS18_SW1 0x11
|
||||
#define CS1_SW2 0x12
|
||||
#define CS2_SW2 0x13
|
||||
#define CS3_SW2 0x14
|
||||
#define CS4_SW2 0x15
|
||||
#define CS5_SW2 0x16
|
||||
#define CS6_SW2 0x17
|
||||
#define CS7_SW2 0x18
|
||||
#define CS8_SW2 0x19
|
||||
#define CS9_SW2 0x1A
|
||||
#define CS10_SW2 0x1B
|
||||
#define CS11_SW2 0x1C
|
||||
#define CS12_SW2 0x1D
|
||||
#define CS13_SW2 0x1E
|
||||
#define CS14_SW2 0x1F
|
||||
#define CS15_SW2 0x20
|
||||
#define CS16_SW2 0x21
|
||||
#define CS17_SW2 0x22
|
||||
#define CS18_SW2 0x23
|
||||
#define CS1_SW3 0x24
|
||||
#define CS2_SW3 0x25
|
||||
#define CS3_SW3 0x26
|
||||
#define CS4_SW3 0x27
|
||||
#define CS5_SW3 0x28
|
||||
#define CS6_SW3 0x29
|
||||
#define CS7_SW3 0x2A
|
||||
#define CS8_SW3 0x2B
|
||||
#define CS9_SW3 0x2C
|
||||
#define CS10_SW3 0x2D
|
||||
#define CS11_SW3 0x2E
|
||||
#define CS12_SW3 0x2F
|
||||
#define CS13_SW3 0x30
|
||||
#define CS14_SW3 0x31
|
||||
#define CS15_SW3 0x32
|
||||
#define CS16_SW3 0x33
|
||||
#define CS17_SW3 0x34
|
||||
#define CS18_SW3 0x35
|
||||
#define CS1_SW4 0x36
|
||||
#define CS2_SW4 0x37
|
||||
#define CS3_SW4 0x38
|
||||
#define CS4_SW4 0x39
|
||||
#define CS5_SW4 0x3A
|
||||
#define CS6_SW4 0x3B
|
||||
#define CS7_SW4 0x3C
|
||||
#define CS8_SW4 0x3D
|
||||
#define CS9_SW4 0x3E
|
||||
#define CS10_SW4 0x3F
|
||||
#define CS11_SW4 0x40
|
||||
#define CS12_SW4 0x41
|
||||
#define CS13_SW4 0x42
|
||||
#define CS14_SW4 0x43
|
||||
#define CS15_SW4 0x44
|
||||
#define CS16_SW4 0x45
|
||||
#define CS17_SW4 0x46
|
||||
#define CS18_SW4 0x47
|
||||
#define CS1_SW5 0x48
|
||||
#define CS2_SW5 0x49
|
||||
#define CS3_SW5 0x4A
|
||||
#define CS4_SW5 0x4B
|
||||
#define CS5_SW5 0x4C
|
||||
#define CS6_SW5 0x4D
|
||||
#define CS7_SW5 0x4E
|
||||
#define CS8_SW5 0x4F
|
||||
#define CS9_SW5 0x50
|
||||
#define CS10_SW5 0x51
|
||||
#define CS11_SW5 0x52
|
||||
#define CS12_SW5 0x53
|
||||
#define CS13_SW5 0x54
|
||||
#define CS14_SW5 0x55
|
||||
#define CS15_SW5 0x56
|
||||
#define CS16_SW5 0x57
|
||||
#define CS17_SW5 0x58
|
||||
#define CS18_SW5 0x59
|
||||
#define CS1_SW6 0x5A
|
||||
#define CS2_SW6 0x5B
|
||||
#define CS3_SW6 0x5C
|
||||
#define CS4_SW6 0x5D
|
||||
#define CS5_SW6 0x5E
|
||||
#define CS6_SW6 0x5F
|
||||
#define CS7_SW6 0x60
|
||||
#define CS8_SW6 0x61
|
||||
#define CS9_SW6 0x62
|
||||
#define CS10_SW6 0x63
|
||||
#define CS11_SW6 0x64
|
||||
#define CS12_SW6 0x65
|
||||
#define CS13_SW6 0x66
|
||||
#define CS14_SW6 0x67
|
||||
#define CS15_SW6 0x68
|
||||
#define CS16_SW6 0x69
|
||||
#define CS17_SW6 0x6A
|
||||
#define CS18_SW6 0x6B
|
||||
#define CS1_SW7 0x6C
|
||||
#define CS2_SW7 0x6D
|
||||
#define CS3_SW7 0x6E
|
||||
#define CS4_SW7 0x6F
|
||||
#define CS5_SW7 0x70
|
||||
#define CS6_SW7 0x71
|
||||
#define CS7_SW7 0x72
|
||||
#define CS8_SW7 0x73
|
||||
#define CS9_SW7 0x74
|
||||
#define CS10_SW7 0x75
|
||||
#define CS11_SW7 0x76
|
||||
#define CS12_SW7 0x77
|
||||
#define CS13_SW7 0x78
|
||||
#define CS14_SW7 0x79
|
||||
#define CS15_SW7 0x7A
|
||||
#define CS16_SW7 0x7B
|
||||
#define CS17_SW7 0x7C
|
||||
#define CS18_SW7 0x7D
|
||||
#define CS1_SW8 0x7E
|
||||
#define CS2_SW8 0x7F
|
||||
#define CS3_SW8 0x80
|
||||
#define CS4_SW8 0x81
|
||||
#define CS5_SW8 0x82
|
||||
#define CS6_SW8 0x83
|
||||
#define CS7_SW8 0x84
|
||||
#define CS8_SW8 0x85
|
||||
#define CS9_SW8 0x86
|
||||
#define CS10_SW8 0x87
|
||||
#define CS11_SW8 0x88
|
||||
#define CS12_SW8 0x89
|
||||
#define CS13_SW8 0x8A
|
||||
#define CS14_SW8 0x8B
|
||||
#define CS15_SW8 0x8C
|
||||
#define CS16_SW8 0x8D
|
||||
#define CS17_SW8 0x8E
|
||||
#define CS18_SW8 0x8F
|
||||
#define CS1_SW9 0x90
|
||||
#define CS2_SW9 0x91
|
||||
#define CS3_SW9 0x92
|
||||
#define CS4_SW9 0x93
|
||||
#define CS5_SW9 0x94
|
||||
#define CS6_SW9 0x95
|
||||
#define CS7_SW9 0x96
|
||||
#define CS8_SW9 0x97
|
||||
#define CS9_SW9 0x98
|
||||
#define CS10_SW9 0x99
|
||||
#define CS11_SW9 0x9A
|
||||
#define CS12_SW9 0x9B
|
||||
#define CS13_SW9 0x9C
|
||||
#define CS14_SW9 0x9D
|
||||
#define CS15_SW9 0x9E
|
||||
#define CS16_SW9 0x9F
|
||||
#define CS17_SW9 0xA0
|
||||
#define CS18_SW9 0xA1
|
||||
#define CS1_SW10 0xA2
|
||||
#define CS2_SW10 0xA3
|
||||
#define CS3_SW10 0xA4
|
||||
#define CS4_SW10 0xA5
|
||||
#define CS5_SW10 0xA6
|
||||
#define CS6_SW10 0xA7
|
||||
#define CS7_SW10 0xA8
|
||||
#define CS8_SW10 0xA9
|
||||
#define CS9_SW10 0xAA
|
||||
#define CS10_SW10 0xAB
|
||||
#define CS11_SW10 0xAC
|
||||
#define CS12_SW10 0xAD
|
||||
#define CS13_SW10 0xAE
|
||||
#define CS14_SW10 0xAF
|
||||
#define CS15_SW10 0xB0
|
||||
#define CS16_SW10 0xB1
|
||||
#define CS17_SW10 0xB2
|
||||
#define CS18_SW10 0xB3
|
||||
#define CS1_SW11 0xB4
|
||||
#define CS2_SW11 0xB5
|
||||
#define CS3_SW11 0xB6
|
||||
#define CS4_SW11 0xB7
|
||||
#define CS5_SW11 0xB8
|
||||
#define CS6_SW11 0xB9
|
||||
#define CS7_SW11 0xBA
|
||||
#define CS8_SW11 0xBB
|
||||
#define CS9_SW11 0xBC
|
||||
#define CS10_SW11 0xBD
|
||||
#define CS11_SW11 0xBE
|
||||
#define CS12_SW11 0xBF
|
||||
#define CS13_SW11 0xC0
|
||||
#define CS14_SW11 0xC1
|
||||
#define CS15_SW11 0xC2
|
||||
#define CS16_SW11 0xC3
|
||||
#define CS17_SW11 0xC4
|
||||
#define CS18_SW11 0xC5
|
||||
#define CS1_SW12 0xC6
|
||||
#define CS2_SW12 0xC7
|
||||
#define CS3_SW12 0xC8
|
||||
#define CS4_SW12 0xC9
|
||||
#define CS5_SW12 0xCA
|
||||
#define CS6_SW12 0xCB
|
||||
#define CS7_SW12 0xCC
|
||||
#define CS8_SW12 0xCD
|
||||
#define CS9_SW12 0xCE
|
||||
#define CS10_SW12 0xCF
|
||||
#define CS11_SW12 0xD0
|
||||
#define CS12_SW12 0xD1
|
||||
#define CS13_SW12 0xD2
|
||||
#define CS14_SW12 0xD3
|
||||
#define CS15_SW12 0xD4
|
||||
#define CS16_SW12 0xD5
|
||||
#define CS17_SW12 0xD6
|
||||
#define CS18_SW12 0xD7
|
||||
@@ -74,21 +74,12 @@ static THD_FUNCTION(Thread1, arg) {
|
||||
}
|
||||
}
|
||||
|
||||
static SSTD_t *Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
|
||||
void soft_serial_initiator_init(void) {
|
||||
serial_output();
|
||||
serial_high();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
|
||||
void soft_serial_target_init(void) {
|
||||
serial_input();
|
||||
|
||||
palEnablePadEvent(PAL_PORT(SOFT_SERIAL_PIN), PAL_PAD(SOFT_SERIAL_PIN), PAL_EVENT_MODE_FALLING_EDGE);
|
||||
@@ -154,16 +145,14 @@ void interrupt_handler(void *arg) {
|
||||
uint8_t checksum_computed = 0;
|
||||
int sstd_index = 0;
|
||||
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
sstd_index = serial_read_byte();
|
||||
sync_send();
|
||||
#endif
|
||||
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
|
||||
for (int i = 0; i < trans->initiator2target_buffer_size; ++i) {
|
||||
trans->initiator2target_buffer[i] = serial_read_byte();
|
||||
split_trans_initiator2target_buffer(trans)[i] = serial_read_byte();
|
||||
sync_send();
|
||||
checksum_computed += trans->initiator2target_buffer[i];
|
||||
checksum_computed += split_trans_initiator2target_buffer(trans)[i];
|
||||
}
|
||||
checksum_computed ^= 7;
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
@@ -172,12 +161,17 @@ void interrupt_handler(void *arg) {
|
||||
// wait for the sync to finish sending
|
||||
serial_delay();
|
||||
|
||||
// Allow any slave processing to occur
|
||||
if (trans->slave_callback) {
|
||||
trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans));
|
||||
}
|
||||
|
||||
uint8_t checksum = 0;
|
||||
for (int i = 0; i < trans->target2initiator_buffer_size; ++i) {
|
||||
serial_write_byte(trans->target2initiator_buffer[i]);
|
||||
serial_write_byte(split_trans_target2initiator_buffer(trans)[i]);
|
||||
sync_send();
|
||||
serial_delay_half();
|
||||
checksum += trans->target2initiator_buffer[i];
|
||||
checksum += split_trans_target2initiator_buffer(trans)[i];
|
||||
}
|
||||
serial_write_byte(checksum ^ 7);
|
||||
sync_send();
|
||||
@@ -206,15 +200,10 @@ void interrupt_handler(void *arg) {
|
||||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
int sstd_index = 0;
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
#endif
|
||||
|
||||
if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t *trans = &Transaction_table[sstd_index];
|
||||
if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR;
|
||||
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
|
||||
if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered
|
||||
|
||||
// TODO: remove extra delay between transactions
|
||||
serial_delay();
|
||||
@@ -244,14 +233,13 @@ int soft_serial_transaction(int sstd_index) {
|
||||
|
||||
uint8_t checksum = 0;
|
||||
// send data to the slave
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
serial_write_byte(sstd_index); // first chunk is transaction id
|
||||
sync_recv();
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < trans->initiator2target_buffer_size; ++i) {
|
||||
serial_write_byte(trans->initiator2target_buffer[i]);
|
||||
serial_write_byte(split_trans_initiator2target_buffer(trans)[i]);
|
||||
sync_recv();
|
||||
checksum += trans->initiator2target_buffer[i];
|
||||
checksum += split_trans_initiator2target_buffer(trans)[i];
|
||||
}
|
||||
serial_write_byte(checksum ^ 7);
|
||||
sync_recv();
|
||||
@@ -262,9 +250,9 @@ int soft_serial_transaction(int sstd_index) {
|
||||
// receive data from the slave
|
||||
uint8_t checksum_computed = 0;
|
||||
for (int i = 0; i < trans->target2initiator_buffer_size; ++i) {
|
||||
trans->target2initiator_buffer[i] = serial_read_byte();
|
||||
split_trans_target2initiator_buffer(trans)[i] = serial_read_byte();
|
||||
sync_recv();
|
||||
checksum_computed += trans->target2initiator_buffer[i];
|
||||
checksum_computed += split_trans_target2initiator_buffer(trans)[i];
|
||||
}
|
||||
checksum_computed ^= 7;
|
||||
uint8_t checksum_received = serial_read_byte();
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Need Soft Serial defines in config.h
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// ex.
|
||||
// #define SOFT_SERIAL_PIN ?? // ?? = D0,D1,D2,D3,E6
|
||||
// OPTIONAL: #define SELECT_SOFT_SERIAL_SPEED ? // ? = 1,2,3,4,5
|
||||
// // 1: about 137kbps (default)
|
||||
// // 2: about 75kbps
|
||||
// // 3: about 39kbps
|
||||
// // 4: about 26kbps
|
||||
// // 5: about 20kbps
|
||||
//
|
||||
// //// USE simple API (using signle-type transaction function)
|
||||
// /* nothing */
|
||||
// //// USE flexible API (using multi-type transaction function)
|
||||
// #define SERIAL_USE_MULTI_TRANSACTION
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Soft Serial Transaction Descriptor
|
||||
typedef struct _SSTD_t {
|
||||
uint8_t *status;
|
||||
uint8_t initiator2target_buffer_size;
|
||||
uint8_t *initiator2target_buffer;
|
||||
uint8_t target2initiator_buffer_size;
|
||||
uint8_t *target2initiator_buffer;
|
||||
} SSTD_t;
|
||||
#define TID_LIMIT(table) (sizeof(table) / sizeof(SSTD_t))
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
// target is interrupt accept side
|
||||
void soft_serial_target_init(SSTD_t *sstd_table, int sstd_table_size);
|
||||
|
||||
// initiator result
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void);
|
||||
#else
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
#endif
|
||||
|
||||
// target status
|
||||
// *SSTD_t.status has
|
||||
// initiator:
|
||||
// TRANSACTION_END
|
||||
// or TRANSACTION_NO_RESPONSE
|
||||
// or TRANSACTION_DATA_ERROR
|
||||
// target:
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
#ifdef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
#endif
|
||||
@@ -113,37 +113,29 @@ void usart_slave_init(void) {
|
||||
chThdCreateStatic(waSlaveThread, sizeof(waSlaveThread), HIGHPRIO, SlaveThread, NULL);
|
||||
}
|
||||
|
||||
static SSTD_t* Transaction_table = NULL;
|
||||
static uint8_t Transaction_table_size = 0;
|
||||
void soft_serial_initiator_init(void) { usart_master_init(); }
|
||||
|
||||
void soft_serial_initiator_init(SSTD_t* sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
|
||||
usart_master_init();
|
||||
}
|
||||
|
||||
void soft_serial_target_init(SSTD_t* sstd_table, int sstd_table_size) {
|
||||
Transaction_table = sstd_table;
|
||||
Transaction_table_size = (uint8_t)sstd_table_size;
|
||||
|
||||
usart_slave_init();
|
||||
}
|
||||
void soft_serial_target_init(void) { usart_slave_init(); }
|
||||
|
||||
void handle_soft_serial_slave(void) {
|
||||
uint8_t sstd_index = sdGet(&SERIAL_USART_DRIVER); // first chunk is always transaction id
|
||||
SSTD_t* trans = &Transaction_table[sstd_index];
|
||||
uint8_t sstd_index = sdGet(&SERIAL_USART_DRIVER); // first chunk is always transaction id
|
||||
split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
|
||||
|
||||
// Always write back the sstd_index as part of a basic handshake
|
||||
sstd_index ^= HANDSHAKE_MAGIC;
|
||||
sdWrite(&SERIAL_USART_DRIVER, &sstd_index, sizeof(sstd_index));
|
||||
|
||||
if (trans->initiator2target_buffer_size) {
|
||||
sdRead(&SERIAL_USART_DRIVER, trans->initiator2target_buffer, trans->initiator2target_buffer_size);
|
||||
sdRead(&SERIAL_USART_DRIVER, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size);
|
||||
}
|
||||
|
||||
// Allow any slave processing to occur
|
||||
if (trans->slave_callback) {
|
||||
trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans));
|
||||
}
|
||||
|
||||
if (trans->target2initiator_buffer_size) {
|
||||
sdWrite(&SERIAL_USART_DRIVER, trans->target2initiator_buffer, trans->target2initiator_buffer_size);
|
||||
sdWrite(&SERIAL_USART_DRIVER, split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size);
|
||||
}
|
||||
|
||||
if (trans->status) {
|
||||
@@ -160,17 +152,14 @@ void handle_soft_serial_slave(void) {
|
||||
// TRANSACTION_END
|
||||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
#ifndef SERIAL_USE_MULTI_TRANSACTION
|
||||
int soft_serial_transaction(void) {
|
||||
uint8_t sstd_index = 0;
|
||||
#else
|
||||
int soft_serial_transaction(int index) {
|
||||
uint8_t sstd_index = index;
|
||||
#endif
|
||||
|
||||
if (sstd_index > Transaction_table_size) return TRANSACTION_TYPE_ERROR;
|
||||
SSTD_t* trans = &Transaction_table[sstd_index];
|
||||
msg_t res = 0;
|
||||
if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR;
|
||||
split_transaction_desc_t* trans = &split_transaction_table[sstd_index];
|
||||
msg_t res = 0;
|
||||
|
||||
if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered
|
||||
|
||||
sdClear(&SERIAL_USART_DRIVER);
|
||||
|
||||
@@ -189,7 +178,7 @@ int soft_serial_transaction(int index) {
|
||||
}
|
||||
|
||||
if (trans->initiator2target_buffer_size) {
|
||||
res = sdWriteTimeout(&SERIAL_USART_DRIVER, trans->initiator2target_buffer, trans->initiator2target_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
res = sdWriteTimeout(&SERIAL_USART_DRIVER, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
if (res < 0) {
|
||||
dprintf("serial::usart_transmit NO_RESPONSE\n");
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
@@ -197,7 +186,7 @@ int soft_serial_transaction(int index) {
|
||||
}
|
||||
|
||||
if (trans->target2initiator_buffer_size) {
|
||||
res = sdReadTimeout(&SERIAL_USART_DRIVER, trans->target2initiator_buffer, trans->target2initiator_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
res = sdReadTimeout(&SERIAL_USART_DRIVER, split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size, TIME_MS2I(SERIAL_USART_TIMEOUT));
|
||||
if (res < 0) {
|
||||
dprintf("serial::usart_receive NO_RESPONSE\n");
|
||||
return TRANSACTION_NO_RESPONSE;
|
||||
|
||||
@@ -15,11 +15,16 @@
|
||||
*/
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "quantum.h"
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
static pin_t currentSlavePin = NO_PIN;
|
||||
static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
|
||||
static pin_t currentSlavePin = NO_PIN;
|
||||
|
||||
#if defined(K20x) || defined(KL2x)
|
||||
static SPIConfig spiConfig = {NULL, 0, 0, 0};
|
||||
#else
|
||||
static SPIConfig spiConfig = {false, NULL, 0, 0, 0, 0};
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void spi_init(void) {
|
||||
static bool is_initialised = false;
|
||||
@@ -27,15 +32,15 @@ __attribute__((weak)) void spi_init(void) {
|
||||
is_initialised = true;
|
||||
|
||||
// Try releasing special pins for a short time
|
||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_INPUT);
|
||||
palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_INPUT);
|
||||
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_INPUT);
|
||||
setPinInput(SPI_SCK_PIN);
|
||||
setPinInput(SPI_MOSI_PIN);
|
||||
setPinInput(SPI_MISO_PIN);
|
||||
|
||||
chThdSleepMilliseconds(10);
|
||||
#if defined(USE_GPIOV1)
|
||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
|
||||
palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
|
||||
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
|
||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), SPI_SCK_PAL_MODE);
|
||||
palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), SPI_MOSI_PAL_MODE);
|
||||
palSetPadMode(PAL_PORT(SPI_MISO_PIN), PAL_PAD(SPI_MISO_PIN), SPI_MISO_PAL_MODE);
|
||||
#else
|
||||
palSetPadMode(PAL_PORT(SPI_SCK_PIN), PAL_PAD(SPI_SCK_PIN), PAL_MODE_ALTERNATE(SPI_SCK_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
|
||||
palSetPadMode(PAL_PORT(SPI_MOSI_PIN), PAL_PAD(SPI_MOSI_PIN), PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
|
||||
@@ -58,6 +63,54 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(K20x) || defined(KL2x)
|
||||
spiConfig.tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(1);
|
||||
|
||||
if (lsbFirst) {
|
||||
spiConfig.tar0 |= SPIx_CTARn_LSBFE;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
spiConfig.tar0 |= SPIx_CTARn_CPHA;
|
||||
break;
|
||||
case 2:
|
||||
spiConfig.tar0 |= SPIx_CTARn_CPOL;
|
||||
break;
|
||||
case 3:
|
||||
spiConfig.tar0 |= SPIx_CTARn_CPHA | SPIx_CTARn_CPOL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (roundedDivisor) {
|
||||
case 2:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(0);
|
||||
break;
|
||||
case 4:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(1);
|
||||
break;
|
||||
case 8:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(3);
|
||||
break;
|
||||
case 16:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(4);
|
||||
break;
|
||||
case 32:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(5);
|
||||
break;
|
||||
case 64:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(6);
|
||||
break;
|
||||
case 128:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(7);
|
||||
break;
|
||||
case 256:
|
||||
spiConfig.tar0 |= SPIx_CTARn_BR(8);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
spiConfig.cr1 = 0;
|
||||
|
||||
if (lsbFirst) {
|
||||
@@ -103,6 +156,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
||||
spiConfig.cr1 |= SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
currentSlavePin = slavePin;
|
||||
spiConfig.ssport = PAL_PORT(slavePin);
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
#include <ch.h>
|
||||
#include <hal.h>
|
||||
#include "quantum.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gpio.h"
|
||||
#include "chibios_config.h"
|
||||
|
||||
#ifndef SPI_DRIVER
|
||||
# define SPI_DRIVER SPID2
|
||||
@@ -29,7 +32,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef SPI_SCK_PAL_MODE
|
||||
# define SPI_SCK_PAL_MODE 5
|
||||
# if defined(USE_GPIOV1)
|
||||
# define SPI_SCK_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
|
||||
# else
|
||||
# define SPI_SCK_PAL_MODE 5
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MOSI_PIN
|
||||
@@ -37,7 +44,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MOSI_PAL_MODE
|
||||
# define SPI_MOSI_PAL_MODE 5
|
||||
# if defined(USE_GPIOV1)
|
||||
# define SPI_MOSI_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
|
||||
# else
|
||||
# define SPI_MOSI_PAL_MODE 5
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO_PIN
|
||||
@@ -45,7 +56,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef SPI_MISO_PAL_MODE
|
||||
# define SPI_MISO_PAL_MODE 5
|
||||
# if defined(USE_GPIOV1)
|
||||
# define SPI_MISO_PAL_MODE PAL_MODE_STM32_ALTERNATE_PUSHPULL
|
||||
# else
|
||||
# define SPI_MISO_PAL_MODE 5
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef int16_t spi_status_t;
|
||||
|
||||
@@ -291,6 +291,73 @@ void haptic_play(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record) {
|
||||
switch(keycode) {
|
||||
# ifdef NO_HAPTIC_MOD
|
||||
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
|
||||
if (record->tap.count == 0) return false;
|
||||
break;
|
||||
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
|
||||
if (record->tap.count != TAPPING_TOGGLE) return false;
|
||||
break;
|
||||
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
|
||||
if (record->tap.count == 0) return false;
|
||||
break;
|
||||
case KC_LCTRL ... KC_RGUI:
|
||||
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_FN
|
||||
case KC_FN0 ... KC_FN31:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_ALPHA
|
||||
case KC_A ... KC_Z:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_PUNCTUATION
|
||||
case KC_ENTER:
|
||||
case KC_ESCAPE:
|
||||
case KC_BSPACE:
|
||||
case KC_SPACE:
|
||||
case KC_MINUS:
|
||||
case KC_EQUAL:
|
||||
case KC_LBRACKET:
|
||||
case KC_RBRACKET:
|
||||
case KC_BSLASH:
|
||||
case KC_NONUS_HASH:
|
||||
case KC_SCOLON:
|
||||
case KC_QUOTE:
|
||||
case KC_GRAVE:
|
||||
case KC_COMMA:
|
||||
case KC_SLASH:
|
||||
case KC_DOT:
|
||||
case KC_NONUS_BSLASH:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_LOCKKEYS
|
||||
case KC_CAPSLOCK:
|
||||
case KC_SCROLLLOCK:
|
||||
case KC_NUMLOCK:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_NAV
|
||||
case KC_PSCREEN:
|
||||
case KC_PAUSE:
|
||||
case KC_INSERT:
|
||||
case KC_DELETE:
|
||||
case KC_PGDOWN:
|
||||
case KC_PGUP:
|
||||
case KC_LEFT:
|
||||
case KC_UP:
|
||||
case KC_RIGHT:
|
||||
case KC_DOWN:
|
||||
case KC_END:
|
||||
case KC_HOME:
|
||||
# endif
|
||||
# ifdef NO_HAPTIC_NUMERIC
|
||||
case KC_1 ... KC_0:
|
||||
# endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool process_haptic(uint16_t keycode, keyrecord_t *record) {
|
||||
if (keycode == HPT_ON && record->event.pressed) {
|
||||
haptic_enable();
|
||||
@@ -335,12 +402,12 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
|
||||
if (haptic_config.enable) {
|
||||
if (record->event.pressed) {
|
||||
// keypress
|
||||
if (haptic_config.feedback < 2) {
|
||||
if (haptic_config.feedback < 2 && get_haptic_enabled_key(keycode, record)) {
|
||||
haptic_play();
|
||||
}
|
||||
} else {
|
||||
// keyrelease
|
||||
if (haptic_config.feedback > 0) {
|
||||
if (haptic_config.feedback > 0 && get_haptic_enabled_key(keycode, record)) {
|
||||
haptic_play();
|
||||
}
|
||||
}
|
||||
|
||||
496
drivers/lcd/st7565.c
Normal file
496
drivers/lcd/st7565.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
Copyright 2021
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "st7565.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "progmem.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
|
||||
#include ST7565_FONT_H
|
||||
|
||||
// Fundamental Commands
|
||||
#define CONTRAST 0x81
|
||||
#define DISPLAY_ALL_ON 0xA5
|
||||
#define DISPLAY_ALL_ON_RESUME 0xA4
|
||||
#define NORMAL_DISPLAY 0xA6
|
||||
#define INVERT_DISPLAY 0xA7
|
||||
#define DISPLAY_ON 0xAF
|
||||
#define DISPLAY_OFF 0xAE
|
||||
#define NOP 0xE3
|
||||
|
||||
// Addressing Setting Commands
|
||||
#define PAM_SETCOLUMN_LSB 0x00
|
||||
#define PAM_SETCOLUMN_MSB 0x10
|
||||
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
|
||||
|
||||
// Hardware Configuration Commands
|
||||
#define DISPLAY_START_LINE 0x40
|
||||
#define SEGMENT_REMAP 0xA0
|
||||
#define SEGMENT_REMAP_INV 0xA1
|
||||
#define COM_SCAN_INC 0xC0
|
||||
#define COM_SCAN_DEC 0xC8
|
||||
#define LCD_BIAS_7 0xA3
|
||||
#define LCD_BIAS_9 0xA2
|
||||
#define RESISTOR_RATIO 0x20
|
||||
#define POWER_CONTROL 0x28
|
||||
|
||||
// Misc defines
|
||||
#ifndef ST7565_BLOCK_COUNT
|
||||
# define ST7565_BLOCK_COUNT (sizeof(ST7565_BLOCK_TYPE) * 8)
|
||||
#endif
|
||||
#ifndef ST7565_BLOCK_SIZE
|
||||
# define ST7565_BLOCK_SIZE (ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)
|
||||
#endif
|
||||
|
||||
#define ST7565_ALL_BLOCKS_MASK (((((ST7565_BLOCK_TYPE)1 << (ST7565_BLOCK_COUNT - 1)) - 1) << 1) | 1)
|
||||
|
||||
#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
|
||||
|
||||
// Display buffer's is the same as the display memory layout
|
||||
// this is so we don't end up with rounding errors with
|
||||
// parts of the display unusable or don't get cleared correctly
|
||||
// and also allows for drawing & inverting
|
||||
uint8_t st7565_buffer[ST7565_MATRIX_SIZE];
|
||||
uint8_t * st7565_cursor;
|
||||
ST7565_BLOCK_TYPE st7565_dirty = 0;
|
||||
bool st7565_initialized = false;
|
||||
bool st7565_active = false;
|
||||
bool st7565_inverted = false;
|
||||
display_rotation_t st7565_rotation = DISPLAY_ROTATION_0;
|
||||
#if ST7565_TIMEOUT > 0
|
||||
uint32_t st7565_timeout;
|
||||
#endif
|
||||
#if ST7565_UPDATE_INTERVAL > 0
|
||||
uint16_t st7565_update_timeout;
|
||||
#endif
|
||||
|
||||
// Flips the rendering bits for a character at the current cursor position
|
||||
static void InvertCharacter(uint8_t *cursor) {
|
||||
const uint8_t *end = cursor + ST7565_FONT_WIDTH;
|
||||
while (cursor < end) {
|
||||
*cursor = ~(*cursor);
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
bool st7565_init(display_rotation_t rotation) {
|
||||
setPinOutput(ST7565_A0_PIN);
|
||||
writePinHigh(ST7565_A0_PIN);
|
||||
setPinOutput(ST7565_RST_PIN);
|
||||
writePinHigh(ST7565_RST_PIN);
|
||||
|
||||
st7565_rotation = st7565_init_user(rotation);
|
||||
|
||||
spi_init();
|
||||
spi_start(ST7565_SS_PIN, false, 0, ST7565_SPI_CLK_DIVISOR);
|
||||
|
||||
st7565_reset();
|
||||
|
||||
st7565_send_cmd(LCD_BIAS_7);
|
||||
if (!HAS_FLAGS(st7565_rotation, DISPLAY_ROTATION_180)) {
|
||||
st7565_send_cmd(SEGMENT_REMAP);
|
||||
st7565_send_cmd(COM_SCAN_DEC);
|
||||
} else {
|
||||
st7565_send_cmd(SEGMENT_REMAP_INV);
|
||||
st7565_send_cmd(COM_SCAN_INC);
|
||||
}
|
||||
st7565_send_cmd(DISPLAY_START_LINE | 0x00);
|
||||
st7565_send_cmd(CONTRAST);
|
||||
st7565_send_cmd(ST7565_CONTRAST);
|
||||
st7565_send_cmd(RESISTOR_RATIO | 0x01);
|
||||
st7565_send_cmd(POWER_CONTROL | 0x04);
|
||||
wait_ms(50);
|
||||
st7565_send_cmd(POWER_CONTROL | 0x06);
|
||||
wait_ms(50);
|
||||
st7565_send_cmd(POWER_CONTROL | 0x07);
|
||||
wait_ms(10);
|
||||
st7565_send_cmd(DISPLAY_ON);
|
||||
st7565_send_cmd(DISPLAY_ALL_ON_RESUME);
|
||||
st7565_send_cmd(NORMAL_DISPLAY);
|
||||
|
||||
spi_stop();
|
||||
|
||||
#if ST7565_TIMEOUT > 0
|
||||
st7565_timeout = timer_read32() + ST7565_TIMEOUT;
|
||||
#endif
|
||||
|
||||
st7565_clear();
|
||||
st7565_initialized = true;
|
||||
st7565_active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
__attribute__((weak)) display_rotation_t st7565_init_user(display_rotation_t rotation) { return rotation; }
|
||||
|
||||
void st7565_clear(void) {
|
||||
memset(st7565_buffer, 0, sizeof(st7565_buffer));
|
||||
st7565_cursor = &st7565_buffer[0];
|
||||
st7565_dirty = ST7565_ALL_BLOCKS_MASK;
|
||||
}
|
||||
|
||||
uint8_t crot(uint8_t a, int8_t n) {
|
||||
const uint8_t mask = 0x7;
|
||||
n &= mask;
|
||||
return a << n | a >> (-n & mask);
|
||||
}
|
||||
|
||||
void st7565_render(void) {
|
||||
if (!st7565_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we have work to do?
|
||||
st7565_dirty &= ST7565_ALL_BLOCKS_MASK;
|
||||
if (!st7565_dirty) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find first dirty block
|
||||
uint8_t update_start = 0;
|
||||
while (!(st7565_dirty & ((ST7565_BLOCK_TYPE)1 << update_start))) {
|
||||
++update_start;
|
||||
}
|
||||
|
||||
// Calculate commands to set memory addressing bounds.
|
||||
uint8_t start_page = ST7565_BLOCK_SIZE * update_start / ST7565_DISPLAY_WIDTH;
|
||||
uint8_t start_column = ST7565_BLOCK_SIZE * update_start % ST7565_DISPLAY_WIDTH;
|
||||
// IC has 132 segment drivers, for panels with less width we need to offset the starting column
|
||||
if (HAS_FLAGS(st7565_rotation, DISPLAY_ROTATION_180)) {
|
||||
start_column += (132 - ST7565_DISPLAY_WIDTH);
|
||||
}
|
||||
|
||||
spi_start(ST7565_SS_PIN, false, 0, ST7565_SPI_CLK_DIVISOR);
|
||||
|
||||
st7565_send_cmd(PAM_PAGE_ADDR | start_page);
|
||||
st7565_send_cmd(PAM_SETCOLUMN_LSB | ((ST7565_COLUMN_OFFSET + start_column) & 0x0f));
|
||||
st7565_send_cmd(PAM_SETCOLUMN_MSB | ((ST7565_COLUMN_OFFSET + start_column) >> 4 & 0x0f));
|
||||
|
||||
st7565_send_data(&st7565_buffer[ST7565_BLOCK_SIZE * update_start], ST7565_BLOCK_SIZE);
|
||||
|
||||
// Turn on display if it is off
|
||||
st7565_on();
|
||||
|
||||
// Clear dirty flag
|
||||
st7565_dirty &= ~((ST7565_BLOCK_TYPE)1 << update_start);
|
||||
}
|
||||
|
||||
void st7565_set_cursor(uint8_t col, uint8_t line) {
|
||||
uint16_t index = line * ST7565_DISPLAY_WIDTH + col * ST7565_FONT_WIDTH;
|
||||
|
||||
// Out of bounds?
|
||||
if (index >= ST7565_MATRIX_SIZE) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
st7565_cursor = &st7565_buffer[index];
|
||||
}
|
||||
|
||||
void st7565_advance_page(bool clearPageRemainder) {
|
||||
uint16_t index = st7565_cursor - &st7565_buffer[0];
|
||||
uint8_t remaining = ST7565_DISPLAY_WIDTH - (index % ST7565_DISPLAY_WIDTH);
|
||||
|
||||
if (clearPageRemainder) {
|
||||
// Remaining Char count
|
||||
remaining = remaining / ST7565_FONT_WIDTH;
|
||||
|
||||
// Write empty character until next line
|
||||
while (remaining--) st7565_write_char(' ', false);
|
||||
} else {
|
||||
// Next page index out of bounds?
|
||||
if (index + remaining >= ST7565_MATRIX_SIZE) {
|
||||
index = 0;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
st7565_cursor = &st7565_buffer[index + remaining];
|
||||
}
|
||||
}
|
||||
|
||||
void st7565_advance_char(void) {
|
||||
uint16_t nextIndex = st7565_cursor - &st7565_buffer[0] + ST7565_FONT_WIDTH;
|
||||
uint8_t remainingSpace = ST7565_DISPLAY_WIDTH - (nextIndex % ST7565_DISPLAY_WIDTH);
|
||||
|
||||
// Do we have enough space on the current line for the next character
|
||||
if (remainingSpace < ST7565_FONT_WIDTH) {
|
||||
nextIndex += remainingSpace;
|
||||
}
|
||||
|
||||
// Did we go out of bounds
|
||||
if (nextIndex >= ST7565_MATRIX_SIZE) {
|
||||
nextIndex = 0;
|
||||
}
|
||||
|
||||
// Update cursor position
|
||||
st7565_cursor = &st7565_buffer[nextIndex];
|
||||
}
|
||||
|
||||
// Main handler that writes character data to the display buffer
|
||||
void st7565_write_char(const char data, bool invert) {
|
||||
// Advance to the next line if newline
|
||||
if (data == '\n') {
|
||||
// Old source wrote ' ' until end of line...
|
||||
st7565_advance_page(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == '\r') {
|
||||
st7565_advance_page(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// copy the current render buffer to check for dirty after
|
||||
static uint8_t st7565_temp_buffer[ST7565_FONT_WIDTH];
|
||||
memcpy(&st7565_temp_buffer, st7565_cursor, ST7565_FONT_WIDTH);
|
||||
|
||||
_Static_assert(sizeof(font) >= ((ST7565_FONT_END + 1 - ST7565_FONT_START) * ST7565_FONT_WIDTH), "ST7565_FONT_END references outside array");
|
||||
|
||||
// set the reder buffer data
|
||||
uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
|
||||
if (cast_data < ST7565_FONT_START || cast_data > ST7565_FONT_END) {
|
||||
memset(st7565_cursor, 0x00, ST7565_FONT_WIDTH);
|
||||
} else {
|
||||
const uint8_t *glyph = &font[(cast_data - ST7565_FONT_START) * ST7565_FONT_WIDTH];
|
||||
memcpy_P(st7565_cursor, glyph, ST7565_FONT_WIDTH);
|
||||
}
|
||||
|
||||
// Invert if needed
|
||||
if (invert) {
|
||||
InvertCharacter(st7565_cursor);
|
||||
}
|
||||
|
||||
// Dirty check
|
||||
if (memcmp(&st7565_temp_buffer, st7565_cursor, ST7565_FONT_WIDTH)) {
|
||||
uint16_t index = st7565_cursor - &st7565_buffer[0];
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (index / ST7565_BLOCK_SIZE));
|
||||
// Edgecase check if the written data spans the 2 chunks
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << ((index + ST7565_FONT_WIDTH - 1) / ST7565_BLOCK_SIZE));
|
||||
}
|
||||
|
||||
// Finally move to the next char
|
||||
st7565_advance_char();
|
||||
}
|
||||
|
||||
void st7565_write(const char *data, bool invert) {
|
||||
const char *end = data + strlen(data);
|
||||
while (data < end) {
|
||||
st7565_write_char(*data, invert);
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
void st7565_write_ln(const char *data, bool invert) {
|
||||
st7565_write(data, invert);
|
||||
st7565_advance_page(true);
|
||||
}
|
||||
|
||||
void st7565_pan(bool left) {
|
||||
uint16_t i = 0;
|
||||
for (uint16_t y = 0; y < ST7565_DISPLAY_HEIGHT / 8; y++) {
|
||||
if (left) {
|
||||
for (uint16_t x = 0; x < ST7565_DISPLAY_WIDTH - 1; x++) {
|
||||
i = y * ST7565_DISPLAY_WIDTH + x;
|
||||
st7565_buffer[i] = st7565_buffer[i + 1];
|
||||
}
|
||||
} else {
|
||||
for (uint16_t x = ST7565_DISPLAY_WIDTH - 1; x > 0; x--) {
|
||||
i = y * ST7565_DISPLAY_WIDTH + x;
|
||||
st7565_buffer[i] = st7565_buffer[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
st7565_dirty = ST7565_ALL_BLOCKS_MASK;
|
||||
}
|
||||
|
||||
display_buffer_reader_t st7565_read_raw(uint16_t start_index) {
|
||||
if (start_index > ST7565_MATRIX_SIZE) start_index = ST7565_MATRIX_SIZE;
|
||||
display_buffer_reader_t ret_reader;
|
||||
ret_reader.current_element = &st7565_buffer[start_index];
|
||||
ret_reader.remaining_element_count = ST7565_MATRIX_SIZE - start_index;
|
||||
return ret_reader;
|
||||
}
|
||||
|
||||
void st7565_write_raw_byte(const char data, uint16_t index) {
|
||||
if (index > ST7565_MATRIX_SIZE) index = ST7565_MATRIX_SIZE;
|
||||
if (st7565_buffer[index] == data) return;
|
||||
st7565_buffer[index] = data;
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (index / ST7565_BLOCK_SIZE));
|
||||
}
|
||||
|
||||
void st7565_write_raw(const char *data, uint16_t size) {
|
||||
uint16_t cursor_start_index = st7565_cursor - &st7565_buffer[0];
|
||||
if ((size + cursor_start_index) > ST7565_MATRIX_SIZE) size = ST7565_MATRIX_SIZE - cursor_start_index;
|
||||
for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
|
||||
uint8_t c = *data++;
|
||||
if (st7565_buffer[i] == c) continue;
|
||||
st7565_buffer[i] = c;
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (i / ST7565_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
void st7565_write_pixel(uint8_t x, uint8_t y, bool on) {
|
||||
if (x >= ST7565_DISPLAY_WIDTH) {
|
||||
return;
|
||||
}
|
||||
uint16_t index = x + (y / 8) * ST7565_DISPLAY_WIDTH;
|
||||
if (index >= ST7565_MATRIX_SIZE) {
|
||||
return;
|
||||
}
|
||||
uint8_t data = st7565_buffer[index];
|
||||
if (on) {
|
||||
data |= (1 << (y % 8));
|
||||
} else {
|
||||
data &= ~(1 << (y % 8));
|
||||
}
|
||||
if (st7565_buffer[index] != data) {
|
||||
st7565_buffer[index] = data;
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (index / ST7565_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__AVR__)
|
||||
void st7565_write_P(const char *data, bool invert) {
|
||||
uint8_t c = pgm_read_byte(data);
|
||||
while (c != 0) {
|
||||
st7565_write_char(c, invert);
|
||||
c = pgm_read_byte(++data);
|
||||
}
|
||||
}
|
||||
|
||||
void st7565_write_ln_P(const char *data, bool invert) {
|
||||
st7565_write_P(data, invert);
|
||||
st7565_advance_page(true);
|
||||
}
|
||||
|
||||
void st7565_write_raw_P(const char *data, uint16_t size) {
|
||||
uint16_t cursor_start_index = st7565_cursor - &st7565_buffer[0];
|
||||
if ((size + cursor_start_index) > ST7565_MATRIX_SIZE) size = ST7565_MATRIX_SIZE - cursor_start_index;
|
||||
for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
|
||||
uint8_t c = pgm_read_byte(data++);
|
||||
if (st7565_buffer[i] == c) continue;
|
||||
st7565_buffer[i] = c;
|
||||
st7565_dirty |= ((ST7565_BLOCK_TYPE)1 << (i / ST7565_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
bool st7565_on(void) {
|
||||
if (!st7565_initialized) {
|
||||
return st7565_active;
|
||||
}
|
||||
|
||||
#if ST7565_TIMEOUT > 0
|
||||
st7565_timeout = timer_read32() + ST7565_TIMEOUT;
|
||||
#endif
|
||||
|
||||
if (!st7565_active) {
|
||||
spi_start(ST7565_SS_PIN, false, 0, ST7565_SPI_CLK_DIVISOR);
|
||||
st7565_send_cmd(DISPLAY_ON);
|
||||
spi_stop();
|
||||
st7565_active = true;
|
||||
st7565_on_user();
|
||||
}
|
||||
return st7565_active;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void st7565_on_user(void) {}
|
||||
|
||||
bool st7565_off(void) {
|
||||
if (!st7565_initialized) {
|
||||
return !st7565_active;
|
||||
}
|
||||
|
||||
if (st7565_active) {
|
||||
spi_start(ST7565_SS_PIN, false, 0, ST7565_SPI_CLK_DIVISOR);
|
||||
st7565_send_cmd(DISPLAY_OFF);
|
||||
spi_stop();
|
||||
st7565_active = false;
|
||||
st7565_off_user();
|
||||
}
|
||||
return !st7565_active;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void st7565_off_user(void) {}
|
||||
|
||||
bool st7565_is_on(void) { return st7565_active; }
|
||||
|
||||
bool st7565_invert(bool invert) {
|
||||
if (!st7565_initialized) {
|
||||
return st7565_inverted;
|
||||
}
|
||||
|
||||
if (invert != st7565_inverted) {
|
||||
spi_start(ST7565_SS_PIN, false, 0, ST7565_SPI_CLK_DIVISOR);
|
||||
st7565_send_cmd(invert ? INVERT_DISPLAY : NORMAL_DISPLAY);
|
||||
spi_stop();
|
||||
st7565_inverted = invert;
|
||||
}
|
||||
return st7565_inverted;
|
||||
}
|
||||
|
||||
uint8_t st7565_max_chars(void) { return ST7565_DISPLAY_WIDTH / ST7565_FONT_WIDTH; }
|
||||
|
||||
uint8_t st7565_max_lines(void) { return ST7565_DISPLAY_HEIGHT / ST7565_FONT_HEIGHT; }
|
||||
|
||||
void st7565_task(void) {
|
||||
if (!st7565_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if ST7565_UPDATE_INTERVAL > 0
|
||||
if (timer_elapsed(st7565_update_timeout) >= ST7565_UPDATE_INTERVAL) {
|
||||
st7565_update_timeout = timer_read();
|
||||
st7565_set_cursor(0, 0);
|
||||
st7565_task_user();
|
||||
}
|
||||
#else
|
||||
st7565_set_cursor(0, 0);
|
||||
st7565_task_user();
|
||||
#endif
|
||||
|
||||
// Smart render system, no need to check for dirty
|
||||
st7565_render();
|
||||
|
||||
// Display timeout check
|
||||
#if ST7565_TIMEOUT > 0
|
||||
if (st7565_active && timer_expired32(timer_read32(), st7565_timeout)) {
|
||||
st7565_off();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((weak)) void st7565_task_user(void) {}
|
||||
|
||||
void st7565_reset(void) {
|
||||
writePinLow(ST7565_RST_PIN);
|
||||
wait_ms(20);
|
||||
writePinHigh(ST7565_RST_PIN);
|
||||
wait_ms(20);
|
||||
}
|
||||
|
||||
spi_status_t st7565_send_cmd(uint8_t cmd) {
|
||||
writePinLow(ST7565_A0_PIN);
|
||||
return spi_write(cmd);
|
||||
}
|
||||
|
||||
spi_status_t st7565_send_data(uint8_t *data, uint16_t length) {
|
||||
writePinHigh(ST7565_A0_PIN);
|
||||
return spi_transmit(data, length);
|
||||
}
|
||||
219
drivers/lcd/st7565.h
Normal file
219
drivers/lcd/st7565.h
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
Copyright 2021
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "spi_master.h"
|
||||
|
||||
#ifndef ST7565_DISPLAY_WIDTH
|
||||
# define ST7565_DISPLAY_WIDTH 128
|
||||
#endif
|
||||
#ifndef ST7565_DISPLAY_HEIGHT
|
||||
# define ST7565_DISPLAY_HEIGHT 32
|
||||
#endif
|
||||
#ifndef ST7565_MATRIX_SIZE
|
||||
# define ST7565_MATRIX_SIZE (ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH) // 1024 (compile time mathed)
|
||||
#endif
|
||||
#ifndef ST7565_BLOCK_TYPE
|
||||
# define ST7565_BLOCK_TYPE uint16_t
|
||||
#endif
|
||||
#ifndef ST7565_BLOCK_COUNT
|
||||
# define ST7565_BLOCK_COUNT (sizeof(ST7565_BLOCK_TYPE) * 8) // 32 (compile time mathed)
|
||||
#endif
|
||||
#ifndef ST7565_BLOCK_SIZE
|
||||
# define ST7565_BLOCK_SIZE (ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT) // 32 (compile time mathed)
|
||||
#endif
|
||||
|
||||
// the column address corresponding to the first column in the display hardware
|
||||
#if !defined(ST7565_COLUMN_OFFSET)
|
||||
# define ST7565_COLUMN_OFFSET 0
|
||||
#endif
|
||||
|
||||
// spi clock divisor
|
||||
#if !defined(ST7565_SPI_CLK_DIVISOR)
|
||||
# define ST7565_SPI_CLK_DIVISOR 4
|
||||
#endif
|
||||
|
||||
// Custom font file to use
|
||||
#if !defined(ST7565_FONT_H)
|
||||
# define ST7565_FONT_H "glcdfont.c"
|
||||
#endif
|
||||
// unsigned char value of the first character in the font file
|
||||
#if !defined(ST7565_FONT_START)
|
||||
# define ST7565_FONT_START 0
|
||||
#endif
|
||||
// unsigned char value of the last character in the font file
|
||||
#if !defined(ST7565_FONT_END)
|
||||
# define ST7565_FONT_END 223
|
||||
#endif
|
||||
// Font render width
|
||||
#if !defined(ST7565_FONT_WIDTH)
|
||||
# define ST7565_FONT_WIDTH 6
|
||||
#endif
|
||||
// Font render height
|
||||
#if !defined(ST7565_FONT_HEIGHT)
|
||||
# define ST7565_FONT_HEIGHT 8
|
||||
#endif
|
||||
// Default contrast level
|
||||
#if !defined(ST7565_CONTRAST)
|
||||
# define ST7565_CONTRAST 32
|
||||
#endif
|
||||
|
||||
#if !defined(ST7565_TIMEOUT)
|
||||
# if defined(ST7565_DISABLE_TIMEOUT)
|
||||
# define ST7565_TIMEOUT 0
|
||||
# else
|
||||
# define ST7565_TIMEOUT 60000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ST7565_UPDATE_INTERVAL) && defined(SPLIT_KEYBOARD)
|
||||
# define ST7565_UPDATE_INTERVAL 50
|
||||
#endif
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t *current_element;
|
||||
uint16_t remaining_element_count;
|
||||
} display_buffer_reader_t;
|
||||
|
||||
// Rotation enum values are flags
|
||||
typedef enum { DISPLAY_ROTATION_0, DISPLAY_ROTATION_180 } display_rotation_t;
|
||||
|
||||
// Initialize the display, rotating the rendered output based on the define passed in.
|
||||
// Returns true if the display was initialized successfully
|
||||
bool st7565_init(display_rotation_t rotation);
|
||||
|
||||
// Called at the start of st7565_init, weak function overridable by the user
|
||||
// rotation - the value passed into st7565_init
|
||||
// Return new display_rotation_t if you want to override default rotation
|
||||
display_rotation_t st7565_init_user(display_rotation_t rotation);
|
||||
|
||||
// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering
|
||||
void st7565_clear(void);
|
||||
|
||||
// Renders the dirty chunks of the buffer to display
|
||||
void st7565_render(void);
|
||||
|
||||
// Moves cursor to character position indicated by column and line, wraps if out of bounds
|
||||
// Max column denoted by 'st7565_max_chars()' and max lines by 'st7565_max_lines()' functions
|
||||
void st7565_set_cursor(uint8_t col, uint8_t line);
|
||||
|
||||
// Advances the cursor to the next page, writing ' ' if true
|
||||
// Wraps to the begining when out of bounds
|
||||
void st7565_advance_page(bool clearPageRemainder);
|
||||
|
||||
// Moves the cursor forward 1 character length
|
||||
// Advance page if there is not enough room for the next character
|
||||
// Wraps to the begining when out of bounds
|
||||
void st7565_advance_char(void);
|
||||
|
||||
// Writes a single character to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Main handler that writes character data to the display buffer
|
||||
void st7565_write_char(const char data, bool invert);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
void st7565_write(const char *data, bool invert);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||
void st7565_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
|
||||
void st7565_pan(bool left);
|
||||
|
||||
// Returns a pointer to the requested start index in the buffer plus remaining
|
||||
// buffer length as struct
|
||||
display_buffer_reader_t st7565_read_raw(uint16_t start_index);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
void st7565_write_raw(const char *data, uint16_t size);
|
||||
|
||||
// Writes a single byte into the buffer at the specified index
|
||||
void st7565_write_raw_byte(const char data, uint16_t index);
|
||||
|
||||
// Sets a specific pixel on or off
|
||||
// Coordinates start at top-left and go right and down for positive x and y
|
||||
void st7565_write_pixel(uint8_t x, uint8_t y, bool on);
|
||||
|
||||
#if defined(__AVR__)
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Remapped to call 'void st7565_write(const char *data, bool invert);' on ARM
|
||||
void st7565_write_P(const char *data, bool invert);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||
// Remapped to call 'void st7565_write_ln(const char *data, bool invert);' on ARM
|
||||
void st7565_write_ln_P(const char *data, bool invert);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
void st7565_write_raw_P(const char *data, uint16_t size);
|
||||
#else
|
||||
# define st7565_write_P(data, invert) st7565_write(data, invert)
|
||||
# define st7565_write_ln_P(data, invert) st7565_write_ln(data, invert)
|
||||
# define st7565_write_raw_P(data, size) st7565_write_raw(data, size)
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
// Can be used to manually turn on the screen if it is off
|
||||
// Returns true if the screen was on or turns on
|
||||
bool st7565_on(void);
|
||||
|
||||
// Called when st7565_on() turns on the screen, weak function overridable by the user
|
||||
// Not called if the screen is already on
|
||||
void st7565_on_user(void);
|
||||
|
||||
// Can be used to manually turn off the screen if it is on
|
||||
// Returns true if the screen was off or turns off
|
||||
bool st7565_off(void);
|
||||
|
||||
// Called when st7565_off() turns off the screen, weak function overridable by the user
|
||||
// Not called if the screen is already off
|
||||
void st7565_off_user(void);
|
||||
|
||||
// Returns true if the screen is currently on, false if it is
|
||||
// not
|
||||
bool st7565_is_on(void);
|
||||
|
||||
// Basically it's st7565_render, but with timeout management and st7565_task_user calling!
|
||||
void st7565_task(void);
|
||||
|
||||
// Called at the start of st7565_task, weak function overridable by the user
|
||||
void st7565_task_user(void);
|
||||
|
||||
// Inverts the display
|
||||
// Returns true if the screen was or is inverted
|
||||
bool st7565_invert(bool invert);
|
||||
|
||||
// Returns the maximum number of characters that will fit on a line
|
||||
uint8_t st7565_max_chars(void);
|
||||
|
||||
// Returns the maximum number of lines that will fit on the display
|
||||
uint8_t st7565_max_lines(void);
|
||||
|
||||
void st7565_reset(void);
|
||||
|
||||
spi_status_t st7565_send_cmd(uint8_t cmd);
|
||||
|
||||
spi_status_t st7565_send_data(uint8_t *data, uint16_t length);
|
||||
@@ -4,7 +4,7 @@
|
||||
// Online editor: http://teripom.x0.com/
|
||||
|
||||
static const unsigned char font[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, 0x26, 0x29, 0x79, 0x29, 0x26, 0x00, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
|
||||
0x07, 0x08, 0x7F, 0x08, 0x07, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00, 0x26, 0x29, 0x79, 0x29, 0x26, 0x00, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
|
||||
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x80, 0x70, 0x30, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
|
||||
0x72, 0x49, 0x49, 0x49, 0x46, 0x00, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00, 0x41, 0x21, 0x11, 0x09, 0x07, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x02, 0x01, 0x59, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x03, 0x04, 0x78, 0x04, 0x03, 0x00, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x03, 0x07, 0x08, 0x00, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x00, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00, 0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
|
||||
|
||||
@@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define DISPLAY_ALL_ON 0xA5
|
||||
#define DISPLAY_ALL_ON_RESUME 0xA4
|
||||
#define NORMAL_DISPLAY 0xA6
|
||||
#define INVERT_DISPLAY 0xA7
|
||||
#define DISPLAY_ON 0xAF
|
||||
#define DISPLAY_OFF 0xAE
|
||||
#define NOP 0xE3
|
||||
@@ -114,8 +115,9 @@ OLED_BLOCK_TYPE oled_dirty = 0;
|
||||
bool oled_initialized = false;
|
||||
bool oled_active = false;
|
||||
bool oled_scrolling = false;
|
||||
bool oled_inverted = false;
|
||||
uint8_t oled_brightness = OLED_BRIGHTNESS;
|
||||
uint8_t oled_rotation = 0;
|
||||
oled_rotation_t oled_rotation = 0;
|
||||
uint8_t oled_rotation_width = 0;
|
||||
uint8_t oled_scroll_speed = 0; // this holds the speed after being remapped to ssd1306 internal values
|
||||
uint8_t oled_scroll_start = 0;
|
||||
@@ -158,7 +160,7 @@ static void InvertCharacter(uint8_t *cursor) {
|
||||
}
|
||||
}
|
||||
|
||||
bool oled_init(uint8_t rotation) {
|
||||
bool oled_init(oled_rotation_t rotation) {
|
||||
#if defined(USE_I2C) && defined(SPLIT_KEYBOARD)
|
||||
if (!is_keyboard_master()) {
|
||||
return true;
|
||||
@@ -491,8 +493,9 @@ void oled_write_raw(const char *data, uint16_t size) {
|
||||
uint16_t cursor_start_index = oled_cursor - &oled_buffer[0];
|
||||
if ((size + cursor_start_index) > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE - cursor_start_index;
|
||||
for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
|
||||
if (oled_buffer[i] == data[i]) continue;
|
||||
oled_buffer[i] = data[i];
|
||||
uint8_t c = *data++;
|
||||
if (oled_buffer[i] == c) continue;
|
||||
oled_buffer[i] = c;
|
||||
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
|
||||
}
|
||||
}
|
||||
@@ -689,6 +692,30 @@ bool oled_scroll_off(void) {
|
||||
return !oled_scrolling;
|
||||
}
|
||||
|
||||
bool oled_invert(bool invert) {
|
||||
if (!oled_initialized) {
|
||||
return oled_inverted;
|
||||
}
|
||||
|
||||
if (invert && !oled_inverted) {
|
||||
static const uint8_t PROGMEM display_inverted[] = {I2C_CMD, INVERT_DISPLAY};
|
||||
if (I2C_TRANSMIT_P(display_inverted) != I2C_STATUS_SUCCESS) {
|
||||
print("oled_invert cmd failed\n");
|
||||
return oled_inverted;
|
||||
}
|
||||
oled_inverted = true;
|
||||
} else if (!invert && oled_inverted) {
|
||||
static const uint8_t PROGMEM display_normal[] = {I2C_CMD, NORMAL_DISPLAY};
|
||||
if (I2C_TRANSMIT_P(display_normal) != I2C_STATUS_SUCCESS) {
|
||||
print("oled_invert cmd failed\n");
|
||||
return oled_inverted;
|
||||
}
|
||||
oled_inverted = false;
|
||||
}
|
||||
|
||||
return oled_inverted;
|
||||
}
|
||||
|
||||
uint8_t oled_max_chars(void) {
|
||||
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
|
||||
return OLED_DISPLAY_WIDTH / OLED_FONT_WIDTH;
|
||||
|
||||
@@ -226,13 +226,17 @@ void oled_write(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
|
||||
void oled_pan(bool left);
|
||||
|
||||
// Returns a pointer to the requested start index in the buffer plus remaining
|
||||
// buffer length as struct
|
||||
oled_buffer_reader_t oled_read_raw(uint16_t start_index);
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
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);
|
||||
|
||||
// Sets a specific pixel on or off
|
||||
@@ -251,17 +255,11 @@ void oled_write_P(const char *data, bool invert);
|
||||
// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM
|
||||
void oled_write_ln_P(const char *data, bool invert);
|
||||
|
||||
// Writes a PROGMEM string to the buffer at current cursor position
|
||||
void oled_write_raw_P(const char *data, uint16_t size);
|
||||
#else
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
# define oled_write_P(data, invert) oled_write(data, invert)
|
||||
|
||||
// Writes a string to the buffer at current cursor position
|
||||
// Advances the cursor while writing, inverts the pixels if true
|
||||
// Advances the cursor to the next page, wiring ' ' to the remainder of the current page
|
||||
# define oled_write_ln_P(data, invert) oled_write(data, invert)
|
||||
|
||||
# define oled_write_raw_P(data, size) oled_write_raw(data, size)
|
||||
#endif // defined(__AVR__)
|
||||
|
||||
@@ -315,6 +313,10 @@ bool oled_scroll_left(void);
|
||||
// Returns true if the screen was not scrolling or stops scrolling
|
||||
bool oled_scroll_off(void);
|
||||
|
||||
// Inverts the display
|
||||
// Returns true if the screen was or is inverted
|
||||
bool oled_invert(bool invert);
|
||||
|
||||
// Returns the maximum number of characters that will fit on a line
|
||||
uint8_t oled_max_chars(void);
|
||||
|
||||
|
||||
46
drivers/serial.h
Normal file
46
drivers/serial.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <transactions.h>
|
||||
|
||||
// initiator is transaction start side
|
||||
void soft_serial_initiator_init(void);
|
||||
// target is interrupt accept side
|
||||
void soft_serial_target_init(void);
|
||||
|
||||
// initiator result
|
||||
#define TRANSACTION_END 0
|
||||
#define TRANSACTION_NO_RESPONSE 0x1
|
||||
#define TRANSACTION_DATA_ERROR 0x2
|
||||
#define TRANSACTION_TYPE_ERROR 0x4
|
||||
int soft_serial_transaction(int sstd_index);
|
||||
|
||||
// target status
|
||||
// *SSTD_t.status has
|
||||
// initiator:
|
||||
// TRANSACTION_END
|
||||
// or TRANSACTION_NO_RESPONSE
|
||||
// or TRANSACTION_DATA_ERROR
|
||||
// target:
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// or TRANSACTION_ACCEPTED
|
||||
#define TRANSACTION_ACCEPTED 0x8
|
||||
int soft_serial_get_and_clean_status(int sstd_index);
|
||||
@@ -2,6 +2,9 @@
|
||||
MCU = STM32F303
|
||||
BOARD = QMK_PROTON_C
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
## Features
|
||||
CONSOLE_ENABLE = yes
|
||||
ENCODER_ENABLE = yes
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
MCU = STM32F303
|
||||
BOARD = QMK_PROTON_C
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,4 +17,4 @@
|
||||
|
||||
// Nothing to see here, move along... ;-)
|
||||
|
||||
#include "constellation.h"
|
||||
#include "constellation.h"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,18 +19,8 @@
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define ____ KC_NO
|
||||
|
||||
#define LAYOUT_all( \
|
||||
K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K213, K014, \
|
||||
K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \
|
||||
K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, \
|
||||
K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K312, K313, K314, \
|
||||
K400, K401, K402, K408, K409, K410, K412, K413, K414 \
|
||||
) { \
|
||||
{ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \
|
||||
{ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \
|
||||
{ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 }, \
|
||||
{ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, ____, K312, K313, K314 }, \
|
||||
{ K400, K401, K402, ____, ____, ____, ____, ____, K408, K409, K410, ____, K412, K413, K414 } \
|
||||
}
|
||||
#if defined(KEYBOARD_aeboards_constellation_rev1)
|
||||
#include "rev1.h"
|
||||
#elif defined(KEYBOARD_aeboards_constellation_rev2)
|
||||
#include "rev2.h"
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,7 +24,7 @@
|
||||
#define PRODUCT_ID 0x065C // 65 - Constellation
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER AEBoards
|
||||
#define PRODUCT AEBoards Constellation
|
||||
#define PRODUCT AEBoards Constellation Rev1
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 5
|
||||
20
keyboards/aeboards/constellation/rev1/readme.md
Executable file
20
keyboards/aeboards/constellation/rev1/readme.md
Executable file
@@ -0,0 +1,20 @@
|
||||
# CONSTELLATION REV1
|
||||
|
||||
A gasket 65% keyboard by [aeboards](https://aeboards.com/)
|
||||
|
||||
* Keyboard Maintainer: [Xelus22](https://github.com/Xelus22)
|
||||
* Hardware Supported: CONSTELLATION
|
||||
* Hardware Availability: Custom keyboard group buys
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make aeboards/constellation/rev1:default
|
||||
|
||||
Reset your keyboard in 3 ways:
|
||||
<ol>
|
||||
<li>Software reset on Fn + Backspace</li>
|
||||
<li>Bootmagic reset: hold down the top left key (usually escape) and plugin the keyboard</li>
|
||||
<li>Physical reset: on the back of the PCB, there is a ISP header which you should short the RST and GND together</li>
|
||||
</ol>
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||
18
keyboards/aeboards/constellation/rev1/rev1.c
Executable file
18
keyboards/aeboards/constellation/rev1/rev1.c
Executable file
@@ -0,0 +1,18 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rev1.h"
|
||||
36
keyboards/aeboards/constellation/rev1/rev1.h
Executable file
36
keyboards/aeboards/constellation/rev1/rev1.h
Executable file
@@ -0,0 +1,36 @@
|
||||
/* Copyright 2018 Jason Williams (Wilba)
|
||||
* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define ____ KC_NO
|
||||
|
||||
#define LAYOUT_all( \
|
||||
K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K213, K014, \
|
||||
K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \
|
||||
K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, \
|
||||
K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K312, K313, K314, \
|
||||
K400, K401, K402, K408, K409, K410, K412, K413, K414 \
|
||||
) { \
|
||||
{ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \
|
||||
{ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \
|
||||
{ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 }, \
|
||||
{ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, ____, K312, K313, K314 }, \
|
||||
{ K400, K401, K402, ____, ____, ____, ____, ____, K408, K409, K410, ____, K412, K413, K414 } \
|
||||
}
|
||||
22
keyboards/aeboards/constellation/rev1/rules.mk
Executable file
22
keyboards/aeboards/constellation/rev1/rules.mk
Executable file
@@ -0,0 +1,22 @@
|
||||
# MCU name
|
||||
MCU = atmega32u4
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||
CONSOLE_ENABLE = yes # Console for debug
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth
|
||||
AUDIO_ENABLE = no # Audio output
|
||||
LTO_ENABLE = yes
|
||||
61
keyboards/aeboards/constellation/rev2/config.h
Executable file
61
keyboards/aeboards/constellation/rev2/config.h
Executable file
@@ -0,0 +1,61 @@
|
||||
/* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config_common.h"
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0x4145 // AE
|
||||
#define PRODUCT_ID 0x065C // 65 - Constellation
|
||||
#define DEVICE_VER 0x0001
|
||||
#define MANUFACTURER AEBoards
|
||||
#define PRODUCT AEBoards Constellation Rev2
|
||||
|
||||
/* key matrix size */
|
||||
#define MATRIX_ROWS 5
|
||||
#define MATRIX_COLS 15
|
||||
|
||||
/* key matrix pins */
|
||||
#define MATRIX_ROW_PINS { B15, A14, A2, B13, B14 }
|
||||
#define MATRIX_COL_PINS { B12, H0, C15, C14, B11, B10, B2, B1, B0, A7, A6, A5, A4, A3 }
|
||||
#define UNUSED_PINS
|
||||
|
||||
/* COL2ROW or ROW2COL */
|
||||
#define DIODE_DIRECTION COL2ROW
|
||||
|
||||
/* Set 0 if debouncing isn't needed */
|
||||
#define DEBOUNCE 5
|
||||
|
||||
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||
#define LOCKING_SUPPORT_ENABLE
|
||||
|
||||
/* Locking resynchronize hack */
|
||||
#define LOCKING_RESYNC_ENABLE
|
||||
|
||||
// I2C setup
|
||||
#define I2C1_SCL 8
|
||||
#define I2C1_SDA 9
|
||||
#define I2C1_SCL_PAL_MODE 4
|
||||
#define I2C1_SDA_PAL_MODE 4
|
||||
#define I2C1_TIMINGR_PRESC 0U
|
||||
#define I2C1_TIMINGR_SCLDEL 11U
|
||||
#define I2C1_TIMINGR_SDADEL 0U
|
||||
#define I2C1_TIMINGR_SCLH 14U
|
||||
#define I2C1_TIMINGR_SCLL 42U
|
||||
|
||||
// I2C EEPROM
|
||||
#define EEPROM_I2C_24LC64
|
||||
27
keyboards/aeboards/constellation/rev2/halconf.h
Normal file
27
keyboards/aeboards/constellation/rev2/halconf.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Copyright 2020 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was auto-generated by:
|
||||
* `qmk chibios-confmigrate -i keyboards/aeboards/ext65/rev2/halconf.h -r platforms/chibios/common/configs/halconf.h`
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define HAL_USE_I2C TRUE
|
||||
|
||||
#include_next <halconf.h>
|
||||
|
||||
85
keyboards/aeboards/constellation/rev2/info.json
Normal file
85
keyboards/aeboards/constellation/rev2/info.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"keyboard_name": "Constellation",
|
||||
"url": "",
|
||||
"maintainer": "Xelus22",
|
||||
"width": 16,
|
||||
"height": 5,
|
||||
"layouts": {
|
||||
"LAYOUT_all": {
|
||||
"layout": [
|
||||
{"x":0, "y":0},
|
||||
{"x":1, "y":0},
|
||||
{"x":2, "y":0},
|
||||
{"x":3, "y":0},
|
||||
{"x":4, "y":0},
|
||||
{"x":5, "y":0},
|
||||
{"x":6, "y":0},
|
||||
{"x":7, "y":0},
|
||||
{"x":8, "y":0},
|
||||
{"x":9, "y":0},
|
||||
{"x":10, "y":0},
|
||||
{"x":11, "y":0},
|
||||
{"x":12, "y":0},
|
||||
{"x":13, "y":0},
|
||||
{"x":14, "y":0},
|
||||
{"x":15, "y":0},
|
||||
|
||||
{"x":0, "y":1, "w":1.5},
|
||||
{"x":1.5, "y":1},
|
||||
{"x":2.5, "y":1},
|
||||
{"x":3.5, "y":1},
|
||||
{"x":4.5, "y":1},
|
||||
{"x":5.5, "y":1},
|
||||
{"x":6.5, "y":1},
|
||||
{"x":7.5, "y":1},
|
||||
{"x":8.5, "y":1},
|
||||
{"x":9.5, "y":1},
|
||||
{"x":10.5, "y":1},
|
||||
{"x":11.5, "y":1},
|
||||
{"x":12.5, "y":1},
|
||||
{"x":13.5, "y":1, "w":1.5},
|
||||
{"x":15, "y":1},
|
||||
|
||||
{"x":0, "y":2, "w":1.75},
|
||||
{"x":1.75, "y":2},
|
||||
{"x":2.75, "y":2},
|
||||
{"x":3.75, "y":2},
|
||||
{"x":4.75, "y":2},
|
||||
{"x":5.75, "y":2},
|
||||
{"x":6.75, "y":2},
|
||||
{"x":7.75, "y":2},
|
||||
{"x":8.75, "y":2},
|
||||
{"x":9.75, "y":2},
|
||||
{"x":10.75, "y":2},
|
||||
{"label":"\"", "x":11.75, "y":2},
|
||||
{"x":12.75, "y":2, "w":2.25},
|
||||
{"x":15, "y":2},
|
||||
|
||||
{"x":0, "y":3, "w":2.25},
|
||||
{"x":2.25, "y":3},
|
||||
{"x":3.25, "y":3},
|
||||
{"x":4.25, "y":3},
|
||||
{"x":5.25, "y":3},
|
||||
{"x":6.25, "y":3},
|
||||
{"x":7.25, "y":3},
|
||||
{"x":8.25, "y":3},
|
||||
{"x":9.25, "y":3},
|
||||
{"x":10.25, "y":3},
|
||||
{"x":11.25, "y":3},
|
||||
{"x":12.25, "y":3, "w":1.75},
|
||||
{"x":14, "y":3},
|
||||
{"x":15, "y":3},
|
||||
|
||||
{"x":0, "y":4, "w":1.25},
|
||||
{"x":1.25, "y":4, "w":1.25},
|
||||
{"x":2.5, "y":4, "w":1.25},
|
||||
{"x":3.75, "y":4, "w":6.25},
|
||||
{"x":10, "y":4, "w":1.5},
|
||||
{"x":11.5, "y":4, "w":1.5},
|
||||
{"x":13, "y":4},
|
||||
{"x":14, "y":4},
|
||||
{"x":15, "y":4}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
27
keyboards/aeboards/constellation/rev2/mcuconf.h
Normal file
27
keyboards/aeboards/constellation/rev2/mcuconf.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Copyright 2020 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was auto-generated by:
|
||||
* `qmk chibios-confmigrate -i keyboards/aeboards/ext65/rev2/mcuconf.h -r platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h`
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include_next <mcuconf.h>
|
||||
|
||||
#undef STM32_I2C_USE_I2C1
|
||||
#define STM32_I2C_USE_I2C1 TRUE
|
||||
20
keyboards/aeboards/constellation/rev2/readme.md
Executable file
20
keyboards/aeboards/constellation/rev2/readme.md
Executable file
@@ -0,0 +1,20 @@
|
||||
# CONSTELLATION REV2
|
||||
|
||||
A gasket 65% keyboard by [aeboards](https://aeboards.com/)
|
||||
|
||||
* Keyboard Maintainer: [Xelus22](https://github.com/Xelus22)
|
||||
* Hardware Supported: CONSTELLATION
|
||||
* Hardware Availability: Custom keyboard group buys
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make aeboards/constellation/rev2:default
|
||||
|
||||
Reset your keyboard in 3 ways:
|
||||
<ol>
|
||||
<li>Software reset on Fn + Backspace</li>
|
||||
<li>Bootmagic reset: hold down the top left key (usually escape) and plugin the keyboard</li>
|
||||
<li>Physical reset button: on the back of the PCB, there are 2 open pins which you can short, labelled RESET</li>
|
||||
</ol>
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||
21
keyboards/aeboards/constellation/rev2/rev2.c
Executable file
21
keyboards/aeboards/constellation/rev2/rev2.c
Executable file
@@ -0,0 +1,21 @@
|
||||
/* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rev2.h"
|
||||
|
||||
void matrix_io_delay(void) {
|
||||
__asm__ volatile("nop\nnop\nnop\n");
|
||||
}
|
||||
35
keyboards/aeboards/constellation/rev2/rev2.h
Executable file
35
keyboards/aeboards/constellation/rev2/rev2.h
Executable file
@@ -0,0 +1,35 @@
|
||||
/* Copyright 2021 Harrison Chan (Xelus)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define ____ KC_NO
|
||||
|
||||
#define LAYOUT_all( \
|
||||
K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K213, K014, \
|
||||
K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \
|
||||
K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K214, \
|
||||
K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K312, K313, K314, \
|
||||
K400, K401, K402, K408, K409, K410, K412, K413, K414 \
|
||||
) { \
|
||||
{ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \
|
||||
{ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \
|
||||
{ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 }, \
|
||||
{ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, ____, K312, K313, K314 }, \
|
||||
{ K400, K401, K402, ____, ____, ____, ____, ____, K408, K409, K410, ____, K412, K413, K414 } \
|
||||
}
|
||||
20
keyboards/aeboards/constellation/rev2/rules.mk
Executable file
20
keyboards/aeboards/constellation/rev2/rules.mk
Executable file
@@ -0,0 +1,20 @@
|
||||
# MCU name
|
||||
MCU = STM32L433
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||
CONSOLE_ENABLE = yes # Console for debug
|
||||
COMMAND_ENABLE = no # Commands for debug and configuration
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth
|
||||
AUDIO_ENABLE = no # Audio output
|
||||
|
||||
EEPROM_DRIVER = i2c
|
||||
@@ -1,22 +1 @@
|
||||
# MCU name
|
||||
MCU = atmega32u4
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = atmel-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||
CONSOLE_ENABLE = yes # Console for debug
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||
BLUETOOTH_ENABLE = no # Enable Bluetooth
|
||||
AUDIO_ENABLE = no # Audio output
|
||||
LTO_ENABLE = yes
|
||||
DEFAULT_FOLDER = aeboards/constellation/rev1
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# MCU name
|
||||
MCU = STM32F042
|
||||
|
||||
BOARD = ST_NUCLEO32_F042K6
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# MCU name
|
||||
MCU = STM32F072
|
||||
|
||||
# Bootloader selection
|
||||
BOOTLOADER = stm32-dfu
|
||||
|
||||
# Build Options
|
||||
# change yes to no to disable
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user