Compare commits
706
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c1ec2f187 | ||
|
|
7dadc8d9ee | ||
|
|
cd7146d611 | ||
|
|
853833d18a | ||
|
|
c500803d95 | ||
|
|
68a92d0219 | ||
|
|
5221d93fc0 | ||
|
|
22deb13ac0 | ||
|
|
58b875d5ed | ||
|
|
12f5d6070f | ||
|
|
5e0b1fa3cc | ||
|
|
1ee3a7c3e2 | ||
|
|
43c13db970 | ||
|
|
b5818d22af | ||
|
|
fd7a5fc057 | ||
|
|
5af1ca9363 | ||
|
|
c4d096e60c | ||
|
|
174b0743a9 | ||
|
|
4b50533560 | ||
|
|
1555dae1c8 | ||
|
|
8b5717470a | ||
|
|
38b2cf03b0 | ||
|
|
1293b07c9e | ||
|
|
aa4c41ddf7 | ||
|
|
628f423171 | ||
|
|
a9d179f93a | ||
|
|
4955dc0844 | ||
|
|
3f66f0d67a | ||
|
|
bc7ab5170a | ||
|
|
d61649f748 | ||
|
|
9a33a78574 | ||
|
|
030c0c60f3 | ||
|
|
19ff834d99 | ||
|
|
400a078a05 | ||
|
|
618bebc46b | ||
|
|
dee23ec52e | ||
|
|
baca85b8cd | ||
|
|
00b1cfcb3b | ||
|
|
a9dbf5ef70 | ||
|
|
a0b1153ec3 | ||
|
|
39a5e0eba0 | ||
|
|
308bb6f9b8 | ||
|
|
86d96848a2 | ||
|
|
98100a9bad | ||
|
|
e66562bb25 | ||
|
|
902ebc2e83 | ||
|
|
403d60e214 | ||
|
|
1c5130e78a | ||
|
|
481a5dea2e | ||
|
|
320129633d | ||
|
|
0dea21a53e | ||
|
|
79625e9c8a | ||
|
|
0cff1734ce | ||
|
|
e1d8f48cb9 | ||
|
|
752737034b | ||
|
|
ecf1d2ce98 | ||
|
|
bb743c6b62 | ||
|
|
f02223d6ba | ||
|
|
b87980965d | ||
|
|
2255eea14e | ||
|
|
0ccf2d0c33 | ||
|
|
5ce6ec9ea7 | ||
|
|
97e1c3e913 | ||
|
|
9937731ad8 | ||
|
|
bd4f3728f6 | ||
|
|
009a6ccd2a | ||
|
|
6606ab92bd | ||
|
|
595248cc10 | ||
|
|
ffc02e6c98 | ||
|
|
ac2d911566 | ||
|
|
633dfdbddd | ||
|
|
54cd8408e8 | ||
|
|
384011aab3 | ||
|
|
95ded7b871 | ||
|
|
607d83b795 | ||
|
|
f4872c52bd | ||
|
|
505e2d2aa4 | ||
|
|
77ecfc3b46 | ||
|
|
8107288838 | ||
|
|
05e76cc733 | ||
|
|
816eabb1d1 | ||
|
|
9b6e24947d | ||
|
|
5778d344e0 | ||
|
|
b785f2efbf | ||
|
|
224f59450e | ||
|
|
b80cbe931e | ||
|
|
87adb0bdb7 | ||
|
|
78c7572a2c | ||
|
|
bbed1f64a7 | ||
|
|
ac071902c0 | ||
|
|
62a4cd31c5 | ||
|
|
751961b3b3 | ||
|
|
30625548e5 | ||
|
|
9451771ccb | ||
|
|
12442046e2 | ||
|
|
47baeb6b6b | ||
|
|
263561868c | ||
|
|
9bc58b039b | ||
|
|
82c0ff8452 | ||
|
|
2d7e996e4b | ||
|
|
0ae76e40c2 | ||
|
|
343c285321 | ||
|
|
6492852627 | ||
|
|
acc032a69c | ||
|
|
950a3be01d | ||
|
|
6626321e80 | ||
|
|
7276f5e1d5 | ||
|
|
5f9c4f8432 | ||
|
|
a1cd324731 | ||
|
|
c2c5e6666d | ||
|
|
f7d6ede033 | ||
|
|
25f9e2a110 | ||
|
|
8ef6888a28 | ||
|
|
78a7be63ef | ||
|
|
f108515a6e | ||
|
|
ad4e198aea | ||
|
|
5aad79135f | ||
|
|
5fc6981c16 | ||
|
|
942df26432 | ||
|
|
b3860be638 | ||
|
|
8ecabb0789 | ||
|
|
d3fc88b24f | ||
|
|
dfb2e52e7b | ||
|
|
96af869d79 | ||
|
|
4c6429ae76 | ||
|
|
7d2877a8e9 | ||
|
|
a25f3ef2fc | ||
|
|
15ace9d094 | ||
|
|
58aba0a147 | ||
|
|
199db16ec0 | ||
|
|
c364fabf57 | ||
|
|
15a2d5beaf | ||
|
|
5b956f7ff1 | ||
|
|
dc42248a88 | ||
|
|
eeeab399be | ||
|
|
39d451793b | ||
|
|
5db888fba0 | ||
|
|
1b91687fac | ||
|
|
7d38cd4a78 | ||
|
|
899b90decc | ||
|
|
8dcb1f075d | ||
|
|
5588f9b7a9 | ||
|
|
717620e8dd | ||
|
|
877d462dbc | ||
|
|
d3cf315175 | ||
|
|
f47129902a | ||
|
|
5a3c69ec32 | ||
|
|
392c547b87 | ||
|
|
38527a5122 | ||
|
|
77412a959f | ||
|
|
3a5ebe387e | ||
|
|
1db412e970 | ||
|
|
a3c931392a | ||
|
|
b94f701db8 | ||
|
|
b79ff124e6 | ||
|
|
60baf6d05f | ||
|
|
cb9b22804a | ||
|
|
d2dfd03551 | ||
|
|
f3bdee9bd2 | ||
|
|
7a3de1edbb | ||
|
|
0464fbcbe2 | ||
|
|
12226804f3 | ||
|
|
f06d71bd0c | ||
|
|
112d5a1cb2 | ||
|
|
b70658e37d | ||
|
|
80a2770263 | ||
|
|
765ef62858 | ||
|
|
0e58fcc236 | ||
|
|
4bf0330974 | ||
|
|
6d585d3eeb | ||
|
|
0286a5dd58 | ||
|
|
b3cadbae5d | ||
|
|
e26e874d1c | ||
|
|
c9c214267d | ||
|
|
6957c1ca03 | ||
|
|
f5aafda340 | ||
|
|
f1fe428f59 | ||
|
|
614c9768ad | ||
|
|
5828c4df8d | ||
|
|
6cf32b8a94 | ||
|
|
bc6487505a | ||
|
|
d1e8104442 | ||
|
|
91414084d6 | ||
|
|
372ff746ad | ||
|
|
ab297281d3 | ||
|
|
2cbba19bf9 | ||
|
|
b5001c983e | ||
|
|
7d4d6152ab | ||
|
|
f2c1022c7f | ||
|
|
771e362a63 | ||
|
|
3eba2c3dd3 | ||
|
|
305f66ad3d | ||
|
|
3191a87f46 | ||
|
|
a9493d46aa | ||
|
|
6499ee4312 | ||
|
|
f26897df71 | ||
|
|
8ae07ea9e2 | ||
|
|
cb94b4fe28 | ||
|
|
f51f222fb4 | ||
|
|
d3162ea2e8 | ||
|
|
fa1f0b05ce | ||
|
|
c7bb002b7c | ||
|
|
b1de039f21 | ||
|
|
e086ecd0bb | ||
|
|
f612ca8bdc | ||
|
|
5b8441c57d | ||
|
|
919d89d52f | ||
|
|
479d51df87 | ||
|
|
687424e732 | ||
|
|
a2a613f22d | ||
|
|
a34d0f93a3 | ||
|
|
8e62be0b9e | ||
|
|
95bcc5e0fd | ||
|
|
19ef8afe70 | ||
|
|
5fdea9d34f | ||
|
|
32938ec2af | ||
|
|
8d29a40954 | ||
|
|
a75a2bbf8b | ||
|
|
f96a4c3557 | ||
|
|
1d426f109a | ||
|
|
8827d0e0c2 | ||
|
|
edfb4f8d4e | ||
|
|
13ce388e9a | ||
|
|
316902b2c3 | ||
|
|
6667cdeed9 | ||
|
|
de44c57081 | ||
|
|
30a1bc9893 | ||
|
|
cf4b421abd | ||
|
|
1a9e1c2430 | ||
|
|
bde9e7ea6b | ||
|
|
fc9c6585af | ||
|
|
be9711a021 | ||
|
|
bfa7f63486 | ||
|
|
8f19267886 | ||
|
|
fab6e41810 | ||
|
|
c3ceac1ed9 | ||
|
|
bb01790d71 | ||
|
|
9cf7bdea29 | ||
|
|
6da6ff6cc0 | ||
|
|
baa04913c3 | ||
|
|
64c0861097 | ||
|
|
522016137b | ||
|
|
40d0f17ae2 | ||
|
|
c88e71d52a | ||
|
|
c3d284c97b | ||
|
|
19b572da30 | ||
|
|
e6c4017ad0 | ||
|
|
b862912fb1 | ||
|
|
02f7f57130 | ||
|
|
c6b3d7c675 | ||
|
|
1b2a5a4b14 | ||
|
|
c0190d35d1 | ||
|
|
4d0219b184 | ||
|
|
85fc72232a | ||
|
|
cbb13b0d22 | ||
|
|
bd6ec4c41e | ||
|
|
d843b3d619 | ||
|
|
ca9c40f084 | ||
|
|
6a85729f10 | ||
|
|
13414ec9b8 | ||
|
|
74faee0f73 | ||
|
|
3f0027aa90 | ||
|
|
d22aa1ed6c | ||
|
|
23d51f65d0 | ||
|
|
cad356efca | ||
|
|
70e83c13cc | ||
|
|
7ca0a1b6ab | ||
|
|
9bd5536d07 | ||
|
|
eaa3b9a368 | ||
|
|
599c468de8 | ||
|
|
9f21814395 | ||
|
|
cb8a551683 | ||
|
|
7f1156d81c | ||
|
|
5beee08166 | ||
|
|
1334129078 | ||
|
|
216b492f24 | ||
|
|
1b65bb9cc3 | ||
|
|
0f4ddd164f | ||
|
|
e6aadc414b | ||
|
|
883a78ad9d | ||
|
|
15d23d3009 | ||
|
|
e2c2b8c1df | ||
|
|
5133c30242 | ||
|
|
69e1e19bf9 | ||
|
|
46f08f7423 | ||
|
|
352b9928ca | ||
|
|
87854d5781 | ||
|
|
1b3f8f9eb4 | ||
|
|
6438c15dd3 | ||
|
|
dbe29991f0 | ||
|
|
a5e9a3de05 | ||
|
|
edf1b251c0 | ||
|
|
9ff4314840 | ||
|
|
3ad0986ae7 | ||
|
|
6bfc9dd9db | ||
|
|
9b8a0d465e | ||
|
|
119741b736 | ||
|
|
2fe958783c | ||
|
|
1c59ef6b80 | ||
|
|
9e44e4ba4f | ||
|
|
b8e14ea067 | ||
|
|
525071c205 | ||
|
|
bfe03b0564 | ||
|
|
04b87ce2eb | ||
|
|
81acc47cd6 | ||
|
|
6e426b1403 | ||
|
|
6509e53a9b | ||
|
|
5b42b3d11d | ||
|
|
8bd515296d | ||
|
|
2bbf66c0ee | ||
|
|
d716973642 | ||
|
|
25f7a87a79 | ||
|
|
0619a16be2 | ||
|
|
4a3802f344 | ||
|
|
105f5642ef | ||
|
|
54ab57cea6 | ||
|
|
e3e6c0347e | ||
|
|
4d6706ce61 | ||
|
|
39c5aff864 | ||
|
|
450f438538 | ||
|
|
0270c745ce | ||
|
|
e2dfcd5b0f | ||
|
|
68fa3c2def | ||
|
|
cde7469191 | ||
|
|
7c1a1396ca | ||
|
|
7f052f21aa | ||
|
|
dff667751b | ||
|
|
2625807c1a | ||
|
|
7af283fdbf | ||
|
|
c7ffe3b926 | ||
|
|
46339c5f86 | ||
|
|
cf69598fd1 | ||
|
|
594f66ab23 | ||
|
|
01e0808e41 | ||
|
|
2dc443ff1e | ||
|
|
0ab0586dfa | ||
|
|
88fa6bf25a | ||
|
|
9346490e4a | ||
|
|
7d4e5d6122 | ||
|
|
d4a03b23c8 | ||
|
|
47b5c94310 | ||
|
|
079a984f8d | ||
|
|
b6e35c4155 | ||
|
|
c9d1ac5d8f | ||
|
|
427c635ed8 | ||
|
|
0703bcd0a8 | ||
|
|
984c6bb7f5 | ||
|
|
d27095dacd | ||
|
|
9228b5c4cd | ||
|
|
7fe87703e5 | ||
|
|
c65edbeebc | ||
|
|
b6bf34279c | ||
|
|
68e444aa3b | ||
|
|
3d12930067 | ||
|
|
3de7f32a3a | ||
|
|
216fe063e0 | ||
|
|
ef6195271e | ||
|
|
86eb273e46 | ||
|
|
22813c06dc | ||
|
|
9840f0a8b6 | ||
|
|
69539432b5 | ||
|
|
4433760cab | ||
|
|
ba2ce98a3e | ||
|
|
1e171fcfb0 | ||
|
|
dc88b1a752 | ||
|
|
3f2a118a39 | ||
|
|
b8c80e6ba5 | ||
|
|
405bbc5464 | ||
|
|
5371fe1cc2 | ||
|
|
cdce79bd07 | ||
|
|
87395d0b0d | ||
|
|
7050a0dac1 | ||
|
|
bc01b53de5 | ||
|
|
680c143ad7 | ||
|
|
38c3f2d94c | ||
|
|
5344806a85 | ||
|
|
21f29a1a56 | ||
|
|
c5149b2521 | ||
|
|
f9a25c9612 | ||
|
|
4b4d3bf790 | ||
|
|
3a11ed4e43 | ||
|
|
238dc0f0ae | ||
|
|
0568fc5ed2 | ||
|
|
37241ee6f2 | ||
|
|
1f91dd227f | ||
|
|
facfa05062 | ||
|
|
6fd6c7f176 | ||
|
|
d947cc2499 | ||
|
|
5db52e5dc2 | ||
|
|
1249814e93 | ||
|
|
dda8e9470f | ||
|
|
72482d4ff9 | ||
|
|
a50049e63b | ||
|
|
2970e56324 | ||
|
|
aa1ad8db85 | ||
|
|
7f865cfee9 | ||
|
|
c7b9fe90a6 | ||
|
|
0c7009b973 | ||
|
|
d791361f22 | ||
|
|
5719956441 | ||
|
|
eba9fc0213 | ||
|
|
556fb634bb | ||
|
|
e39617a665 | ||
|
|
9f6c3819bd | ||
|
|
91c8ec0cb0 | ||
|
|
314283a37c | ||
|
|
c3e5d91b6b | ||
|
|
c769c20af1 | ||
|
|
2a43cefbe6 | ||
|
|
68960b7b14 | ||
|
|
ad85efcb14 | ||
|
|
7c221416cc | ||
|
|
9ba1b2fc57 | ||
|
|
caf1e5c7f0 | ||
|
|
2b660a47c7 | ||
|
|
0c45e26c98 | ||
|
|
fdbaf9bf63 | ||
|
|
08a1197b7e | ||
|
|
87a9ea5b14 | ||
|
|
2b8d25559a | ||
|
|
3db9189cbb | ||
|
|
a0c379e8c7 | ||
|
|
0ae4964545 | ||
|
|
69651b3f91 | ||
|
|
ce9508aa88 | ||
|
|
aa182936ba | ||
|
|
745bbac93b | ||
|
|
5c3c15f930 | ||
|
|
4919b03bd1 | ||
|
|
18c18e3999 | ||
|
|
01020b50d9 | ||
|
|
00f422375b | ||
|
|
25807902c9 | ||
|
|
0bbef425a4 | ||
|
|
ec65d8a2a9 | ||
|
|
47df8f3414 | ||
|
|
c560ee4b7e | ||
|
|
74080150e0 | ||
|
|
ab7ddc1629 | ||
|
|
000bef969c | ||
|
|
c8e0aec596 | ||
|
|
ecf4427c76 | ||
|
|
d299e90954 | ||
|
|
98bb92acdb | ||
|
|
0e77149444 | ||
|
|
e6c21f0a72 | ||
|
|
da9f6d7c72 | ||
|
|
97975b6d36 | ||
|
|
ad98cc173b | ||
|
|
5a33c80d65 | ||
|
|
f661bf66f1 | ||
|
|
f1e1c41d68 | ||
|
|
a7ed250c4e | ||
|
|
62c06202e0 | ||
|
|
23ad5ca244 | ||
|
|
5712717ef8 | ||
|
|
da54e89839 | ||
|
|
57b8377f5a | ||
|
|
fbb718c532 | ||
|
|
5a469ea615 | ||
|
|
2099abb126 | ||
|
|
4b4e939d10 | ||
|
|
e0094915fe | ||
|
|
aa6e2e611b | ||
|
|
ce8331b467 | ||
|
|
54ff4d57b0 | ||
|
|
3abb0c05ba | ||
|
|
acc84f6a09 | ||
|
|
74b0d195d9 | ||
|
|
920e001bab | ||
|
|
4c2ceed5b6 | ||
|
|
515c17b8dd | ||
|
|
2ffb02abde | ||
|
|
3237c8842a | ||
|
|
fde468a162 | ||
|
|
f854441cf7 | ||
|
|
408020c244 | ||
|
|
f806f3ad66 | ||
|
|
7c1c9a7979 | ||
|
|
283cb5a8ac | ||
|
|
5f21674b8f | ||
|
|
fe6a84d6c9 | ||
|
|
f7cb8ca969 | ||
|
|
64dad049f9 | ||
|
|
1115213d5a | ||
|
|
bc01ec0e4b | ||
|
|
62518b5163 | ||
|
|
736e624366 | ||
|
|
d7298cafd0 | ||
|
|
70783fb28f | ||
|
|
45a5f629e5 | ||
|
|
ec73337929 | ||
|
|
148b84b7d1 | ||
|
|
3cf855bd10 | ||
|
|
9deb0f8fff | ||
|
|
8c86686d01 | ||
|
|
c451487401 | ||
|
|
5defbc1580 | ||
|
|
b5af840dcc | ||
|
|
1b170ff664 | ||
|
|
31a6da1b21 | ||
|
|
cb6dfd83d8 | ||
|
|
50ea274205 | ||
|
|
c7960c090a | ||
|
|
85b2545409 | ||
|
|
e10881db3e | ||
|
|
977feabe6e | ||
|
|
a6c9d1232a | ||
|
|
4024e6de85 | ||
|
|
f3df584d3a | ||
|
|
60a0ab5c93 | ||
|
|
c908847577 | ||
|
|
bd027e596e | ||
|
|
51c3568f7a | ||
|
|
4f8db7d63f | ||
|
|
f844c2fb07 | ||
|
|
f7041988e4 | ||
|
|
71c650cd45 | ||
|
|
3c6ac31eab | ||
|
|
20a99ef7ef | ||
|
|
c69a98096b | ||
|
|
92afebe2c7 | ||
|
|
5b82eb39a8 | ||
|
|
7b120515d8 | ||
|
|
b480bbd666 | ||
|
|
5e5ac81f53 | ||
|
|
adcd59848a | ||
|
|
937cbc656e | ||
|
|
aead384282 | ||
|
|
b717600c37 | ||
|
|
f38be5119e | ||
|
|
f8de686296 | ||
|
|
0703fb8c68 | ||
|
|
8d0915de6e | ||
|
|
ef33d7e2c4 | ||
|
|
bba88eb1f2 | ||
|
|
7b35cf72f7 | ||
|
|
9603489f4a | ||
|
|
d4cd2a6853 | ||
|
|
c4d2f72df1 | ||
|
|
1a07aee7a6 | ||
|
|
415d79a3ef | ||
|
|
fd59f83556 | ||
|
|
7adcfa77fa | ||
|
|
b338fbca3c | ||
|
|
aba3a3fd23 | ||
|
|
cb680508a5 | ||
|
|
2104c975be | ||
|
|
339e1e14c2 | ||
|
|
dca3b0d733 | ||
|
|
c52eb528ea | ||
|
|
3948e74711 | ||
|
|
4672d4a686 | ||
|
|
befa9baf20 | ||
|
|
077cda545e | ||
|
|
e934ce2c23 | ||
|
|
b10ff42df2 | ||
|
|
afb6ff6a74 | ||
|
|
6828335dc5 | ||
|
|
966297710b | ||
|
|
443d558ac2 | ||
|
|
2cd0b64251 | ||
|
|
7ad3c18e3f | ||
|
|
fc11427019 | ||
|
|
2f00fb9186 | ||
|
|
ea1f21106c | ||
|
|
47ca068628 | ||
|
|
f07cc134bb | ||
|
|
1d98ce063c | ||
|
|
9ddb9f04ce | ||
|
|
8aee3c427b | ||
|
|
6a6ad0dda6 | ||
|
|
12116c70ee | ||
|
|
7d6699cf9c | ||
|
|
48b9be3f76 | ||
|
|
760c57c29c | ||
|
|
c6cc88ba7b | ||
|
|
779471e3e4 | ||
|
|
adb9a6e59f | ||
|
|
d48bcec5ba | ||
|
|
80d2282313 | ||
|
|
a4474602d8 | ||
|
|
d28be0640e | ||
|
|
5b17833c6e | ||
|
|
e8e9a1e7e5 | ||
|
|
d7740c2d28 | ||
|
|
f110589f91 | ||
|
|
b3c1cdf63d | ||
|
|
6b789be1e1 | ||
|
|
12f307228b | ||
|
|
848ea8b064 | ||
|
|
438c3840a7 | ||
|
|
fef6f4cba3 | ||
|
|
d38543a820 | ||
|
|
2a76201ca4 | ||
|
|
2e84e9808c | ||
|
|
ee492632ac | ||
|
|
fd16bc3053 | ||
|
|
64f11b42f4 | ||
|
|
7ba610df77 | ||
|
|
a76bd7b974 | ||
|
|
7999620db2 | ||
|
|
585eb8a5a3 | ||
|
|
f1523adcdf | ||
|
|
1113c7874f | ||
|
|
ab03311717 | ||
|
|
d13971b7ce | ||
|
|
5bc94fd677 | ||
|
|
90dfa5678b | ||
|
|
48ba8435b1 | ||
|
|
cf2c2d6b93 | ||
|
|
4b8668e0ef | ||
|
|
0bc5982970 | ||
|
|
2ae74c1e7f | ||
|
|
abd4c87b1e | ||
|
|
fb3103e458 | ||
|
|
c70943da18 | ||
|
|
2efd0dc81d | ||
|
|
8b8012a431 | ||
|
|
0716f55880 | ||
|
|
bcc95abe53 | ||
|
|
bb7852a3e4 | ||
|
|
d79c7e9c04 | ||
|
|
fa4d9ebbf6 | ||
|
|
ec8cdf1e26 | ||
|
|
1d6e0cf6a4 | ||
|
|
b06d56bb2d | ||
|
|
50c9f7b84b | ||
|
|
dd6a6ca85a | ||
|
|
4d5003f49d | ||
|
|
7226a4164f | ||
|
|
c7030ad47d | ||
|
|
11770aaa3a | ||
|
|
f8212ca59e | ||
|
|
dbf3dd86b4 | ||
|
|
0fe3adc267 | ||
|
|
f45b20602b | ||
|
|
f6bf044ba0 | ||
|
|
420e4dc077 | ||
|
|
3c77c1a9a8 | ||
|
|
5074a923d1 | ||
|
|
bfd8030438 | ||
|
|
af84c5bb00 | ||
|
|
3de7150408 | ||
|
|
6fdf34e16f | ||
|
|
7bdf19387d | ||
|
|
a27c614a8b | ||
|
|
b7b93ad606 | ||
|
|
dbf796256b | ||
|
|
f38b90ad52 | ||
|
|
5f3fe509a4 | ||
|
|
189bf0d7a4 | ||
|
|
60531bbf07 | ||
|
|
fd9134c911 | ||
|
|
f33f00d8a9 | ||
|
|
f2d35466a5 | ||
|
|
bce9fc929e | ||
|
|
cdaae5fb9f | ||
|
|
9fc9059b0b | ||
|
|
2c1fe31211 | ||
|
|
13f53ae4f8 | ||
|
|
eac739fdb4 | ||
|
|
5ae3de993d | ||
|
|
e79c97c4d0 | ||
|
|
45c7bc8008 | ||
|
|
7de0b2549b | ||
|
|
39b52326b6 | ||
|
|
b35c900fae | ||
|
|
7cea74e466 | ||
|
|
5f3e43e7b8 | ||
|
|
a84407b609 | ||
|
|
000511deff | ||
|
|
fe37c261a2 | ||
|
|
cbdbb71d79 | ||
|
|
5f786e649a | ||
|
|
f76bf34d8d | ||
|
|
e799574730 | ||
|
|
1a5b12c7a0 | ||
|
|
d2acc75ba8 | ||
|
|
74bcfbd940 | ||
|
|
1db45f2cf2 | ||
|
|
6e467fe8cd | ||
|
|
441c462e59 | ||
|
|
89b4716012 | ||
|
|
e51e9a71a0 | ||
|
|
02273a3601 | ||
|
|
e0018b23aa | ||
|
|
b06f384350 | ||
|
|
7dddb9d111 | ||
|
|
0d38154134 | ||
|
|
7dd84c7ac8 | ||
|
|
ffd0088378 | ||
|
|
f0c486c30d | ||
|
|
010ab1182d | ||
|
|
7e64ca1f83 | ||
|
|
2fcff92523 | ||
|
|
8beeb5f7b2 | ||
|
|
7d2b5f285f | ||
|
|
b8eb4e9bcb | ||
|
|
733b904ec4 | ||
|
|
59a3b41480 | ||
|
|
28b41451f8 | ||
|
|
126c9295ac | ||
|
|
0e4a162667 | ||
|
|
15fd537fa8 | ||
|
|
557c9df9a0 |
@@ -0,0 +1,8 @@
|
||||
*.pro.user*
|
||||
*.o
|
||||
ui_*
|
||||
moc_*
|
||||
qrc_*
|
||||
OpenRGB
|
||||
Makefile
|
||||
OpenRGB-x86_64.AppImage
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
# swy: some useful references; the MSVC part of the CI script is based on the one from bind9, by Michał Kępień:
|
||||
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md
|
||||
# https://gitlab.isc.org/isc-projects/bind9/commit/facc6a051fcac70fbbc61cb92a37be8c3e4db5ec#587d266bb27a4dc3022bbed44dfa19849df3044c_718_731
|
||||
# https://www.kittell.net/code/powershell-unix-sed-equivalent-change-text-file/
|
||||
# https://powershell.org/forums/topic/how-to-use-ansi-vt100-formatting-in-powershell-ooh-pretty-colors/
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# OpenRGB GitLab CI Configuration #
|
||||
#-----------------------------------------------------------------------#
|
||||
|
||||
.shared_windows_runners:
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
- windows-1809
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
before_script:
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Linux (AppImage) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_linux:
|
||||
image: ubuntu:bionic
|
||||
stage: build
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
|
||||
- ./scripts/build-appimage.sh
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- OpenRGB-x86_64.AppImage
|
||||
expire_in: 1337 years
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Windows (32-bit) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_windows_32:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: build
|
||||
script:
|
||||
- $esc = "$([char]27)"
|
||||
- $count = 0
|
||||
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
|
||||
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
|
||||
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
|
||||
|
||||
|
||||
- _fold_start_ 'configuring the msvc environment variables'
|
||||
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
|
||||
- '& cmd.exe /C "vcvarsall.bat x86 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
|
||||
- mkdir _qt
|
||||
- mkdir _qt_download
|
||||
- Push-Location _qt_download
|
||||
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
|
||||
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
|
||||
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'extracting the downloaded qt binaries'
|
||||
- 7z x qt-base.7z '-o../_qt' -y
|
||||
- 7z x qt-tools.7z '-o../_qt' -y
|
||||
- 7z x qt-jom.zip '-o../_qt' -y
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
|
||||
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019\mkspecs\qconfig.pri'
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
|
||||
- mkdir _build; cd _build
|
||||
- ..\_qt\5.15.0\msvc2019\bin\qmake ..\OpenRGB.pro
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
|
||||
- ..\_qt\jom
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
|
||||
- ..\_qt\5.15.0\msvc2019\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
|
||||
- mv release 'OpenRGB Windows 32-bit'
|
||||
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
|
||||
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
|
||||
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
|
||||
- 7z a -mx9 -r -y "OpenRGB_${rversion}_32_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 32-bit'
|
||||
- _fold_final_
|
||||
# cache:
|
||||
# key: same-key
|
||||
# paths:
|
||||
# - C:\vcpkg\installed\
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/*.7z
|
||||
expire_in: 1337 years
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Windows (64-bit) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_windows_64:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: build
|
||||
script:
|
||||
- $esc = "$([char]27)"
|
||||
- $count = 0
|
||||
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
|
||||
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
|
||||
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
|
||||
|
||||
|
||||
- _fold_start_ 'configuring the msvc environment variables'
|
||||
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
|
||||
- '& cmd.exe /C "vcvarsall.bat x64 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
|
||||
- mkdir _qt
|
||||
- mkdir _qt_download
|
||||
- Push-Location _qt_download
|
||||
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
|
||||
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
|
||||
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'extracting the downloaded qt binaries'
|
||||
- 7z x qt-base.7z '-o../_qt' -y
|
||||
- 7z x qt-tools.7z '-o../_qt' -y
|
||||
- 7z x qt-jom.zip '-o../_qt' -y
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
|
||||
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019_64\mkspecs\qconfig.pri'
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
|
||||
- mkdir _build; cd _build
|
||||
- ..\_qt\5.15.0\msvc2019_64\bin\qmake ..\OpenRGB.pro
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
|
||||
- ..\_qt\jom
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
|
||||
- ..\_qt\5.15.0\msvc2019_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
|
||||
- mv release 'OpenRGB Windows 64-bit'
|
||||
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
|
||||
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
|
||||
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
|
||||
- 7z a -mx9 -r -y "OpenRGB_${rversion}_64_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 64-bit'
|
||||
- _fold_final_
|
||||
# cache:
|
||||
# key: same-key
|
||||
# paths:
|
||||
# - C:\vcpkg\installed\
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/*.7z
|
||||
expire_in: 1337 years
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "razer-drivers-win32"]
|
||||
path = razer-drivers-win32
|
||||
url = https://github.com/rsandoz/razer-drivers-win32
|
||||
@@ -0,0 +1,262 @@
|
||||
#---------------------------------------------------------------#
|
||||
# OpenRGB udev rules #
|
||||
# #
|
||||
# Adam Honse (CalcProgrammer1) 5/29/2020 #
|
||||
#---------------------------------------------------------------#
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# User I2C/SMBus Access #
|
||||
#---------------------------------------------------------------#
|
||||
KERNEL=="i2c-[0-99]*", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# User hidraw Access #
|
||||
#---------------------------------------------------------------#
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# AMD Wraith Prism #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0051", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# ASUS Aura Core Devices #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1854", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1869", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1866", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# ASUS Aura USB Devices #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1867", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1889", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a3", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f3", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Cooler Master Peripheral Devices #
|
||||
# #
|
||||
# Mousemats: #
|
||||
# Cooler Master MP750 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Corsair Lighting Node Devices #
|
||||
# #
|
||||
# Corsair Lighting Node Core #
|
||||
# Corsair Lighting Node Pro #
|
||||
# Corsair Commander Pro #
|
||||
# Corsair LS100 #
|
||||
# Corsair 1000D Obsidian #
|
||||
# Corsair Spec Omega RGB #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1a", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c0b", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1e", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d00", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d04", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Corsair Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# Corsair K55 RGB #
|
||||
# Corsair K65 RGB #
|
||||
# Corsair K65 RGB Lux #
|
||||
# Corsair K65 RGB Rapidfire #
|
||||
# Corsair K68 RGB #
|
||||
# Corsair K70 RGB #
|
||||
# Corsair K70 RGB Lux #
|
||||
# Corsair K70 RGB Rapidfire #
|
||||
# Corsair K70 RGB MK2 #
|
||||
# Corsair K70 RGB MK2 SE #
|
||||
# Corsair K70 RGB MK2 LP #
|
||||
# Corsair K95 RGB #
|
||||
# Corsair K95 Platinum #
|
||||
# Corsair Strafe #
|
||||
# Corsair Strafe MK2 #
|
||||
# #
|
||||
# Mice: #
|
||||
# Corsair M65 Pro #
|
||||
# Corsair M65 RGB Elite #
|
||||
# #
|
||||
# Mousemats: #
|
||||
# Corsair MM800 RGB Polaris #
|
||||
# #
|
||||
# Headset Stands: #
|
||||
# Corsair ST100 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3d", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b17", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b37", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b39", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b4f", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b13", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b33", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b38", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b49", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6b", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b55", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b11", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# HyperX Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# HyperX Alloy Elite #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Logitech Peripheral Devices #
|
||||
# #
|
||||
# Mice: #
|
||||
# Logitech G203 Prodigy #
|
||||
# Logitech G403 Prodigy #
|
||||
# Logitech G403 Hero #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# MSI Mysticlight #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="3EA4", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4559", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B10", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B93", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B94", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B96", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C34", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C35", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C36", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C37", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C42", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C56", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C59", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C60", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C67", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C70", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C71", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C73", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C75", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C76", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C77", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C79", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C80", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C81", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C82", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C83", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C84", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C85", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C86", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C87", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C88", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C89", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C90", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C91", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C92", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C94", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C96", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C98", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C99", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="905D", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# MSI/SteelSeries 3-Zone Laptop Keyboard #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1770", ATTR{idProduct}=="FF00", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# NZXT Hue 2 Devices #
|
||||
# #
|
||||
# NZXT Hue 2 #
|
||||
# NZXT Smart Device V2 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# NZXT Kraken #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Redragon Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# Redragon K550 Yama #
|
||||
# Redragon K552 Kumara #
|
||||
# Redragon K556 Devarajas #
|
||||
# Tecware Phantom Elite #
|
||||
# #
|
||||
# Mice: #
|
||||
# Redragon M711 Cobra #
|
||||
# Redragon M715 Dagger #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5204", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5104", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5004", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Gigabyte/Aorus RGB Fusion 2 USB #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="8297", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="5702", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# SteelSeries Peripheral Devices #
|
||||
# #
|
||||
# Mice: #
|
||||
# SteelSeries Rival 100 #
|
||||
# SteelSeries Rival 100 DotA 2 Edition #
|
||||
# SteelSeries Rival 105 #
|
||||
# SteelSeries Rival 110 #
|
||||
# SteelSeries Rival 300 #
|
||||
# Acer Predator Gaming Mouse (Rival 300) #
|
||||
# SteelSeries Rival 300 CS:GO Fade Edition #
|
||||
# SteelSeries Rival 300 CS:GO Fade Edition (stm32) #
|
||||
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
|
||||
# SteelSeries Rival 300 Dota 2 Edition #
|
||||
# SteelSeries Rival 300 HP Omen Edition #
|
||||
# Headsets: #
|
||||
# SteelSeries Siberia 350 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1702", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="170c", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1814", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1729", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1384", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1714", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1394", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1716", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171a", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1392", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1718", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
|
||||
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Thermaltake Poseidon Z RGB Keyboard #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="3006", TAG+="uaccess"
|
||||
@@ -0,0 +1,343 @@
|
||||
/*-----------------------------------------*\
|
||||
| AMDWraithPrismController.h |
|
||||
| |
|
||||
| Driver for AMD Wraith Prism RGB lighting |
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12/6/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AMDWraithPrismController.h"
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
strcpy(device_name, "AMD Wraith Prism");
|
||||
|
||||
current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
|
||||
current_fan_speed = 0xFF;
|
||||
current_fan_random_color = false;
|
||||
|
||||
current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
|
||||
current_logo_speed = 0xFF;
|
||||
current_logo_random_color = false;
|
||||
|
||||
current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
|
||||
current_ring_speed = 0xFF;
|
||||
current_ring_direction = false;
|
||||
|
||||
SendEnableCommand();
|
||||
}
|
||||
|
||||
AMDWraithPrismController::~AMDWraithPrismController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* AMDWraithPrismController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
std::string AMDWraithPrismController::GetEffectChannelString(unsigned char channel)
|
||||
{
|
||||
std::string ret_string = "";
|
||||
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x40, 0x21, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
usb_buf[0x03] = channel;
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
ret_string.append((char *)&usb_buf[0x08]);
|
||||
|
||||
return(ret_string);
|
||||
}
|
||||
|
||||
std::string AMDWraithPrismController::GetFirmwareVersionString()
|
||||
{
|
||||
std::string ret_string = "";
|
||||
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x12, 0x20, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
unsigned char fw_buf[16] = {0x00};
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
for(int char_idx = 0; char_idx < 16; char_idx+=2)
|
||||
{
|
||||
if(usb_buf[char_idx + 0x08] != 0)
|
||||
{
|
||||
fw_buf[char_idx / 2] = usb_buf[char_idx + 0x08];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret_string.append((char *)fw_buf);
|
||||
|
||||
return(ret_string);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, bool random_color)
|
||||
{
|
||||
current_fan_mode = mode;
|
||||
current_fan_speed = speed_values_fan_logo[mode][speed];
|
||||
current_fan_random_color = random_color;
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetFanColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
SendEffectChannelUpdate
|
||||
(
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED,
|
||||
current_fan_speed,
|
||||
false,
|
||||
current_fan_random_color,
|
||||
current_fan_mode,
|
||||
max_brightness_fan_logo[current_fan_mode],
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, bool random_color)
|
||||
{
|
||||
current_logo_mode = mode;
|
||||
current_logo_speed = speed_values_fan_logo[mode][speed];
|
||||
current_logo_random_color = random_color;
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetLogoColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
SendEffectChannelUpdate
|
||||
(
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED,
|
||||
current_logo_speed,
|
||||
false,
|
||||
current_logo_random_color,
|
||||
current_logo_mode,
|
||||
max_brightness_fan_logo[current_logo_mode],
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color)
|
||||
{
|
||||
current_ring_mode = mode;
|
||||
current_ring_speed = speed_values_ring[mode][speed];
|
||||
current_ring_direction = direction;
|
||||
current_ring_random_color = random_color;
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetRingColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
SetRingEffectChannel(current_ring_mode);
|
||||
|
||||
SendEffectChannelUpdate
|
||||
(
|
||||
current_ring_mode,
|
||||
current_ring_speed,
|
||||
current_ring_direction,
|
||||
current_ring_random_color,
|
||||
mode_value_ring[current_ring_mode],
|
||||
max_brightness_ring[current_ring_mode],
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
);
|
||||
|
||||
SendApplyCommand();
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SetRingEffectChannel(unsigned char channel)
|
||||
{
|
||||
SendChannelRemap(channel, AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED, AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendEnableCommand()
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x41, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendApplyCommand()
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0x28, 0x00, 0x00,
|
||||
0xE0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendEffectChannelUpdate
|
||||
(
|
||||
unsigned char effect_channel,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
bool random_color,
|
||||
unsigned char mode,
|
||||
unsigned char brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0x2C, 0x01, 0x00,
|
||||
0x05, 0xFF, 0x00, 0x01,
|
||||
0xFF, 0xFF, 0x00, 0xFF,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
usb_buf[0x05] = effect_channel;
|
||||
usb_buf[0x06] = speed;
|
||||
usb_buf[0x07] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
|
||||
usb_buf[0x08] = mode;
|
||||
|
||||
usb_buf[0x0A] = brightness;
|
||||
|
||||
usb_buf[0x0B] = red;
|
||||
usb_buf[0x0C] = green;
|
||||
usb_buf[0x0D] = blue;
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel)
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0xA0, 0x01, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00,
|
||||
0x05, 0x06, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
usb_buf[0x09] = logo_channel;
|
||||
usb_buf[0x0A] = fan_channel;
|
||||
|
||||
for(int led = 0x0B; led <= 0x19; led++)
|
||||
{
|
||||
usb_buf[led] = ring_channel;
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*-----------------------------------------*\
|
||||
| AMDWraithPrismController.h |
|
||||
| |
|
||||
| Definitions and types for AMD Wraith |
|
||||
| Prism lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12/6/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
static const unsigned char max_brightness_fan_logo[] =
|
||||
{
|
||||
0x00,
|
||||
0xFF,
|
||||
0x7F,
|
||||
0xFF
|
||||
};
|
||||
|
||||
static const unsigned char speed_values_fan_logo[][5] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
|
||||
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
|
||||
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
|
||||
};
|
||||
|
||||
static const unsigned char max_brightness_ring[] =
|
||||
{
|
||||
0xFF,
|
||||
0xFF,
|
||||
0x7F,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0xFF
|
||||
};
|
||||
|
||||
static const unsigned char mode_value_ring[] =
|
||||
{
|
||||
0xFF,
|
||||
0x03,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x05,
|
||||
0xFF,
|
||||
0xC3,
|
||||
0x4A,
|
||||
0x05
|
||||
};
|
||||
|
||||
static const unsigned char speed_values_ring[][5] =
|
||||
{
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /* Static */
|
||||
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
|
||||
{ 0x96, 0x8C, 0x80, 0x6E, 0x68 }, /* Color Cycle */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* */
|
||||
{ 0x72, 0x68, 0x64, 0x62, 0x61 }, /* Rainbow */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Bounce */
|
||||
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Chase */
|
||||
{ 0x77, 0x74, 0x6E, 0x6B, 0x67 }, /* Swirl */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Morse Code */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC = 0x01, /* Fan/Logo Static Mode */
|
||||
AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE = 0x02, /* Fan/Logo Color Cycle Mode */
|
||||
AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING = 0x03, /* Fan/Logo Breathing Mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC = 0x00, /* Static effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING = 0x01, /* Breathing effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE = 0x02, /* Color cycle effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED = 0x05, /* Logo LED effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED = 0x06, /* Fan LED effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW = 0x07, /* Rainbow effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE = 0x08, /* Bounce effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE = 0x09, /* Chase effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL = 0x0A, /* Swirl effect channel */
|
||||
AMD_WRAITH_PRISM_EFFECT_CHANNEL_MORSE = 0x0B, /* Morse code effect channel */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AMD_WRAITH_PRISM_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
AMD_WRAITH_PRISM_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
AMD_WRAITH_PRISM_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
AMD_WRAITH_PRISM_SPEED_FAST = 0x03, /* Fast speed */
|
||||
AMD_WRAITH_PRISM_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class AMDWraithPrismController
|
||||
{
|
||||
public:
|
||||
AMDWraithPrismController(hid_device* dev_handle);
|
||||
~AMDWraithPrismController();
|
||||
|
||||
char* GetDeviceName();
|
||||
|
||||
std::string GetEffectChannelString(unsigned char channel);
|
||||
std::string GetFirmwareVersionString();
|
||||
|
||||
void SetRingEffectChannel(unsigned char channel);
|
||||
|
||||
void SetFanMode(unsigned char mode, unsigned char speed, bool random_color);
|
||||
void SetFanColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
void SetLogoMode(unsigned char mode, unsigned char speed, bool random_color);
|
||||
void SetLogoColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
void SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color);
|
||||
void SetRingColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_fan_mode;
|
||||
unsigned char current_fan_speed;
|
||||
bool current_fan_random_color;
|
||||
|
||||
unsigned char current_logo_mode;
|
||||
unsigned char current_logo_speed;
|
||||
bool current_logo_random_color;
|
||||
|
||||
unsigned char current_ring_mode;
|
||||
unsigned char current_ring_speed;
|
||||
bool current_ring_direction;
|
||||
bool current_ring_random_color;
|
||||
|
||||
void SendEnableCommand();
|
||||
|
||||
void SendApplyCommand();
|
||||
|
||||
void SendEffectChannelUpdate
|
||||
(
|
||||
unsigned char effect_channel,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
bool random_color,
|
||||
unsigned char mode,
|
||||
unsigned char brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "AMDWraithPrismController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AMDWraithPrism.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
#define AMD_WRAITH_PRISM_VID 0x2516
|
||||
#define AMD_WRAITH_PRISM_PID 0x0051
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAMDWraithPrismControllers *
|
||||
* *
|
||||
* Tests the USB address to see if an AMD Wraith Prism controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
info = hid_enumerate(AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
|
||||
|
||||
//Look for AMD Wraith Prism
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == AMD_WRAITH_PRISM_VID)
|
||||
&&(info->product_id == AMD_WRAITH_PRISM_PID)
|
||||
#if USE_HID_USAGE
|
||||
&&(info->interface_number == 1)
|
||||
&&(info->usage_page == 0xFF00))
|
||||
#else
|
||||
&&(info->interface_number == 1))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
|
||||
|
||||
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
#include "AuraController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Aura.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForAuraController *
|
||||
* *
|
||||
* Tests the given address to see if an Aura controller exists there. First does a *
|
||||
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
|
||||
* for incrementing values 0...F which was observed at this location during data dump *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForAuraController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
for (int i = 0xA0; i < 0xB0; i++)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, i);
|
||||
|
||||
if (res != (i - 0xA0))
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForAuraController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAuraControllers *
|
||||
* *
|
||||
* Detect Aura controllers on the enumerated I2C busses. Searches for Aura-enabled *
|
||||
* RAM at 0x77 and tries to initialize their slot addresses, then searches for them *
|
||||
* at their correct initialized addresses. Also looks for motherboard controller at *
|
||||
* address 0x4E. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAuraControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
AuraController* new_aura;
|
||||
RGBController_Aura* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Remap Aura-enabled RAM modules on 0x77
|
||||
for (unsigned int slot = 0; slot < 8; slot++)
|
||||
{
|
||||
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
AuraController temp_controller(busses[bus], 0x77);
|
||||
|
||||
temp_controller.AuraRegisterWrite(AURA_REG_SLOT_INDEX, slot);
|
||||
temp_controller.AuraRegisterWrite(AURA_REG_I2C_ADDRESS, 0xE0 + (slot << 1));
|
||||
}
|
||||
|
||||
// Add Aura-enabled controllers at their remapped addresses
|
||||
for (unsigned int slot = 0; slot < 8; slot++)
|
||||
{
|
||||
if (TestForAuraController(busses[bus], 0x70 + slot))
|
||||
{
|
||||
new_aura = new AuraController(busses[bus], 0x70 + slot);
|
||||
new_controller = new RGBController_Aura(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for Aura controller at 0x40
|
||||
if (TestForAuraController(busses[bus], 0x40))
|
||||
{
|
||||
new_aura = new AuraController(busses[bus], 0x40);
|
||||
new_controller = new RGBController_Aura(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Aura controller at 0x4E
|
||||
if (TestForAuraController(busses[bus], 0x4E))
|
||||
{
|
||||
new_aura = new AuraController(busses[bus], 0x4E);
|
||||
new_controller = new RGBController_Aura(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Aura controller at 0x4F
|
||||
if (TestForAuraController(busses[bus], 0x4F))
|
||||
{
|
||||
new_aura = new AuraController(busses[bus], 0x4F);
|
||||
new_controller = new RGBController_Aura(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Aura controller at 0x66
|
||||
if (TestForAuraController(busses[bus], 0x66))
|
||||
{
|
||||
new_aura = new AuraController(busses[bus], 0x66);
|
||||
new_controller = new RGBController_Aura(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectAuraControllers() */
|
||||
@@ -0,0 +1,125 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraCoreController.cpp |
|
||||
| |
|
||||
| Driver for ASUS ROG Aura Core RGB |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 4/13/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraCoreController.h"
|
||||
#include <cstring>
|
||||
|
||||
AuraCoreController::AuraCoreController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
AuraCoreController::~AuraCoreController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AuraCoreController::SendBrightness
|
||||
(
|
||||
unsigned char brightness
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[17];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x5A;
|
||||
usb_buf[0x01] = AURA_CORE_COMMAND_BRIGHTNESS;
|
||||
usb_buf[0x02] = 0xC5;
|
||||
usb_buf[0x03] = 0xC4;
|
||||
usb_buf[0x04] = brightness;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void AuraCoreController::SendUpdate
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[17];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x5D;
|
||||
usb_buf[0x01] = AURA_CORE_COMMAND_UPDATE;
|
||||
usb_buf[0x02] = zone;
|
||||
usb_buf[0x03] = mode;
|
||||
usb_buf[0x04] = red;
|
||||
usb_buf[0x05] = green;
|
||||
usb_buf[0x06] = blue;
|
||||
usb_buf[0x07] = speed;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void AuraCoreController::SendSet()
|
||||
{
|
||||
unsigned char usb_buf[17];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x5D;
|
||||
usb_buf[0x01] = AURA_CORE_COMMAND_SET;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void AuraCoreController::SendApply()
|
||||
{
|
||||
unsigned char usb_buf[17];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x5D;
|
||||
usb_buf[0x01] = AURA_CORE_COMMAND_APPLY;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, 17);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraCoreController.h |
|
||||
| |
|
||||
| Definitions and types for ASUS ROG Aura |
|
||||
| Core RGB lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 4/13/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_CORE_MODE_STATIC = 0, /* Static color mode */
|
||||
AURA_CORE_MODE_BREATHING = 1, /* Breathing effect mode */
|
||||
AURA_CORE_MODE_SPECTRUM_CYCLE = 2, /* Spectrum Cycle mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_CORE_COMMAND_UPDATE = 0xB3, /* Update mode and color */
|
||||
AURA_CORE_COMMAND_SET = 0xB5, /* Set command */
|
||||
AURA_CORE_COMMAND_APPLY = 0xB4, /* Apply command */
|
||||
AURA_CORE_COMMAND_BRIGHTNESS = 0xBA, /* Brightness command */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_CORE_ZONE_IDX_ALL = 0x00, /* Update all zones */
|
||||
AURA_CORE_ZONE_IDX_1 = 0x01, /* Update zone 1 */
|
||||
AURA_CORE_ZONE_IDX_2 = 0x02, /* Update zone 2 */
|
||||
AURA_CORE_ZONE_IDX_3 = 0x03, /* Update zone 3 */
|
||||
AURA_CORE_ZONE_IDX_4 = 0x04, /* Update zone 4 */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_CORE_SPEED_SLOW = 0xE1, /* Slowest speed */
|
||||
AURA_CORE_SPEED_NORMAL = 0xEB, /* Normal speed */
|
||||
AURA_CORE_SPEED_FAST = 0xF5, /* Fastest speed */
|
||||
};
|
||||
|
||||
class AuraCoreController
|
||||
{
|
||||
public:
|
||||
AuraCoreController(hid_device* dev_handle);
|
||||
~AuraCoreController();
|
||||
|
||||
void SendBrightness
|
||||
(
|
||||
unsigned char brightness
|
||||
);
|
||||
|
||||
void SendUpdate
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendSet();
|
||||
|
||||
void SendApply();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "AuraCoreController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AuraCore.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define AURA_CORE_VID 0x0B05
|
||||
|
||||
#define NUM_PIDS 3
|
||||
static const unsigned short pid_table[] =
|
||||
{
|
||||
0x1854,
|
||||
0x1869,
|
||||
0x1866
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAuraCoreControllers *
|
||||
* *
|
||||
* Tests the USB address to see if an Asus ROG Aura Core controller exists there *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAuraCoreControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device* dev;
|
||||
|
||||
//Look for Asus ROG Aura Core RGB controller
|
||||
hid_init();
|
||||
|
||||
for(int pid_idx = 0; pid_idx < NUM_PIDS; pid_idx++)
|
||||
{
|
||||
dev = hid_open(AURA_CORE_VID, pid_table[pid_idx], 0);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
AuraCoreController* controller = new AuraCoreController(dev);
|
||||
|
||||
RGBController_AuraCore* rgb_controller = new RGBController_AuraCore(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraGPUController.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB on GPUs |
|
||||
| |
|
||||
| Jan Rettig (Klapstuhl) 14.02.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraGPUController.h"
|
||||
#include <cstring>
|
||||
|
||||
AuraGPUController::AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
strcpy(device_name, "ASUS Aura GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
|
||||
}
|
||||
|
||||
AuraGPUController::~AuraGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string AuraGPUController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string AuraGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned char AuraGPUController::GetLEDRed()
|
||||
{
|
||||
return(AuraGPURegisterRead(AURA_GPU_REG_RED));
|
||||
}
|
||||
|
||||
unsigned char AuraGPUController::GetLEDGreen()
|
||||
{
|
||||
return(AuraGPURegisterRead(AURA_GPU_REG_GREEN));
|
||||
}
|
||||
|
||||
unsigned char AuraGPUController::GetLEDBlue()
|
||||
{
|
||||
return(AuraGPURegisterRead(AURA_GPU_REG_BLUE));
|
||||
}
|
||||
|
||||
void AuraGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
|
||||
{
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
|
||||
}
|
||||
|
||||
void AuraGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_RED, red);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_GREEN, green);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_BLUE, blue);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
|
||||
}
|
||||
|
||||
void AuraGPUController::SetMode(unsigned char mode)
|
||||
{
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_MODE, mode);
|
||||
AuraGPURegisterWrite(AURA_GPU_REG_APPLY, AURA_GPU_APPLY_VAL);
|
||||
}
|
||||
|
||||
unsigned char AuraGPUController::AuraGPURegisterRead(unsigned char reg)
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, reg));
|
||||
}
|
||||
|
||||
void AuraGPUController::AuraGPURegisterWrite(unsigned char reg, unsigned char val)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraGPUController.h |
|
||||
| |
|
||||
| Definitions for ASUS Aura RGB on GPUs |
|
||||
| |
|
||||
| Jan Rettig (Klapstuhl) 14.02.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char aura_gpu_dev_id;
|
||||
|
||||
#define AURA_GPU_MAGIC_VAL 0x1589 /* This magic value is present in all Aura GPU controllers */
|
||||
#define AURA_GPU_APPLY_VAL 0x01 /* Value for Apply Changes Register */
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_GPU_REG_RED = 0x04, /* AURA GPU RED Register */
|
||||
AURA_GPU_REG_GREEN = 0x05, /* AURA GPU GREEN Register */
|
||||
AURA_GPU_REG_BLUE = 0x06, /* AURA GPU BLUE Register */
|
||||
AURA_GPU_REG_MODE = 0x07, /* AURA GPU Mode Selection Register */
|
||||
AURA_GPU_REG_SYNC = 0x0C, /* AURA GPU "Sync" Register */
|
||||
AURA_GPU_REG_APPLY = 0x0E, /* AURA GPU Apply Chnages Register */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_GPU_MODE_OFF = 0, /* OFF mode (not a real Mode! Doesn't do anything!) */
|
||||
AURA_GPU_MODE_STATIC = 1, /* Static color mode */
|
||||
AURA_GPU_MODE_BREATHING = 2, /* Breathing effect mode */
|
||||
AURA_GPU_MODE_FLASHING = 3, /* Flashing effect mode */
|
||||
AURA_GPU_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
|
||||
AURA_GPU_MODE_DIRECT = 5, /* Direct mode (not a real Mode! Doesn't do anything!) */
|
||||
AURA_GPU_NUMBER_MODES
|
||||
};
|
||||
|
||||
class AuraGPUController
|
||||
{
|
||||
public:
|
||||
AuraGPUController(i2c_smbus_interface* bus, aura_gpu_dev_id);
|
||||
~AuraGPUController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned char GetLEDRed();
|
||||
unsigned char GetLEDGreen();
|
||||
unsigned char GetLEDBlue();
|
||||
void SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char AuraGPURegisterRead(unsigned char reg);
|
||||
void AuraGPURegisterWrite(unsigned char reg, unsigned char val);
|
||||
|
||||
bool direct = false; // Temporary solution to check if we are in "Direct" mode
|
||||
|
||||
private:
|
||||
char device_name[16];
|
||||
i2c_smbus_interface * bus;
|
||||
aura_gpu_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB on GPUs |
|
||||
| |
|
||||
| Jan Rettig (Klapstuhl) 14.02.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AuraGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| This list contains the available I2C addresses for Aura GPUs |
|
||||
\*-------------------------------------------------------------*/
|
||||
#define AURA_GPU_ADDRESS_COUNT 3
|
||||
|
||||
static const unsigned char aura_gpu_addresses[] =
|
||||
{
|
||||
0x29,
|
||||
0x2A,
|
||||
0x60
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForAuraGPUController *
|
||||
* *
|
||||
* Tests the given address to see if an Aura GPU controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForAuraGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
unsigned char aura_gpu_magic_high = bus->i2c_smbus_read_byte_data(address, 0x20); // High Byte of magic (0x15)
|
||||
unsigned char aura_gpu_magic_low = bus->i2c_smbus_read_byte_data(address, 0x21); // Low Byte of magic (0x89)
|
||||
|
||||
if((aura_gpu_magic_high << 8) + aura_gpu_magic_low == AURA_GPU_MAGIC_VAL)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForAuraGPUController() */
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAuraGPUControllers *
|
||||
* *
|
||||
* Detect Aura GPU controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
AuraGPUController* new_aura_gpu;
|
||||
RGBController_AuraGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Add Aura-enabled GPU controllers
|
||||
for (unsigned int address_list_idx = 0; address_list_idx < AURA_GPU_ADDRESS_COUNT; address_list_idx++)
|
||||
{
|
||||
if (TestForAuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]))
|
||||
{
|
||||
new_aura_gpu = new AuraGPUController(busses[bus], aura_gpu_addresses[address_list_idx]);
|
||||
new_controller = new RGBController_AuraGPU(new_aura_gpu);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
} /* DetectAuraGPUControllers() */
|
||||
+47
-22
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraController.h |
|
||||
| AuraSMBusController.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB lighting |
|
||||
| controller |
|
||||
@@ -7,10 +7,10 @@
|
||||
| Adam Honse (CalcProgrammer1) 8/19/2018 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraController.h"
|
||||
#include "AuraSMBusController.h"
|
||||
#include <cstring>
|
||||
|
||||
AuraController::AuraController(i2c_smbus_interface* bus, aura_dev_id dev)
|
||||
AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
@@ -77,22 +77,32 @@ AuraController::AuraController(i2c_smbus_interface* bus, aura_dev_id dev)
|
||||
}
|
||||
}
|
||||
|
||||
AuraController::~AuraController()
|
||||
AuraSMBusController::~AuraSMBusController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char * AuraController::GetDeviceName()
|
||||
std::string AuraSMBusController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
unsigned char AuraController::GetChannel(unsigned int led)
|
||||
std::string AuraSMBusController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned char AuraSMBusController::GetChannel(unsigned int led)
|
||||
{
|
||||
return(config_table[channel_cfg + led]);
|
||||
}
|
||||
|
||||
const char * AuraController::GetChannelName(unsigned int led)
|
||||
const char * AuraSMBusController::GetChannelName(unsigned int led)
|
||||
{
|
||||
switch (config_table[channel_cfg + led])
|
||||
{
|
||||
@@ -142,16 +152,31 @@ const char * AuraController::GetChannelName(unsigned int led)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int AuraController::GetLEDCount()
|
||||
unsigned int AuraSMBusController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void AuraController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
unsigned char AuraSMBusController::GetLEDRed(unsigned int led)
|
||||
{
|
||||
return(AuraRegisterRead(direct_reg + ( 3 * led )));
|
||||
}
|
||||
|
||||
unsigned char AuraSMBusController::GetLEDGreen(unsigned int led)
|
||||
{
|
||||
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 2));
|
||||
}
|
||||
|
||||
unsigned char AuraSMBusController::GetLEDBlue(unsigned int led)
|
||||
{
|
||||
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 1));
|
||||
}
|
||||
|
||||
void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char* colors = new unsigned char[led_count * 3];
|
||||
|
||||
for (int i = 0; i < (led_count * 3); i += 3)
|
||||
for (unsigned int i = 0; i < (led_count * 3); i += 3)
|
||||
{
|
||||
colors[i + 0] = red;
|
||||
colors[i + 1] = blue;
|
||||
@@ -163,11 +188,11 @@ void AuraController::SetAllColorsDirect(unsigned char red, unsigned char green,
|
||||
delete colors;
|
||||
}
|
||||
|
||||
void AuraController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char* colors = new unsigned char[led_count * 3];
|
||||
|
||||
for (int i = 0; i < (led_count * 3); i += 3)
|
||||
for (unsigned int i = 0; i < (led_count * 3); i += 3)
|
||||
{
|
||||
colors[i + 0] = red;
|
||||
colors[i + 1] = blue;
|
||||
@@ -178,23 +203,23 @@ void AuraController::SetAllColorsEffect(unsigned char red, unsigned char green,
|
||||
|
||||
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
|
||||
|
||||
delete colors;
|
||||
delete[] colors;
|
||||
}
|
||||
|
||||
void AuraController::SetDirect(unsigned char direct)
|
||||
void AuraSMBusController::SetDirect(unsigned char direct)
|
||||
{
|
||||
AuraRegisterWrite(AURA_REG_DIRECT, direct);
|
||||
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
|
||||
}
|
||||
|
||||
void AuraController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void AuraSMBusController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char colors[3] = { red, blue, green };
|
||||
|
||||
AuraRegisterWriteBlock(direct_reg + ( 3 * led ), colors, 3);
|
||||
}
|
||||
|
||||
void AuraController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void AuraSMBusController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char colors[3] = { red, blue, green };
|
||||
|
||||
@@ -203,13 +228,13 @@ void AuraController::SetLEDColorEffect(unsigned int led, unsigned char red, unsi
|
||||
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
|
||||
}
|
||||
|
||||
void AuraController::SetMode(unsigned char mode)
|
||||
void AuraSMBusController::SetMode(unsigned char mode)
|
||||
{
|
||||
AuraRegisterWrite(AURA_REG_MODE, mode);
|
||||
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
|
||||
}
|
||||
|
||||
void AuraController::AuraUpdateDeviceName()
|
||||
void AuraSMBusController::AuraUpdateDeviceName()
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
@@ -217,7 +242,7 @@ void AuraController::AuraUpdateDeviceName()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char AuraController::AuraRegisterRead(aura_register reg)
|
||||
unsigned char AuraSMBusController::AuraRegisterRead(aura_register reg)
|
||||
{
|
||||
//Write Aura register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
@@ -227,7 +252,7 @@ unsigned char AuraController::AuraRegisterRead(aura_register reg)
|
||||
|
||||
}
|
||||
|
||||
void AuraController::AuraRegisterWrite(aura_register reg, unsigned char val)
|
||||
void AuraSMBusController::AuraRegisterWrite(aura_register reg, unsigned char val)
|
||||
{
|
||||
//Write Aura register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
@@ -237,7 +262,7 @@ void AuraController::AuraRegisterWrite(aura_register reg, unsigned char val)
|
||||
|
||||
}
|
||||
|
||||
void AuraController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
|
||||
void AuraSMBusController::AuraRegisterWriteBlock(aura_register reg, unsigned char * data, unsigned char sz)
|
||||
{
|
||||
//Write Aura register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
@@ -245,4 +270,4 @@ void AuraController::AuraRegisterWriteBlock(aura_register reg, unsigned char * d
|
||||
//Write Aura block data
|
||||
bus->i2c_smbus_write_block_data(dev, 0x03, sz, data);
|
||||
|
||||
}
|
||||
}
|
||||
+11
-6
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraController.h |
|
||||
| AuraSMBusController.h |
|
||||
| |
|
||||
| Definitions and types for ASUS Aura RGB |
|
||||
| lighting controller |
|
||||
@@ -7,6 +7,7 @@
|
||||
| Adam Honse (CalcProgrammer1) 8/19/2018 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
@@ -87,16 +88,20 @@ enum
|
||||
AURA_CONFIG_CHANNEL_V2 = 0x1B, /* LED Channel V2 configuration offset */
|
||||
};
|
||||
|
||||
class AuraController
|
||||
class AuraSMBusController
|
||||
{
|
||||
public:
|
||||
AuraController(i2c_smbus_interface* bus, aura_dev_id dev);
|
||||
~AuraController();
|
||||
AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id dev);
|
||||
~AuraSMBusController();
|
||||
|
||||
char* GetDeviceName();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned char GetChannel(unsigned int led);
|
||||
const char* GetChannelName(unsigned int led);
|
||||
unsigned int GetLEDCount();
|
||||
unsigned char GetLEDRed(unsigned int led);
|
||||
unsigned char GetLEDGreen(unsigned int led);
|
||||
unsigned char GetLEDBlue(unsigned int led);
|
||||
void SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetDirect(unsigned char direct);
|
||||
@@ -120,4 +125,4 @@ private:
|
||||
i2c_smbus_interface * bus;
|
||||
aura_dev_id dev;
|
||||
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,190 @@
|
||||
#include "AuraSMBusController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AuraSMBus.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for mapping Aura RAM |
|
||||
\*----------------------------------------------------------------------*/
|
||||
#define AURA_RAM_ADDRESS_COUNT 23
|
||||
|
||||
static const unsigned char aura_ram_addresses[] =
|
||||
{
|
||||
0x70,
|
||||
0x71,
|
||||
0x72,
|
||||
0x73,
|
||||
0x74,
|
||||
0x75,
|
||||
0x76,
|
||||
0x78,
|
||||
0x79,
|
||||
0x7A,
|
||||
0x7B,
|
||||
0x7C,
|
||||
0x7D,
|
||||
0x7E,
|
||||
0x7F,
|
||||
0x4F,
|
||||
0x66,
|
||||
0x67,
|
||||
0x39,
|
||||
0x3A,
|
||||
0x3B,
|
||||
0x3C,
|
||||
0x3D
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for mapping Aura motherboards |
|
||||
\*---------------------------------------------------------------------------------*/
|
||||
#define AURA_MOBO_ADDRESS_COUNT 3
|
||||
|
||||
static const unsigned char aura_mobo_addresses[] =
|
||||
{
|
||||
0x40,
|
||||
0x4E,
|
||||
0x4F
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* AuraRegisterWrite *
|
||||
* *
|
||||
* A standalone version of the AuraSMBusController::AuraRegisterWrite function for *
|
||||
* access to Aura devices without instancing the AuraSMBusController class or reading *
|
||||
* the config table from the device. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void AuraRegisterWrite(i2c_smbus_interface* bus, aura_dev_id dev, aura_register reg, unsigned char val)
|
||||
{
|
||||
//Write Aura register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write Aura value
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
|
||||
}
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForAuraSMBusController *
|
||||
* *
|
||||
* Tests the given address to see if an Aura controller exists there. First does a *
|
||||
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
|
||||
* for incrementing values 0...F which was observed at this location during data dump *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForAuraSMBusController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
for (int i = 0xA0; i < 0xB0; i++)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, i);
|
||||
|
||||
if (res != (i - 0xA0))
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForAuraSMBusController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAuraSMBusControllers *
|
||||
* *
|
||||
* Detect Aura controllers on the enumerated I2C busses. Searches for Aura-enabled *
|
||||
* RAM at 0x77 and tries to initialize their slot addresses, then searches for them *
|
||||
* at their correct initialized addresses. Also looks for motherboard controller at *
|
||||
* address 0x4E. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
AuraSMBusController* new_aura;
|
||||
RGBController_AuraSMBus* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
int address_list_idx = -1;
|
||||
|
||||
// Remap Aura-enabled RAM modules on 0x77
|
||||
for (unsigned int slot = 0; slot < 8; slot++)
|
||||
{
|
||||
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
address_list_idx++;
|
||||
|
||||
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
|
||||
{
|
||||
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (res >= 0);
|
||||
|
||||
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
|
||||
{
|
||||
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
|
||||
AuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Add Aura-enabled controllers at their remapped addresses
|
||||
for (unsigned int address_list_idx = 0; address_list_idx < AURA_RAM_ADDRESS_COUNT; address_list_idx++)
|
||||
{
|
||||
if (TestForAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
|
||||
{
|
||||
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
|
||||
new_controller = new RGBController_AuraSMBus(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
// Add Aura-enabled motherboard controllers
|
||||
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
|
||||
{
|
||||
if (TestForAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
|
||||
{
|
||||
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
|
||||
new_controller = new RGBController_AuraSMBus(new_aura);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectAuraSMBusControllers() */
|
||||
@@ -0,0 +1,144 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraAddressableController.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB Addressable |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/18/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraAddressableController.h"
|
||||
#include <cstring>
|
||||
|
||||
AuraAddressableController::AuraAddressableController(hid_device* dev_handle) : AuraUSBController(dev_handle)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Add addressable devices |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < config_table[0x02]; ++i)
|
||||
{
|
||||
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
|
||||
}
|
||||
}
|
||||
|
||||
AuraAddressableController::~AuraAddressableController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AuraAddressableController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
|
||||
{
|
||||
unsigned char led_data[60];
|
||||
unsigned int leds_sent = 0;
|
||||
|
||||
while(leds_sent < num_colors)
|
||||
{
|
||||
unsigned int leds_to_send = 20;
|
||||
|
||||
if((num_colors - leds_sent) < leds_to_send)
|
||||
{
|
||||
leds_to_send = num_colors - leds_sent;
|
||||
}
|
||||
|
||||
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
|
||||
{
|
||||
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
|
||||
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
|
||||
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
|
||||
}
|
||||
|
||||
SendDirect
|
||||
(
|
||||
channel,
|
||||
leds_sent,
|
||||
leds_to_send,
|
||||
led_data
|
||||
);
|
||||
|
||||
leds_sent += leds_to_send;
|
||||
}
|
||||
|
||||
SendDirectApply(channel);
|
||||
}
|
||||
|
||||
void AuraAddressableController::SetMode
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
)
|
||||
{
|
||||
SendEffect
|
||||
(
|
||||
channel,
|
||||
mode,
|
||||
red,
|
||||
grn,
|
||||
blu
|
||||
);
|
||||
}
|
||||
|
||||
void AuraAddressableController::SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_ADDRESSABLE_CONTROL_MODE_EFFECT;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x04] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x05] = red;
|
||||
usb_buf[0x06] = grn;
|
||||
usb_buf[0x07] = blu;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraAddressableController::SendDirectApply
|
||||
(
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = 0x80 | channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraAddressableController.h |
|
||||
| |
|
||||
| Definitions and types for ASUS Aura |
|
||||
| Addressable RGB lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/18/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AuraUSBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_ADDRESSABLE_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */
|
||||
};
|
||||
|
||||
class AuraAddressableController : public AuraUSBController
|
||||
{
|
||||
public:
|
||||
AuraAddressableController(hid_device* dev_handle);
|
||||
~AuraAddressableController();
|
||||
|
||||
void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
void SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
);
|
||||
|
||||
void SendDirectApply
|
||||
(
|
||||
unsigned char channel
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,199 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraMainboardController.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB USB mainboard |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 4/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraMainboardController.h"
|
||||
#include <cstring>
|
||||
|
||||
AuraMainboardController::AuraMainboardController(hid_device* dev_handle) : AuraUSBController(dev_handle), mode(AURA_MODE_DIRECT)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Add mainboard device |
|
||||
\*-----------------------------------------------------*/
|
||||
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Add addressable devices |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < config_table[0x02]; ++i)
|
||||
{
|
||||
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
|
||||
}
|
||||
}
|
||||
|
||||
AuraMainboardController::~AuraMainboardController()
|
||||
{
|
||||
}
|
||||
|
||||
void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
|
||||
{
|
||||
unsigned char led_data[60];
|
||||
unsigned int leds_sent = 0;
|
||||
|
||||
while(leds_sent < num_colors)
|
||||
{
|
||||
unsigned int leds_to_send = 20;
|
||||
|
||||
if((num_colors - leds_sent) < leds_to_send)
|
||||
{
|
||||
leds_to_send = num_colors - leds_sent;
|
||||
}
|
||||
|
||||
for(int led_idx = 0; led_idx < leds_to_send; led_idx++)
|
||||
{
|
||||
led_data[(led_idx * 3) + 0] = RGBGetRValue(colors[led_idx + leds_sent]);
|
||||
led_data[(led_idx * 3) + 1] = RGBGetGValue(colors[led_idx + leds_sent]);
|
||||
led_data[(led_idx * 3) + 2] = RGBGetBValue(colors[led_idx + leds_sent]);
|
||||
}
|
||||
|
||||
SendDirect
|
||||
(
|
||||
device_info[channel].direct_channel,
|
||||
leds_sent,
|
||||
leds_to_send,
|
||||
led_data,
|
||||
leds_sent + leds_to_send >= num_colors
|
||||
);
|
||||
|
||||
leds_sent += leds_to_send;
|
||||
}
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void AuraMainboardController::SetMode
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
)
|
||||
{
|
||||
this->mode = mode;
|
||||
RGBColor color = ToRGBColor(red, grn, blu);
|
||||
|
||||
SendEffect(device_info[channel].effect_channel, mode);
|
||||
if(mode == AURA_MODE_DIRECT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char led_data[60];
|
||||
unsigned char start_led = 0;
|
||||
|
||||
for(std::size_t i = 0; i < channel; ++i)
|
||||
{
|
||||
start_led += device_info[i].num_leds;
|
||||
}
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < device_info[channel].num_leds; led_idx++)
|
||||
{
|
||||
led_data[(led_idx * 3) + 0] = RGBGetRValue(color);
|
||||
led_data[(led_idx * 3) + 1] = RGBGetGValue(color);
|
||||
led_data[(led_idx * 3) + 2] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
SendColor
|
||||
(
|
||||
channel,
|
||||
start_led,
|
||||
device_info[channel].num_leds,
|
||||
led_data,
|
||||
device_info[channel].device_type == AuraDeviceType::FIXED
|
||||
);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void AuraMainboardController::SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraMainboardController::SendColor
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool fixed
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = fixed ? 0xFF : 0x00;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05 + 3 * start_led], led_data, led_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraMainboardController::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_COMMIT;
|
||||
usb_buf[0x02] = 0x55;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraMainboardController.h |
|
||||
| |
|
||||
| Definitions and types for ASUS Aura |
|
||||
| USB Mainboard RGB lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 4/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AuraUSBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_MAINBOARD_CONTROL_MODE_EFFECT = 0x35, /* Effect control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR = 0x36, /* Effect color control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_COMMIT = 0x3F, /* Commit mode */
|
||||
};
|
||||
|
||||
class AuraMainboardController : public AuraUSBController
|
||||
{
|
||||
public:
|
||||
AuraMainboardController(hid_device* dev_handle);
|
||||
~AuraMainboardController();
|
||||
|
||||
void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
);
|
||||
|
||||
private:
|
||||
unsigned int mode;
|
||||
|
||||
void SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode
|
||||
);
|
||||
|
||||
void SendColor
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool fixed
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
@@ -0,0 +1,155 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraUSBController.cpp |
|
||||
| |
|
||||
| Driver for ASUS Aura RGB USB |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 4/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "AuraUSBController.h"
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
AuraUSBController::AuraUSBController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
GetFirmwareVersion();
|
||||
GetConfigTable();
|
||||
}
|
||||
|
||||
AuraUSBController::~AuraUSBController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned int AuraUSBController::GetChannelCount()
|
||||
{
|
||||
return(device_info.size());
|
||||
}
|
||||
|
||||
std::string AuraUSBController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
const std::vector<AuraDeviceInfo>& AuraUSBController::GetAuraDevices() const
|
||||
{
|
||||
return(device_info);
|
||||
}
|
||||
|
||||
void AuraUSBController::GetConfigTable()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_REQUEST_CONFIG_TABLE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 65);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy the firmware string if the reply ID is correct |
|
||||
\*-----------------------------------------------------*/
|
||||
if(usb_buf[1] == 0x30)
|
||||
{
|
||||
memcpy(config_table, &usb_buf[4], 60);
|
||||
|
||||
for(int i = 0; i < 60; i+=6)
|
||||
{
|
||||
printf("%02X %02X %02X %02X %02X %02X\r\n", config_table[i + 0],
|
||||
config_table[i + 1],
|
||||
config_table[i + 2],
|
||||
config_table[i + 3],
|
||||
config_table[i + 4],
|
||||
config_table[i + 5]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
throw std::runtime_error("Could not read config table");
|
||||
}
|
||||
}
|
||||
|
||||
void AuraUSBController::GetFirmwareVersion()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up firmware version request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_REQUEST_FIRMWARE_VERSION;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 65);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy the firmware string if the reply ID is correct |
|
||||
\*-----------------------------------------------------*/
|
||||
if(usb_buf[1] == 0x02)
|
||||
{
|
||||
memcpy(device_name, &usb_buf[2], 16);
|
||||
}
|
||||
}
|
||||
|
||||
void AuraUSBController::SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool apply /* = false */
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = apply ? 0x80 : 0x00;
|
||||
usb_buf[0x02] |= device;
|
||||
usb_buf[0x03] = start_led;
|
||||
usb_buf[0x04] = led_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], led_data, led_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*-----------------------------------------*\
|
||||
| AuraUSBController.h |
|
||||
| |
|
||||
| Definitions and types for ASUS Aura |
|
||||
| USB RGB lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 4/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_MODE_OFF = 0, /* OFF mode */
|
||||
AURA_MODE_STATIC = 1, /* Static color mode */
|
||||
AURA_MODE_BREATHING = 2, /* Breathing effect mode */
|
||||
AURA_MODE_FLASHING = 3, /* Flashing effect mode */
|
||||
AURA_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
|
||||
AURA_MODE_RAINBOW = 5, /* Rainbow effect mode */
|
||||
AURA_MODE_SPECTRUM_CYCLE_BREATHING = 6, /* Rainbow Breathing effect mode */
|
||||
AURA_MODE_CHASE_FADE = 7, /* Chase with Fade effect mode */
|
||||
AURA_MODE_SPECTRUM_CYCLE_CHASE_FADE = 8, /* Chase with Fade, Rainbow effect mode */
|
||||
AURA_MODE_CHASE = 9, /* Chase effect mode */
|
||||
AURA_MODE_SPECTRUM_CYCLE_CHASE = 10, /* Chase with Rainbow effect mode */
|
||||
AURA_MODE_SPECTRUM_CYCLE_WAVE = 11, /* Wave effect mode */
|
||||
AURA_MODE_CHASE_RAINBOW_PULSE = 12, /* Chase with Rainbow Pulse effect mode*/
|
||||
AURA_MODE_RANDOM_FLICKER = 13, /* Random flicker effect mode */
|
||||
AURA_MODE_MUSIC = 14, /* Music effect mode */
|
||||
AURA_MODE_DIRECT = 0xFF, /* Direct control mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AURA_REQUEST_FIRMWARE_VERSION = 0x82, /* Request firmware string */
|
||||
AURA_REQUEST_CONFIG_TABLE = 0xB0, /* Request configuration table */
|
||||
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
|
||||
};
|
||||
|
||||
enum class AuraDeviceType
|
||||
{
|
||||
FIXED,
|
||||
ADDRESSABLE,
|
||||
};
|
||||
|
||||
struct AuraDeviceInfo
|
||||
{
|
||||
unsigned char effect_channel;
|
||||
unsigned char direct_channel;
|
||||
unsigned char num_leds;
|
||||
AuraDeviceType device_type;
|
||||
};
|
||||
|
||||
class AuraUSBController
|
||||
{
|
||||
public:
|
||||
AuraUSBController(hid_device* dev_handle);
|
||||
virtual ~AuraUSBController();
|
||||
|
||||
unsigned int GetChannelCount();
|
||||
|
||||
std::string GetDeviceName();
|
||||
|
||||
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
|
||||
|
||||
virtual void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
) = 0;
|
||||
|
||||
virtual void SetMode
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
) = 0;
|
||||
|
||||
protected:
|
||||
hid_device* dev;
|
||||
unsigned char config_table[60];
|
||||
std::vector<AuraDeviceInfo> device_info;
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool apply = false
|
||||
);
|
||||
private:
|
||||
char device_name[16];
|
||||
unsigned int led_count;
|
||||
|
||||
void GetConfigTable();
|
||||
|
||||
void GetFirmwareVersion();
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "AuraAddressableController.h"
|
||||
#include "AuraMainboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AuraUSB.h"
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define AURA_USB_VID 0x0B05
|
||||
|
||||
#define NUM_ADDRESSABLE_PIDS 4
|
||||
static const unsigned short addressable_pid_table[] =
|
||||
{
|
||||
0x1867,
|
||||
0x1872,
|
||||
0x1889,
|
||||
0x18A3
|
||||
};
|
||||
|
||||
#define NUM_MAINBOARD_PIDS 2
|
||||
static const unsigned short mainboard_pid_table[] =
|
||||
{
|
||||
0x18f3,
|
||||
0x1939
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectAuraUSBControllers *
|
||||
* *
|
||||
* Tests the USB address to see if an Asus Aura USB RGB header controller *
|
||||
* exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectAuraUSBControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device* dev;
|
||||
|
||||
//Look for Asus Aura addressable RGB header controller
|
||||
hid_init();
|
||||
|
||||
for(int pid_idx = 0; pid_idx < NUM_ADDRESSABLE_PIDS; pid_idx++)
|
||||
{
|
||||
dev = hid_open(AURA_USB_VID, addressable_pid_table[pid_idx], 0);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
AuraAddressableController* controller = new AuraAddressableController(dev);
|
||||
|
||||
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
for(int pid_idx = 0; pid_idx < NUM_MAINBOARD_PIDS; pid_idx++)
|
||||
{
|
||||
dev = hid_open(AURA_USB_VID, mainboard_pid_table[pid_idx], 0);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
try
|
||||
{
|
||||
AuraMainboardController* controller = new AuraMainboardController(dev);
|
||||
|
||||
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
catch(std::runtime_error&)
|
||||
{
|
||||
// reading the config table failed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| CMMP750Controller.cpp |
|
||||
| |
|
||||
| Driver for Coolermaster MP750 mousepad |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Apr 2020 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "CMMP750Controller.h"
|
||||
|
||||
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
|
||||
{
|
||||
int tmp_size = wcslen(_vendor);
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
for (int i=0; ( i<tmp_size && i<CM_DEVICE_NAME_SIZE); i++)
|
||||
{
|
||||
device_name[i] = (char)_vendor[i];
|
||||
}
|
||||
for (int j=0; ( j<wcslen(_vendor) && tmp_size+j<CM_DEVICE_NAME_SIZE); j++)
|
||||
device_name[tmp_size+j] = (char)_device_name[j];
|
||||
|
||||
GetStatus(); //When setting up device get current status
|
||||
}
|
||||
|
||||
CMMP750Controller::~CMMP750Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMP750Controller::GetStatus()
|
||||
{
|
||||
unsigned char buffer[0x40] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
buffer[0] = 0x07;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read(dev, buffer, buffer_size);
|
||||
|
||||
if( buffer[0] == 0x80 && buffer[1] == 0x05 )
|
||||
{
|
||||
current_mode = buffer[2] - 1;
|
||||
current_red = buffer[3];
|
||||
current_green = buffer[4];
|
||||
current_blue = buffer[5];
|
||||
|
||||
for( int i = 0; speed_mode_data[current_mode][i] >= buffer[6]; i++)
|
||||
current_speed = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Code should never reach here however just in case there is a failure set something
|
||||
current_mode = MP750_MODE_COLOR_CYCLE; //Unicorn Spew
|
||||
current_red = 0xFF;
|
||||
current_green = 0xFF;
|
||||
current_blue = 0xFF;
|
||||
current_speed = MP750_SPEED_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
char* CMMP750Controller::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
char* CMMP750Controller::GetSerial()
|
||||
{
|
||||
return serial;
|
||||
}
|
||||
|
||||
std::string CMMP750Controller::GetLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedRed()
|
||||
{
|
||||
return current_red;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedGreen()
|
||||
{
|
||||
return current_green;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedBlue()
|
||||
{
|
||||
return current_blue;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedSpeed()
|
||||
{
|
||||
return current_speed;
|
||||
}
|
||||
|
||||
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void CMMP750Controller::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[0x40] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
for(int i = 0; i < CM_COLOUR_MODE_DATA_SIZE; i++)
|
||||
{
|
||||
buffer[i] = colour_mode_data[current_mode][i];
|
||||
}
|
||||
|
||||
if(current_mode > MP750_MODE_BREATHING)
|
||||
{
|
||||
//If the mode is random colours set SPEED at BYTE2
|
||||
buffer[CM_RED_BYTE] = speed_mode_data[current_mode][current_speed];
|
||||
}
|
||||
else
|
||||
{
|
||||
//Otherwise SPEED is BYTE5
|
||||
buffer[CM_RED_BYTE] = current_red;
|
||||
buffer[CM_GREEN_BYTE] = current_green;
|
||||
buffer[CM_BLUE_BYTE] = current_blue;
|
||||
buffer[CM_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| CMMP750Controller.h |
|
||||
| |
|
||||
| Driver for Coolermaster MP750 mousepad |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Apr 2020 |
|
||||
| |
|
||||
| Simple RGB device with 5 modes |
|
||||
| BYTE0 = Mode (0x01 thru 0x05 |
|
||||
| BYTE1 = ?? Must be set to 0x04 for colour modes otherwise ignored |
|
||||
| BYTE2 = Colour Modes: RED else Cycle SPEED |
|
||||
| BYTE3 = Colour Modes: GREEN else ignored |
|
||||
| BYTE4 = Colour Modes: BLUE else ignored |
|
||||
| BYTE5 = Colour Modes: SPEED else ignored |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_INTERRUPT_TIMEOUT 250
|
||||
#define CM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
CM_MODE_BYTE = 0,
|
||||
CM_RED_BYTE = 2,
|
||||
CM_GREEN_BYTE = 3,
|
||||
CM_BLUE_BYTE = 4,
|
||||
CM_SPEED_BYTE = 5
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MP750_MODE_STATIC = 0x00, //Static Mode
|
||||
MP750_MODE_BLINK = 0x01, //Blinking Mode
|
||||
MP750_MODE_BREATHING = 0x02, //Breathing Mode
|
||||
MP750_MODE_COLOR_CYCLE = 0x03, //Color Cycle Mode
|
||||
MP750_MODE_BREATH_CYCLE = 0x04 //Breathing Cycle Mode
|
||||
};
|
||||
|
||||
static unsigned char colour_mode_data[][6] =
|
||||
{
|
||||
{ 0x01, 0x04, 0xFF, 0x00, 0xFF, 0x00 }, /* Static */
|
||||
{ 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Blinking */
|
||||
{ 0x03, 0x04, 0xFF, 0x00, 0xFF, 0x80 }, /* Breathing */
|
||||
{ 0x04, 0x04, 0x80, 0x00, 0x00, 0x00 }, /* Colour Cycle */
|
||||
{ 0x05, 0x04, 0x80, 0x00, 0x00, 0x00 } /* Colour Breath */
|
||||
};
|
||||
|
||||
static unsigned char speed_mode_data[][9] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },/* Static */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Blinking */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Breathing */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Colour Cycle */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 } /* Colour Breath */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MP750_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
MP750_SPEED_SLOWER = 0x01, /* Slower speed */
|
||||
MP750_SPEED_SLOW = 0x02, /* Slow speed */
|
||||
MP750_SPEED_SLOWISH = 0x03, /* Slowish speed */
|
||||
MP750_SPEED_NORMAL = 0x04, /* Normal speed */
|
||||
MP750_SPEED_FASTISH = 0x05, /* Fastish speed */
|
||||
MP750_SPEED_FAST = 0x06, /* Fast speed */
|
||||
MP750_SPEED_FASTER = 0x07, /* Faster speed */
|
||||
MP750_SPEED_FASTEST = 0x08, /* Fastest speed */
|
||||
};
|
||||
|
||||
class CMMP750Controller
|
||||
{
|
||||
public:
|
||||
CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
|
||||
~CMMP750Controller();
|
||||
|
||||
char* GetDeviceName();
|
||||
char* GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
char serial[32];
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
|
||||
void GetStatus();
|
||||
void SendUpdate();
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "CMMP750Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CMMP750Controller.h"
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define COOLERMASTER_VID 0x2516
|
||||
|
||||
#define COOLERMASTER_MP750_XL_PID 0x0109
|
||||
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
|
||||
|
||||
#define COOLERMASTER_NUM_DEVICES (sizeof(cm_pids) / sizeof(cm_pids[ 0 ]))
|
||||
|
||||
enum
|
||||
{
|
||||
CM_PID = 0,
|
||||
CM_INTERFACE = 1
|
||||
};
|
||||
|
||||
static const unsigned int cm_pids[][4] =
|
||||
{ // PID, Interface
|
||||
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
|
||||
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCoolerMasterControllers *
|
||||
* *
|
||||
* Tests the USB address to see if any CoolerMaster controllers exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
|
||||
//Look for the passed in cm_pids
|
||||
hid_init();
|
||||
info = hid_enumerate(COOLERMASTER_VID, 0x0);
|
||||
|
||||
while(info)
|
||||
{
|
||||
hid_device* dev = NULL;
|
||||
if(info->vendor_id == COOLERMASTER_VID)
|
||||
{
|
||||
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
|
||||
{
|
||||
if((info->product_id == cm_pids[cm_pid_idx][CM_PID])
|
||||
&&(info->interface_number == cm_pids[cm_pid_idx][CM_INTERFACE]))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
|
||||
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Processing Code for Corsair Lighting Node Pro |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 1/12/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairLightingNodeController.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
//Include thread libraries for Windows or Linux
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#else
|
||||
#include "pthread.h"
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
//Thread functions have different types in Windows and Linux
|
||||
#ifdef WIN32
|
||||
#define THREAD static void
|
||||
#define THREADRETURN
|
||||
#else
|
||||
#define THREAD static void*
|
||||
#define THREADRETURN return(NULL);
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
THREAD keepalive_thread(void *param)
|
||||
{
|
||||
CorsairLightingNodeController* corsair = static_cast<CorsairLightingNodeController*>(param);
|
||||
corsair->KeepaliveThread();
|
||||
THREADRETURN
|
||||
}
|
||||
|
||||
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
SendFirmwareRequest();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The Corsair Lighting Node Pro requires a packet within|
|
||||
| 20 seconds of sending the lighting change in order |
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 5s |
|
||||
\*-----------------------------------------------------*/
|
||||
#ifdef WIN32
|
||||
_beginthread(keepalive_thread, 0, this);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, &keepalive_thread, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
CorsairLightingNodeController::~CorsairLightingNodeController()
|
||||
{
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::KeepaliveThread()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CorsairLightingNodeController::GetFirmwareString()
|
||||
{
|
||||
return(firmware_version);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SetChannelEffect(unsigned char channel,
|
||||
unsigned char num_leds,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2,
|
||||
unsigned char red3,
|
||||
unsigned char grn3,
|
||||
unsigned char blu3
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Send Reset packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendReset(channel);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send Begin packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendBegin(channel);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set Port State packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set Effect Configuration packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendEffectConfig
|
||||
(
|
||||
channel,
|
||||
0,
|
||||
num_leds,
|
||||
mode,
|
||||
speed,
|
||||
direction,
|
||||
random,
|
||||
red1,
|
||||
grn1,
|
||||
blu1,
|
||||
red2,
|
||||
grn2,
|
||||
blu2,
|
||||
red3,
|
||||
grn3,
|
||||
blu3,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors)
|
||||
{
|
||||
unsigned char red_color_data[50];
|
||||
unsigned char grn_color_data[50];
|
||||
unsigned char blu_color_data[50];
|
||||
unsigned char pkt_offset = 0;
|
||||
unsigned char pkt_size = 0;
|
||||
unsigned int colors_remaining = num_colors;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send Port State packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPortState(channel, CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Loop through colors and send 50 at a time |
|
||||
\*-----------------------------------------------------*/
|
||||
while(colors_remaining > 0)
|
||||
{
|
||||
if(colors_remaining < 50)
|
||||
{
|
||||
pkt_size = colors_remaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkt_size = 50;
|
||||
}
|
||||
|
||||
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
|
||||
{
|
||||
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
|
||||
grn_color_data[color_idx] = RGBGetGValue(colors[pkt_offset + color_idx]);
|
||||
blu_color_data[color_idx] = RGBGetBValue(colors[pkt_offset + color_idx]);
|
||||
}
|
||||
|
||||
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED, red_color_data);
|
||||
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN, grn_color_data);
|
||||
SendDirect(channel, pkt_offset, pkt_size, CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE, blu_color_data);
|
||||
|
||||
colors_remaining -= pkt_size;
|
||||
pkt_offset += pkt_size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void CorsairLightingNodeController::SendFirmwareRequest()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
actual = hid_read(dev, usb_buf, 17);
|
||||
|
||||
if(actual > 0)
|
||||
{
|
||||
firmware_version = std::to_string(usb_buf[0x01]) + "." + std::to_string(usb_buf[0x02]) + "." + std::to_string(usb_buf[0x03]);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendDirect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char start,
|
||||
unsigned char count,
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = start;
|
||||
usb_buf[0x04] = count;
|
||||
usb_buf[0x05] = color_channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x06], color_data, count);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update last commit time |
|
||||
\*-----------------------------------------------------*/
|
||||
last_commit_time = std::chrono::steady_clock::now();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
|
||||
usb_buf[0x02] = 0xFF;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBegin
|
||||
(
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Begin packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
|
||||
usb_buf[0x02] = channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendEffectConfig
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char count,
|
||||
unsigned char led_type,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
unsigned char change_style,
|
||||
unsigned char color_0_red,
|
||||
unsigned char color_0_green,
|
||||
unsigned char color_0_blue,
|
||||
unsigned char color_1_red,
|
||||
unsigned char color_1_green,
|
||||
unsigned char color_1_blue,
|
||||
unsigned char color_2_red,
|
||||
unsigned char color_2_green,
|
||||
unsigned char color_2_blue,
|
||||
unsigned short temperature_0,
|
||||
unsigned short temperature_1,
|
||||
unsigned short temperature_2
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Effect Config packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = count;
|
||||
usb_buf[0x04] = led_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x05] = mode;
|
||||
usb_buf[0x06] = speed;
|
||||
usb_buf[0x07] = direction;
|
||||
usb_buf[0x08] = change_style;
|
||||
usb_buf[0x09] = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x0A] = color_0_red;
|
||||
usb_buf[0x0B] = color_0_green;
|
||||
usb_buf[0x0C] = color_0_blue;
|
||||
usb_buf[0x0D] = color_1_red;
|
||||
usb_buf[0x0E] = color_1_green;
|
||||
usb_buf[0x0F] = color_1_blue;
|
||||
usb_buf[0x10] = color_2_red;
|
||||
usb_buf[0x11] = color_2_green;
|
||||
usb_buf[0x12] = color_2_blue;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up temperatures |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x13] = (temperature_0 >> 8);
|
||||
usb_buf[0x14] = (temperature_0 & 0xFF);
|
||||
usb_buf[0x15] = (temperature_1 >> 8);
|
||||
usb_buf[0x16] = (temperature_1 & 0xFF);
|
||||
usb_buf[0x17] = (temperature_2 >> 8);
|
||||
usb_buf[0x18] = (temperature_2 & 0xFF);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendTemperature()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendReset
|
||||
(
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Reset packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
|
||||
usb_buf[0x02] = channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendPortState
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char state
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Port State packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = state;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBrightness()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendLEDCount()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendProtocol()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for Corsair Lighting Node Pro |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 1/12/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT = 0x32, /* Direct mode LED update packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT = 0x33, /* Commit changes packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN = 0x34, /* Begin effect packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG = 0x35, /* Effect mode configuration packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_TEMPERATURE = 0x36, /* Update temperature value packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_RESET = 0x37, /* Reset channel packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE = 0x38, /* Set port state packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_BRIGHTNESS = 0x39, /* Set brightness packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_LED_COUNT = 0x3A, /* Set LED count packet */
|
||||
CORSAIR_LIGHTING_NODE_PACKET_ID_PROTOCOL = 0x3B, /* Set protocol packet */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_RED = 0x00, /* Red channel for direct update */
|
||||
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_GREEN = 0x01, /* Green channel for direct update */
|
||||
CORSAIR_LIGHTING_NODE_DIRECT_CHANNEL_BLUE = 0x02, /* Blue channel for direct update */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_PORT_STATE_HARDWARE = 0x01, /* Effect hardware control of channel */
|
||||
CORSAIR_LIGHTING_NODE_PORT_STATE_SOFTWARE = 0x02, /* Direct software control of channel */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_LED_TYPE_LED_STRIP = 0x0A, /* Corsair LED Strip Type */
|
||||
CORSAIR_LIGHTING_NODE_LED_TYPE_HD_FAN = 0x0C, /* Corsair HD-series Fan Type */
|
||||
CORSAIR_LIGHTING_NODE_LED_TYPE_SP_FAN = 0x01, /* Corsair SP-series Fan Type */
|
||||
CORSAIR_LIGHTING_NODE_LED_TYPE_ML_FAN = 0x02, /* Corsair ML-series Fan Type */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_CHANNEL_1 = 0x00, /* Channel 1 */
|
||||
CORSAIR_LIGHTING_NODE_CHANNEL_2 = 0x01, /* Channel 2 */
|
||||
CORSAIR_LIGHTING_NODE_NUM_CHANNELS = 0x02, /* Number of channels */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_SPEED_FAST = 0x00, /* Fast speed */
|
||||
CORSAIR_LIGHTING_NODE_SPEED_MEDIUM = 0x01, /* Medium speed */
|
||||
CORSAIR_LIGHTING_NODE_SPEED_SLOW = 0x02, /* Slow speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_NODE_MODE_RAINBOW_WAVE = 0x00, /* Rainbow Wave mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_COLOR_SHIFT = 0x01, /* Color Shift mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_COLOR_PULSE = 0x02, /* Color Pulse mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_COLOR_WAVE = 0x03, /* Color Wave mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_STATIC = 0x04, /* Static mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_TEMPERATURE = 0x05, /* Temperature mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_VISOR = 0x06, /* Visor mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_MARQUEE = 0x07, /* Marquee mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_BLINK = 0x08, /* Blink mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_SEQUENTIAL = 0x09, /* Sequential mode */
|
||||
CORSAIR_LIGHTING_NODE_MODE_RAINBOW = 0x0A, /* Rainbow mode */
|
||||
};
|
||||
|
||||
class CorsairLightingNodeController
|
||||
{
|
||||
public:
|
||||
CorsairLightingNodeController(hid_device* dev_handle);
|
||||
~CorsairLightingNodeController();
|
||||
|
||||
std::string GetFirmwareString();
|
||||
|
||||
unsigned int GetStripsOnChannel(unsigned int channel);
|
||||
|
||||
void SetChannelEffect(unsigned char channel,
|
||||
unsigned char num_leds,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2,
|
||||
unsigned char red3,
|
||||
unsigned char grn3,
|
||||
unsigned char blu3
|
||||
);
|
||||
|
||||
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string firmware_version;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
|
||||
void SendFirmwareRequest();
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char start,
|
||||
unsigned char count,
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
|
||||
void SendBegin
|
||||
(
|
||||
unsigned char channel
|
||||
);
|
||||
|
||||
void SendEffectConfig
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char count,
|
||||
unsigned char led_type,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
unsigned char change_style,
|
||||
unsigned char color_0_red,
|
||||
unsigned char color_0_green,
|
||||
unsigned char color_0_blue,
|
||||
unsigned char color_1_red,
|
||||
unsigned char color_1_green,
|
||||
unsigned char color_1_blue,
|
||||
unsigned char color_2_red,
|
||||
unsigned char color_2_green,
|
||||
unsigned char color_2_blue,
|
||||
unsigned short temperature_0,
|
||||
unsigned short temperature_1,
|
||||
unsigned short temperature_2
|
||||
);
|
||||
|
||||
void SendTemperature();
|
||||
|
||||
void SendReset
|
||||
(
|
||||
unsigned char channel
|
||||
);
|
||||
|
||||
void SendPortState
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char state
|
||||
);
|
||||
|
||||
void SendBrightness();
|
||||
|
||||
void SendLEDCount();
|
||||
|
||||
void SendProtocol();
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "CorsairLightingNodeController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairLightingNode.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
|
||||
#define CORSAIR_LIGHTING_NODE_PRO_PID 0x0C0B
|
||||
#define CORSAIR_COMMANDER_PRO_PID 0x0C10
|
||||
#define CORSAIR_LS100_PID 0x0C1E
|
||||
#define CORSAIR_1000D_OBSIDIAN_PID 0x1D00
|
||||
#define CORSAIR_SPEC_OMEGA_RGB_PID 0x1D04
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char channel_count;
|
||||
const char * name;
|
||||
} corsair_node_device;
|
||||
|
||||
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const corsair_node_device device_list[] =
|
||||
{
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, "Corsair Lighting Node Core" },
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 2, "Corsair Lighting Node Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, "Corsair Commander Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, "Corsair LS100 Lighting Kit" },
|
||||
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, "Corsair 1000D Obsidian" },
|
||||
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 2, "Corsair SPEC OMEGA RGB" }
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairLightingNodeControllers *
|
||||
* *
|
||||
* Detect devices supported by the Corsair Lighting Node Pro driver *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for Corsair Lighting Node Devices
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev);
|
||||
|
||||
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
} /* DetectCorsairLightingNodeControllers() */
|
||||
@@ -0,0 +1,549 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairPeripheralController.cpp |
|
||||
| |
|
||||
| Driver for Corsair RGB keyboard, mouse, |
|
||||
| and mousemat lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/9/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "CorsairPeripheralController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
|
||||
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
|
||||
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
|
||||
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
|
||||
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
|
||||
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
|
||||
136, 137, 139, 140, 141};
|
||||
|
||||
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
|
||||
|
||||
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
ReadFirmwareInfo();
|
||||
|
||||
LightingControl();
|
||||
}
|
||||
|
||||
CorsairPeripheralController::~CorsairPeripheralController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
device_type CorsairPeripheralController::GetDeviceType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralController::GetFirmwareString()
|
||||
{
|
||||
return firmware_version;
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
SetLEDsKeyboardFull(colors);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
SetLEDsMouse(colors);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSEMAT:
|
||||
SetLEDsMousemat(colors);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HEADSET_STAND:
|
||||
/*-----------------------------------------------------*\
|
||||
| The logo zone of the ST100 is in the middle of the |
|
||||
| base LED strip, so remap the colors so that the logo |
|
||||
| is the last LED in the sequence. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<RGBColor> remap_colors;
|
||||
remap_colors.resize(colors.size());
|
||||
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
remap_colors[st100[i]] = colors[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The ST100 uses the mousemat protocol |
|
||||
\*-----------------------------------------------------*/
|
||||
SetLEDsMousemat(remap_colors);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char red_val[144];
|
||||
unsigned char grn_val[144];
|
||||
unsigned char blu_val[144];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffers |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(red_val, 0x00, sizeof( red_val ));
|
||||
memset(grn_val, 0x00, sizeof( grn_val ));
|
||||
memset(blu_val, 0x00, sizeof( blu_val ));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy red, green, and blue components into buffers |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
|
||||
{
|
||||
RGBColor color = colors[color_idx];
|
||||
red_val[keys[color_idx]] = RGBGetRValue(color);
|
||||
grn_val[keys[color_idx]] = RGBGetGValue(color);
|
||||
blu_val[keys[color_idx]] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send red bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
StreamPacket(1, 60, &red_val[0]);
|
||||
StreamPacket(2, 60, &red_val[60]);
|
||||
StreamPacket(3, 24, &red_val[120]);
|
||||
SubmitKeyboardFullColors(1, 3, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send green bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
StreamPacket(1, 60, &grn_val[0]);
|
||||
StreamPacket(2, 60, &grn_val[60]);
|
||||
StreamPacket(3, 24, &grn_val[120]);
|
||||
SubmitKeyboardFullColors(2, 3, 1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send blue bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
StreamPacket(1, 60, &blu_val[0]);
|
||||
StreamPacket(2, 60, &blu_val[60]);
|
||||
StreamPacket(3, 24, &blu_val[120]);
|
||||
SubmitKeyboardFullColors(3, 3, 2);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SetLEDsMouse(std::vector<RGBColor> colors)
|
||||
{
|
||||
SubmitMouseColors(colors.size(), &colors[0]);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SetLEDsMousemat(std::vector<RGBColor> colors)
|
||||
{
|
||||
SubmitMousematColors(colors.size(), &colors[0]);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char data_pkt[216];
|
||||
unsigned char red_val[144];
|
||||
unsigned char grn_val[144];
|
||||
unsigned char blu_val[144];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffers |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(data_pkt, 0x00, sizeof( data_pkt ));
|
||||
memset(red_val, 0x00, sizeof( red_val ));
|
||||
memset(grn_val, 0x00, sizeof( grn_val ));
|
||||
memset(blu_val, 0x00, sizeof( blu_val ));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Scale color values to 9-bit |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
|
||||
{
|
||||
RGBColor color = colors[color_idx];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
if( red > 7 ) red = 7;
|
||||
if( grn > 7 ) grn = 7;
|
||||
if( blu > 7 ) blu = 7;
|
||||
|
||||
red = 7 - red;
|
||||
grn = 7 - grn;
|
||||
blu = 7 - blu;
|
||||
|
||||
red_val[keys[color_idx]] = red;
|
||||
grn_val[keys[color_idx]] = grn;
|
||||
blu_val[keys[color_idx]] = blu;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Pack the color values, 2 values per byte |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int red_idx = 0; red_idx < 72; red_idx++)
|
||||
{
|
||||
data_pkt[red_idx] = red_val[(red_idx * 2) + 1] << 4 | red_val[red_idx * 2];
|
||||
}
|
||||
|
||||
for(int grn_idx = 0; grn_idx < 72; grn_idx++)
|
||||
{
|
||||
data_pkt[grn_idx + 72] = grn_val[(grn_idx * 2) + 1] << 4 | grn_val[grn_idx * 2];
|
||||
}
|
||||
|
||||
for(int blu_idx = 0; blu_idx < 72; blu_idx++)
|
||||
{
|
||||
data_pkt[blu_idx + 144] = blu_val[(blu_idx * 2) + 1] << 4 | blu_val[blu_idx * 2];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the packets |
|
||||
\*-----------------------------------------------------*/
|
||||
StreamPacket(1, 60, &data_pkt[0]);
|
||||
StreamPacket(2, 60, &data_pkt[60]);
|
||||
StreamPacket(3, 60, &data_pkt[120]);
|
||||
StreamPacket(4, 36, &data_pkt[180]);
|
||||
|
||||
SubmitKeyboardLimitedColors(216);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void CorsairPeripheralController::LightingControl()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
|
||||
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Lighting control byte needs to be 3 for keyboards and |
|
||||
| headset stand, 1 for mice and mousepads |
|
||||
\*-----------------------------------------------------*/
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
usb_buf[0x05] = 0x03;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
usb_buf[0x05] = 0x01;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSEMAT:
|
||||
usb_buf[0x05] = 0x04;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HEADSET_STAND:
|
||||
usb_buf[0x05] = 0x03;
|
||||
break;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SpecialFunctionControl()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
|
||||
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
{
|
||||
int actual;
|
||||
char usb_buf[65];
|
||||
char offset = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply as |
|
||||
| a feature report. |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char*)usb_buf, 65);
|
||||
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 65, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
hid_send_feature_report(dev, (unsigned char*)usb_buf, 65);
|
||||
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 65);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device type |
|
||||
| 0xC0 Device is a keyboard |
|
||||
| 0xC1 Device is a mouse |
|
||||
| 0xC2 Device is a mousepad or headset stand |
|
||||
\*-----------------------------------------------------*/
|
||||
switch((unsigned char)usb_buf[0x14 + offset])
|
||||
{
|
||||
case 0xC0:
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
break;
|
||||
|
||||
case 0xC1:
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
{
|
||||
unsigned short pid = (unsigned short)(usb_buf[0x0F] << 8) + (unsigned char)(usb_buf[0x0E]);
|
||||
|
||||
switch(pid)
|
||||
{
|
||||
case 0x0A34:
|
||||
type = DEVICE_TYPE_HEADSET_STAND;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
|
||||
default:
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Format firmware version string if device type is valid|
|
||||
\*-----------------------------------------------------*/
|
||||
if(type != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::StreamPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char data_sz,
|
||||
unsigned char* data_ptr
|
||||
)
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Stream packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_STREAM;
|
||||
usb_buf[0x02] = packet_id;
|
||||
usb_buf[0x03] = data_sz;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], data_ptr, data_sz);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitKeyboardFullColors
|
||||
(
|
||||
unsigned char color_channel,
|
||||
unsigned char packet_count,
|
||||
unsigned char finish_val
|
||||
)
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Keyboard 24-Bit Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
|
||||
usb_buf[0x03] = color_channel;
|
||||
usb_buf[0x04] = packet_count;
|
||||
usb_buf[0x05] = finish_val;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitKeyboardLimitedColors
|
||||
(
|
||||
unsigned char byte_count
|
||||
)
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Keyboard 9-Bit Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
|
||||
usb_buf[0x05] = byte_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitMouseColors
|
||||
(
|
||||
unsigned char num_zones,
|
||||
RGBColor * color_data
|
||||
)
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x03] = num_zones;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
usb_buf[(zone_idx * 4) + 5] = zone_idx;
|
||||
usb_buf[(zone_idx * 4) + 6] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 7] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 8] = RGBGetBValue(color_data[zone_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitMousematColors
|
||||
(
|
||||
unsigned char num_zones,
|
||||
RGBColor * color_data
|
||||
)
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x03] = num_zones;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
usb_buf[(zone_idx * 3) + 5] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 6] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 7] = RGBGetBValue(color_data[zone_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairPeripheralController.h |
|
||||
| |
|
||||
| Definitions and types for Corsair RGB |
|
||||
| keyboard, mouse, and mousemat lighting |
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/9/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_COMMAND_WRITE = 0x07,
|
||||
CORSAIR_COMMAND_READ = 0x0E,
|
||||
CORSAIR_COMMAND_STREAM = 0x7F
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_PROPERTY_FIRMWARE_INFO = 0x01,
|
||||
CORSAIR_PROPERTY_RESET = 0x02,
|
||||
CORSAIR_PROPERTY_SPECIAL_FUNCTION = 0x04,
|
||||
CORSAIR_PROPERTY_LIGHTING_CONTROL = 0x05,
|
||||
CORSAIR_PROPERTY_HARDWARE_PROFILE = 0x13,
|
||||
CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR = 0x22,
|
||||
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9 = 0x27,
|
||||
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24 = 0x28,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_LIGHTING_CONTROL_HARDWARE = 0x01,
|
||||
CORSAIR_LIGHTING_CONTROL_SOFTWARE = 0x02
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CORSAIR_COLOR_CHANNEL_RED = 0x01,
|
||||
CORSAIR_COLOR_CHANNEL_GREEN = 0x02,
|
||||
CORSAIR_COLOR_CHANNEL_BLUE = 0x03
|
||||
};
|
||||
|
||||
class CorsairPeripheralController
|
||||
{
|
||||
public:
|
||||
CorsairPeripheralController(hid_device* dev_handle);
|
||||
~CorsairPeripheralController();
|
||||
|
||||
device_type GetDeviceType();
|
||||
std::string GetFirmwareString();
|
||||
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
|
||||
void SetLEDsKeyboardLimited(std::vector<RGBColor> colors);
|
||||
void SetLEDsMouse(std::vector<RGBColor> colors);
|
||||
void SetLEDsMousemat(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
std::string firmware_version;
|
||||
device_type type;
|
||||
|
||||
void LightingControl();
|
||||
void SpecialFunctionControl();
|
||||
|
||||
void ReadFirmwareInfo();
|
||||
|
||||
void StreamPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char data_sz,
|
||||
unsigned char* data_ptr
|
||||
);
|
||||
|
||||
void SubmitKeyboardFullColors
|
||||
(
|
||||
unsigned char color_channel,
|
||||
unsigned char packet_count,
|
||||
unsigned char finish_val
|
||||
);
|
||||
|
||||
void SubmitKeyboardLimitedColors
|
||||
(
|
||||
unsigned char byte_count
|
||||
);
|
||||
|
||||
void SubmitMouseColors
|
||||
(
|
||||
unsigned char num_zones,
|
||||
RGBColor * color_data
|
||||
);
|
||||
|
||||
void SubmitMousematColors
|
||||
(
|
||||
unsigned char num_zones,
|
||||
RGBColor * color_data
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,160 @@
|
||||
#include "CorsairPeripheralController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairPeripheral.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
| List taken from ckb-next |
|
||||
| Non-RGB keyboards were omitted from this list |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_K55_RGB_PID 0x1B3D
|
||||
|
||||
#define CORSAIR_K65_RGB_PID 0x1B17
|
||||
#define CORSAIR_K65_LUX_RGB_PID 0x1B37
|
||||
#define CORSAIR_K65_RGB_RAPIDFIRE_PID 0x1B39
|
||||
|
||||
#define CORSAIR_K68_RGB 0x1B4F
|
||||
|
||||
#define CORSAIR_K70_RGB_PID 0x1B13
|
||||
#define CORSAIR_K70_LUX_RGB_PID 0x1B33
|
||||
#define CORSAIR_K70_RGB_RAPIDFIRE_PID 0x1B38
|
||||
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
|
||||
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
|
||||
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
|
||||
|
||||
#define CORSAIR_K95_RGB_PID 0x1B11
|
||||
#define CORSAIR_K95_PLATINUM_PID 0x1B2D
|
||||
|
||||
#define CORSAIR_STRAFE_PID 0x1B20
|
||||
#define CORSAIR_STRAFE_MK2_PID 0x1B48
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
| List taken from ckb-next |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_GLAIVE_RGB_PRO_PID 0x1B74
|
||||
#define CORSAIR_HARPOON_RGB_PID 0x1B3C
|
||||
#define CORSAIR_HARPOON_RGB_PRO_PID 0x1B75
|
||||
#define CORSAIR_M65_PRO_PID 0x1B2E
|
||||
#define CORSAIR_M65_RGB_ELITE_PID 0x1B5A
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mousepad product IDs |
|
||||
| List taken from ckb-next |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Headset Stand product IDs |
|
||||
| List taken from ckb-next |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_ST100_PID 0x0A34
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} corsair_node_device;
|
||||
|
||||
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const corsair_node_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
// { CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, "Corsair K55 RGB" }, //Not per-key, disabled for now
|
||||
{ CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, "Corsair K65 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, "Corsair K65 LUX RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, "Corsair K65 RGB RAPIDFIRE" },
|
||||
{ CORSAIR_VID, CORSAIR_K68_RGB, 1, "Corsair K68 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, "Corsair K70 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_LUX_RGB_PID, 1, "Corsair K70 LUX RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_RAPIDFIRE_PID, 1, "Corsair K70 RGB RAPIDFIRE" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_PID, 1, "Corsair K70 RGB MK.2" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_SE_PID, 1, "Corsair K70 RGB MK.2 SE" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, "Corsair K70 RGB MK.2 Low Profile" },
|
||||
{ CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, "Corsair K95 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, "Corsair K95 RGB PLATINUM" },
|
||||
{ CORSAIR_VID, CORSAIR_STRAFE_PID, 1, "Corsair Strafe" },
|
||||
{ CORSAIR_VID, CORSAIR_STRAFE_MK2_PID, 1, "Corsair Strafe MK.2" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_GLAIVE_RGB_PRO_PID, 1, "Corsair Glaive RGB PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PID, 1, "Corsair Harpoon RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PRO_PID, 1, "Corsair Harpoon RGB PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_M65_PRO_PID, 1, "Corsair M65 PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_M65_RGB_ELITE_PID, 1, "Corsair M65 RGB Elite" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Headset Stands |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_ST100_PID, 0, "Corsair ST100 RGB" }
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairPeripheralControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairPeripheralControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for Corsair RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->usage_page == 0xFFC2))
|
||||
#else
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
|
||||
|
||||
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
#include "CorsairProController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairPro.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForCorsairProController *
|
||||
* *
|
||||
* Tests the given address to see if a Corsair Pro controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForCorsairProController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x24);
|
||||
|
||||
if (res != 0x02)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x25);
|
||||
|
||||
if (res != 0x02)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if (res != 0x1C)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x44);
|
||||
|
||||
if (res != 0x03)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForCorsairProController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairProControllers *
|
||||
* *
|
||||
* Detect Corsair Pro controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
CorsairProController* new_corsair_pro;
|
||||
RGBController_CorsairPro* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for Corsair controller at 0x58
|
||||
if (TestForCorsairProController(busses[bus], 0x58))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x58);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x59
|
||||
if (TestForCorsairProController(busses[bus], 0x59))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x59);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5A
|
||||
if (TestForCorsairProController(busses[bus], 0x5A))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x5A);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5B
|
||||
if (TestForCorsairProController(busses[bus], 0x5B))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x5B);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5C
|
||||
if (TestForCorsairProController(busses[bus], 0x5C))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x5C);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5D
|
||||
if (TestForCorsairProController(busses[bus], 0x5D))
|
||||
{
|
||||
new_corsair_pro = new CorsairProController(busses[bus], 0x5D);
|
||||
new_controller = new RGBController_CorsairPro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectCorsairProControllers() */
|
||||
+18
-17
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairController.h |
|
||||
| CorsairVengeanceController.h |
|
||||
| |
|
||||
| Driver for Corsair Vengeance RGB RAM |
|
||||
| lighting controller |
|
||||
@@ -7,10 +7,10 @@
|
||||
| Adam Honse (CalcProgrammer1) 3/8/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "CorsairController.h"
|
||||
#include "CorsairVengeanceController.h"
|
||||
#include <cstring>
|
||||
|
||||
CorsairController::CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
CorsairVengeanceController::CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
@@ -19,22 +19,32 @@ CorsairController::CorsairController(i2c_smbus_interface* bus, corsair_dev_id de
|
||||
led_count = 1;
|
||||
}
|
||||
|
||||
CorsairController::~CorsairController()
|
||||
CorsairVengeanceController::~CorsairVengeanceController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char * CorsairController::GetDeviceName()
|
||||
std::string CorsairVengeanceController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
unsigned int CorsairController::GetLEDCount()
|
||||
std::string CorsairVengeanceController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned int CorsairVengeanceController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void CorsairController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
void CorsairVengeanceController::SetLEDColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_FADE_TIME, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_RED_VAL, red);
|
||||
@@ -43,16 +53,7 @@ void CorsairController::SetAllColors(unsigned char red, unsigned char green, uns
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
|
||||
}
|
||||
|
||||
void CorsairController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void CorsairVengeanceController::SetMode(unsigned char /*mode*/)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_FADE_TIME, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_RED_VAL, red);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_GREEN_VAL, green);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_BLUE_VAL, blue);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
|
||||
}
|
||||
|
||||
void CorsairController::SetMode(unsigned char mode)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_VENGEANCE_RGB_CMD_MODE, CORSAIR_VENGEANCE_RGB_MODE_SINGLE);
|
||||
}
|
||||
+9
-8
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairController.h |
|
||||
| CorsairVengeanceController.h |
|
||||
| |
|
||||
| Definitions and types for Corsair |
|
||||
| Vengeance RGB RAM lighting controller |
|
||||
@@ -7,6 +7,7 @@
|
||||
| Adam Honse (CalcProgrammer1) 3/8/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
@@ -32,22 +33,22 @@ enum
|
||||
CORSAIR_NUMBER_MODES /* Number of Corsair modes */
|
||||
};
|
||||
|
||||
class CorsairController
|
||||
class CorsairVengeanceController
|
||||
{
|
||||
public:
|
||||
CorsairController(i2c_smbus_interface* bus, corsair_dev_id dev);
|
||||
~CorsairController();
|
||||
CorsairVengeanceController(i2c_smbus_interface* bus, corsair_dev_id dev);
|
||||
~CorsairVengeanceController();
|
||||
|
||||
char* GetDeviceName();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
i2c_smbus_interface * bus;
|
||||
corsair_dev_id dev;
|
||||
};
|
||||
};
|
||||
+44
-28
@@ -1,6 +1,6 @@
|
||||
#include "CorsairController.h"
|
||||
#include "CorsairVengeanceController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Corsair.h"
|
||||
#include "RGBController_CorsairVengeance.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForCorsairController *
|
||||
* TestForCorsairVengeanceController *
|
||||
* *
|
||||
* Tests the given address to see if a Corsair controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
|
||||
bool TestForCorsairVengeanceController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
@@ -37,11 +37,11 @@ bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForCorsairController() */
|
||||
} /* TestForCorsairVengeanceController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairControllers *
|
||||
* DetectCorsairVengeanceControllers *
|
||||
* *
|
||||
* Detect Corsair controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
@@ -50,60 +50,76 @@ bool TestForCorsairController(i2c_smbus_interface* bus, unsigned char address)
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
void DetectCorsairVengeanceControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
CorsairController* new_corsair;
|
||||
RGBController_Corsair* new_controller;
|
||||
CorsairVengeanceController* new_corsair;
|
||||
RGBController_CorsairVengeance* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for Corsair controller at 0x58
|
||||
if (TestForCorsairController(busses[bus], 0x58))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x58))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x58);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x58);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x59
|
||||
if (TestForCorsairController(busses[bus], 0x59))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x59))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x59);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x59);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5A
|
||||
if (TestForCorsairController(busses[bus], 0x5A))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5A))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x5A);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5A);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5B
|
||||
if (TestForCorsairController(busses[bus], 0x5B))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5B))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x5B);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5B);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5C
|
||||
if (TestForCorsairController(busses[bus], 0x5C))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5C))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x5C);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5C);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5D
|
||||
if (TestForCorsairController(busses[bus], 0x5D))
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5D))
|
||||
{
|
||||
new_corsair = new CorsairController(busses[bus], 0x5D);
|
||||
new_controller = new RGBController_Corsair(new_corsair);
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5D);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5E
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5E))
|
||||
{
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5E);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5F
|
||||
if (TestForCorsairVengeanceController(busses[bus], 0x5F))
|
||||
{
|
||||
new_corsair = new CorsairVengeanceController(busses[bus], 0x5F);
|
||||
new_controller = new RGBController_CorsairVengeance(new_corsair);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectCorsairControllers() */
|
||||
} /* DetectCorsairVengeanceControllers() */
|
||||
+72
-46
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairProController.cpp |
|
||||
| CorsairVengeanceProController.cpp |
|
||||
| |
|
||||
| Definitions and types for Corsair |
|
||||
| Vengeance Pro RGB RAM lighting controller|
|
||||
@@ -7,21 +7,12 @@
|
||||
| Adam Honse (CalcProgrammer1) 6/30/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "CorsairProController.h"
|
||||
#include "CorsairVengeanceProController.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
|
||||
CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
@@ -29,7 +20,9 @@ CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev
|
||||
strcpy(device_name, "Corsair Vengeance Pro RGB");
|
||||
led_count = CORSAIR_PRO_LED_COUNT;
|
||||
|
||||
for (int i = 0; i < led_count; i++)
|
||||
effect_mode = CORSAIR_PRO_MODE_STATIC;
|
||||
|
||||
for (unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
led_red[i] = 0;
|
||||
led_green[i] = 0;
|
||||
@@ -37,24 +30,39 @@ CorsairProController::CorsairProController(i2c_smbus_interface* bus, corsair_dev
|
||||
}
|
||||
}
|
||||
|
||||
CorsairProController::~CorsairProController()
|
||||
CorsairVengeanceProController::~CorsairVengeanceProController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* CorsairProController::GetDeviceName()
|
||||
std::string CorsairVengeanceProController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
unsigned int CorsairProController::GetLEDCount()
|
||||
std::string CorsairVengeanceProController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned int CorsairVengeanceProController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void CorsairProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
unsigned char CorsairVengeanceProController::GetEffect()
|
||||
{
|
||||
for (int i = 0; i < led_count; i++)
|
||||
return(effect_mode);
|
||||
}
|
||||
|
||||
void CorsairVengeanceProController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
for (unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
led_red[i] = red;
|
||||
led_green[i] = green;
|
||||
@@ -62,19 +70,19 @@ void CorsairProController::SetAllColors(unsigned char red, unsigned char green,
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void CorsairVengeanceProController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
led_red[led] = red;
|
||||
led_green[led] = green;
|
||||
led_blue[led] = blue;
|
||||
}
|
||||
|
||||
void CorsairProController::ApplyColors()
|
||||
void CorsairVengeanceProController::ApplyColors()
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x02);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
@@ -87,24 +95,47 @@ void CorsairProController::ApplyColors()
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x82, 0x02);
|
||||
}
|
||||
|
||||
void CorsairProController::SetEffect(unsigned char mode)
|
||||
void CorsairVengeanceProController::SetEffect(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
|
||||
Sleep(1);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
Sleep(1);
|
||||
effect_mode = mode;
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, mode); //Mode
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_SPEED_MEDIUM); //Speed
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_EFFECT_RANDOM_COLORS); //Custom color
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, CORSAIR_PRO_DIRECTION_UP); //Direction
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 red
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 green
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 1 blue
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
unsigned char random_byte;
|
||||
|
||||
if(random)
|
||||
{
|
||||
random_byte = CORSAIR_PRO_EFFECT_RANDOM_COLORS;
|
||||
}
|
||||
else
|
||||
{
|
||||
random_byte = CORSAIR_PRO_EFFECT_CUSTOM_COLORS;
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, effect_mode); //Mode
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, speed); //Speed
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, random_byte); //Custom color
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, direction); //Direction
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red1); // Custom color 1 red
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn1); // Custom color 1 green
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu1); // Custom color 1 blue
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 red
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 green
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00); // Custom color 2 blue
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, red2); // Custom color 2 red
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, grn2); // Custom color 2 green
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, blu2); // Custom color 2 blue
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, CORSAIR_PRO_REG_COMMAND, 0x00);
|
||||
@@ -119,19 +150,14 @@ void CorsairProController::SetEffect(unsigned char mode)
|
||||
WaitReady();
|
||||
}
|
||||
|
||||
void CorsairProController::SetCustom()
|
||||
{
|
||||
SetEffect(CORSAIR_PRO_MODE_STATIC);
|
||||
}
|
||||
|
||||
bool CorsairProController::WaitReady()
|
||||
bool CorsairVengeanceProController::WaitReady()
|
||||
{
|
||||
int i = 0;
|
||||
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
|
||||
{
|
||||
i++;
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+21
-9
@@ -1,5 +1,5 @@
|
||||
/*-----------------------------------------*\
|
||||
| CorsairProController.h |
|
||||
| CorsairVengeanceProController.h |
|
||||
| |
|
||||
| Definitions and types for Corsair |
|
||||
| Vengeance Pro RGB RAM lighting controller|
|
||||
@@ -7,6 +7,7 @@
|
||||
| Adam Honse (CalcProgrammer1) 6/30/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
@@ -59,16 +60,27 @@ enum
|
||||
CORSAIR_PRO_DIRECTION_HORIZONTAL = 0x03, /* Horizontal direction */
|
||||
};
|
||||
|
||||
class CorsairProController
|
||||
class CorsairVengeanceProController
|
||||
{
|
||||
public:
|
||||
CorsairProController(i2c_smbus_interface* bus, corsair_dev_id dev);
|
||||
~CorsairProController();
|
||||
CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev);
|
||||
~CorsairVengeanceProController();
|
||||
|
||||
char* GetDeviceName();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
void SetEffect(unsigned char mode);
|
||||
void SetCustom();
|
||||
unsigned char GetEffect();
|
||||
void SetEffect(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
bool random,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
);
|
||||
|
||||
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
@@ -78,11 +90,11 @@ public:
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
|
||||
unsigned char effect_mode;
|
||||
unsigned char led_red[CORSAIR_PRO_LED_COUNT];
|
||||
unsigned char led_green[CORSAIR_PRO_LED_COUNT];
|
||||
unsigned char led_blue[CORSAIR_PRO_LED_COUNT];
|
||||
|
||||
i2c_smbus_interface* bus;
|
||||
corsair_dev_id dev;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "CorsairVengeanceProController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairVengeancePro.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForCorsairVengeanceProController *
|
||||
* *
|
||||
* Tests the given address to see if a Corsair Pro controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForCorsairVengeanceProController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if (res != 0x1C)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x44);
|
||||
|
||||
if (!((res == 0x03) || (res == 0x04)))
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForCorsairVengeanceProController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCorsairVengeanceProControllers *
|
||||
* *
|
||||
* Detect Corsair Vengeance Pro controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairVengeanceProControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
CorsairVengeanceProController* new_corsair_pro;
|
||||
RGBController_CorsairVengeancePro* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for Corsair controller at 0x58
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x58))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x58);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x59
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x59))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x59);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5A
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5A))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5A);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5B
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5B))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5B);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5C
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5C))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5C);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5D
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5D))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5D);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5E
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5E))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5E);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
// Check for Corsair controller at 0x5F
|
||||
if (TestForCorsairVengeanceProController(busses[bus], 0x5F))
|
||||
{
|
||||
new_corsair_pro = new CorsairVengeanceProController(busses[bus], 0x5F);
|
||||
new_controller = new RGBController_CorsairVengeancePro(new_corsair_pro);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectCorsairVengeanceProControllers() */
|
||||
@@ -0,0 +1,150 @@
|
||||
/*-----------------------------------------*\
|
||||
| CrucialController.cpp |
|
||||
| |
|
||||
| Driver for Crucial Ballistix RGB lighting|
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/19/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CrucialController.h"
|
||||
#include <cstring>
|
||||
|
||||
CrucialController::CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
}
|
||||
|
||||
CrucialController::~CrucialController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CrucialController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string CrucialController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned int CrucialController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void CrucialController::SetMode(unsigned char mode)
|
||||
{
|
||||
SendEffectMode(mode, 0x10);
|
||||
}
|
||||
|
||||
void CrucialController::SetAllColorsDirect(RGBColor* colors)
|
||||
{
|
||||
SendDirectColors(colors);
|
||||
}
|
||||
|
||||
void CrucialController::SetAllColorsEffect(RGBColor* colors)
|
||||
{
|
||||
for(int led_idx = 0; led_idx < 8; led_idx++)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char grn = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blu = RGBGetBValue(colors[led_idx]);
|
||||
SendEffectColor(led_idx, red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void CrucialController::SendBrightness(unsigned char brightness)
|
||||
{
|
||||
CrucialRegisterWrite(0x82EE, 0xFF);
|
||||
CrucialRegisterWrite(0x82EF, brightness);
|
||||
CrucialRegisterWrite(0x82F0, 0x83);
|
||||
}
|
||||
|
||||
void CrucialController::SendEffectMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
CrucialRegisterWrite(0x820F, mode);
|
||||
CrucialRegisterWrite(0x82EE, 0x00);
|
||||
CrucialRegisterWrite(0x82EF, speed);
|
||||
CrucialRegisterWrite(0x82F0, 0x84);
|
||||
}
|
||||
|
||||
void CrucialController::SendDirectColors(RGBColor* color_buf)
|
||||
{
|
||||
//Red Channels
|
||||
CrucialRegisterWrite(0x8300, RGBGetRValue(color_buf[0]));
|
||||
CrucialRegisterWrite(0x8301, RGBGetRValue(color_buf[1]));
|
||||
CrucialRegisterWrite(0x8302, RGBGetRValue(color_buf[2]));
|
||||
CrucialRegisterWrite(0x8303, RGBGetRValue(color_buf[3]));
|
||||
CrucialRegisterWrite(0x8304, RGBGetRValue(color_buf[4]));
|
||||
CrucialRegisterWrite(0x8305, RGBGetRValue(color_buf[5]));
|
||||
CrucialRegisterWrite(0x8306, RGBGetRValue(color_buf[6]));
|
||||
CrucialRegisterWrite(0x8307, RGBGetRValue(color_buf[7]));
|
||||
|
||||
//Green Channels
|
||||
CrucialRegisterWrite(0x8340, RGBGetGValue(color_buf[0]));
|
||||
CrucialRegisterWrite(0x8341, RGBGetGValue(color_buf[1]));
|
||||
CrucialRegisterWrite(0x8342, RGBGetGValue(color_buf[2]));
|
||||
CrucialRegisterWrite(0x8343, RGBGetGValue(color_buf[3]));
|
||||
CrucialRegisterWrite(0x8344, RGBGetGValue(color_buf[4]));
|
||||
CrucialRegisterWrite(0x8345, RGBGetGValue(color_buf[5]));
|
||||
CrucialRegisterWrite(0x8346, RGBGetGValue(color_buf[6]));
|
||||
CrucialRegisterWrite(0x8347, RGBGetGValue(color_buf[7]));
|
||||
|
||||
//Blue Channels
|
||||
CrucialRegisterWrite(0x8380, RGBGetBValue(color_buf[0]));
|
||||
CrucialRegisterWrite(0x8381, RGBGetBValue(color_buf[1]));
|
||||
CrucialRegisterWrite(0x8382, RGBGetBValue(color_buf[2]));
|
||||
CrucialRegisterWrite(0x8383, RGBGetBValue(color_buf[3]));
|
||||
CrucialRegisterWrite(0x8384, RGBGetBValue(color_buf[4]));
|
||||
CrucialRegisterWrite(0x8385, RGBGetBValue(color_buf[5]));
|
||||
CrucialRegisterWrite(0x8386, RGBGetBValue(color_buf[6]));
|
||||
CrucialRegisterWrite(0x8387, RGBGetBValue(color_buf[7]));
|
||||
}
|
||||
|
||||
unsigned char CrucialController::CrucialRegisterRead(crucial_register reg)
|
||||
{
|
||||
//Write Crucial register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Read Crucial value
|
||||
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
|
||||
|
||||
}
|
||||
|
||||
void CrucialController::CrucialRegisterWrite(crucial_register reg, unsigned char val)
|
||||
{
|
||||
//Write Crucial register
|
||||
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
|
||||
|
||||
//Write Crucial value
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
|
||||
|
||||
}
|
||||
|
||||
void CrucialController::SendEffectColor
|
||||
(
|
||||
unsigned int led_idx,
|
||||
unsigned int red,
|
||||
unsigned int green,
|
||||
unsigned int blue
|
||||
)
|
||||
{
|
||||
CrucialRegisterWrite(0x82E9, (1 << led_idx));
|
||||
CrucialRegisterWrite(0x82EA, 0x00);
|
||||
CrucialRegisterWrite(0x82EB, 0x00);
|
||||
CrucialRegisterWrite(0x82EC, 0x00);
|
||||
CrucialRegisterWrite(0x82ED, red);
|
||||
CrucialRegisterWrite(0x82EE, green);
|
||||
CrucialRegisterWrite(0x82EF, blue);
|
||||
CrucialRegisterWrite(0x82F0, 0x01);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*-----------------------------------------*\
|
||||
| CrucialController.h |
|
||||
| |
|
||||
| Definitions and types for Crucial |
|
||||
| Ballistix RGB lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/19/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char crucial_dev_id;
|
||||
typedef unsigned short crucial_register;
|
||||
|
||||
enum
|
||||
{
|
||||
CRUCIAL_MODE_SHIFT = 0x1F, /* Shift effect mode */
|
||||
CRUCIAL_MODE_GRADIENT_SHIFT = 0x2F, /* Gradient shift mode */
|
||||
CRUCIAL_MODE_FILL = 0x3F, /* Fill effect mode */
|
||||
CRUCIAL_MODE_STACK = 0x4F, /* Stack effect mode */
|
||||
CRUCIAL_MODE_DOUBLE_STACK = 0x5F, /* Double stack effect mode */
|
||||
CRUCIAL_MODE_BREATHING = 0x6F, /* Breathing effect mode */
|
||||
CRUCIAL_MODE_MOTION_POINT = 0x7F, /* Motion point effect mode */
|
||||
CRUCIAL_MODE_INSIDE_OUT = 0x8F, /* Inside out effect mode */
|
||||
CRUCIAL_MODE_COLOR_STEP = 0x9F, /* Color step effect mode */
|
||||
CRUCIAL_MODE_WATER_WAVE = 0xAF, /* Water wave effect mode */
|
||||
CRUCIAL_MODE_FLASHING = 0xBF, /* Flashing effect mode */
|
||||
CRUCIAL_MODE_STATIC = 0xCF, /* Static effect mode */
|
||||
};
|
||||
|
||||
class CrucialController
|
||||
{
|
||||
public:
|
||||
CrucialController(i2c_smbus_interface* bus, crucial_dev_id dev);
|
||||
~CrucialController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
void SetAllColorsDirect(RGBColor* colors);
|
||||
void SetAllColorsEffect(RGBColor* colors);
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char CrucialRegisterRead(crucial_register reg);
|
||||
void CrucialRegisterWrite(crucial_register reg, unsigned char val);
|
||||
|
||||
private:
|
||||
char device_name[16];
|
||||
unsigned char config_table[64];
|
||||
unsigned int led_count;
|
||||
unsigned char channel_cfg;
|
||||
i2c_smbus_interface * bus;
|
||||
crucial_dev_id dev;
|
||||
|
||||
void SendEffectColor
|
||||
(
|
||||
unsigned int led_idx,
|
||||
unsigned int red,
|
||||
unsigned int green,
|
||||
unsigned int blue
|
||||
);
|
||||
|
||||
void SendDirectColors(RGBColor* color_buf);
|
||||
void SendBrightness(unsigned char brightness);
|
||||
void SendEffectMode(unsigned char mode, unsigned char speed);
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "CrucialController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Crucial.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for Crucial RAM |
|
||||
\*----------------------------------------------------------------------*/
|
||||
#define CRUCIAL_ADDRESS_COUNT 4
|
||||
|
||||
static const unsigned char crucial_addresses[] =
|
||||
{
|
||||
0x20,
|
||||
0x21,
|
||||
0x22,
|
||||
0x23
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForCrucialController *
|
||||
* *
|
||||
* Tests the given address to see if an Crucial controller exists there. First does a*
|
||||
* quick write to test for a response, and if so does a simple read at 0xA0 to test *
|
||||
* for incrementing values 0...F which was observed at this location during data dump *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForCrucialController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
for (int i = 0xA0; i < 0xB0; i++)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, i);
|
||||
|
||||
if (res != (i - 0xA0))
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForCrucialController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectCrucialControllers *
|
||||
* *
|
||||
* Detect Crucial controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCrucialControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
CrucialController* new_crucial;
|
||||
RGBController_Crucial* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Add Crucial controllers
|
||||
for (unsigned int address_list_idx = 0; address_list_idx < CRUCIAL_ADDRESS_COUNT; address_list_idx++)
|
||||
{
|
||||
if (TestForCrucialController(busses[bus], crucial_addresses[address_list_idx]))
|
||||
{
|
||||
new_crucial = new CrucialController(busses[bus], crucial_addresses[address_list_idx]);
|
||||
new_controller = new RGBController_Crucial(new_crucial);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectCrucialControllers() */
|
||||
@@ -0,0 +1,187 @@
|
||||
/*-----------------------------------------*\
|
||||
| DuckyKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for Ducky RGB keyboardlighting |
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "DuckyKeyboardController.h"
|
||||
|
||||
DuckyKeyboardController::DuckyKeyboardController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
SendInitialize();
|
||||
}
|
||||
|
||||
DuckyKeyboardController::~DuckyKeyboardController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendColors
|
||||
(
|
||||
unsigned char* color_data,
|
||||
unsigned int color_data_size
|
||||
)
|
||||
{
|
||||
unsigned int bytes_sent;
|
||||
unsigned char* color_data_ptr = color_data;
|
||||
|
||||
SendInitializeColorPacket();
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
bytes_sent = SendColorDataPacket(i, color_data_ptr, color_data_size);
|
||||
|
||||
color_data_ptr += bytes_sent;
|
||||
color_data_size -= bytes_sent;
|
||||
}
|
||||
|
||||
SendTerminateColorPacket();
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendInitialize()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Initialize Direct Mode packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x41;
|
||||
usb_buf[0x02] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendInitializeColorPacket()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Initialize Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x56;
|
||||
usb_buf[0x02] = 0x81;
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x09] = 0x08;
|
||||
usb_buf[0x0D] = 0xAA;
|
||||
usb_buf[0x0E] = 0xAA;
|
||||
usb_buf[0x0F] = 0xAA;
|
||||
usb_buf[0x10] = 0xAA;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
unsigned int DuckyKeyboardController::SendColorDataPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char* color_data,
|
||||
unsigned int color_size
|
||||
)
|
||||
{
|
||||
unsigned int bytes_sent;
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Color Data packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x56;
|
||||
usb_buf[0x02] = 0x83;
|
||||
usb_buf[0x03] = packet_id;
|
||||
|
||||
if(packet_id == 0x00)
|
||||
{
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x09] = 0x80;
|
||||
usb_buf[0x0A] = 0x01;
|
||||
usb_buf[0x0C] = 0xC1;
|
||||
usb_buf[0x11] = 0xFF;
|
||||
usb_buf[0x12] = 0xFF;
|
||||
usb_buf[0x13] = 0xFF;
|
||||
usb_buf[0x14] = 0xFF;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(packet_id == 0x00)
|
||||
{
|
||||
bytes_sent = 65 - 0x19;
|
||||
|
||||
if(color_size < bytes_sent)
|
||||
{
|
||||
bytes_sent = color_size;
|
||||
}
|
||||
|
||||
memcpy(&usb_buf[0x19], color_data, bytes_sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_sent = 65 - 0x05;
|
||||
|
||||
if(color_size < bytes_sent)
|
||||
{
|
||||
bytes_sent = color_size;
|
||||
}
|
||||
|
||||
memcpy(&usb_buf[0x05], color_data, bytes_sent);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
|
||||
return(bytes_sent);
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendTerminateColorPacket()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Terminate Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x51;
|
||||
usb_buf[0x02] = 0x28;
|
||||
usb_buf[0x05] = 0xFF;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*-----------------------------------------*\
|
||||
| DuckyKeyboardController.h |
|
||||
| |
|
||||
| Definitions and types for Ducky RGB |
|
||||
| keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class DuckyKeyboardController
|
||||
{
|
||||
public:
|
||||
DuckyKeyboardController(hid_device* dev_handle);
|
||||
~DuckyKeyboardController();
|
||||
|
||||
void SendColors
|
||||
(
|
||||
unsigned char* color_data,
|
||||
unsigned int color_data_size
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
void SendInitialize();
|
||||
void SendInitializeColorPacket();
|
||||
unsigned int SendColorDataPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char* color_data,
|
||||
unsigned int color_size
|
||||
);
|
||||
void SendTerminateColorPacket();
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "DuckyKeyboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_DuckyKeyboard.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Ducky vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define DUCKY_VID 0x04D9
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define DUCKY_SHINE_7_ONE_2_RGB_PID 0x0348
|
||||
#define DUCKY_ONE_2_RGB_TKL_PID 0x0356
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} ducky_device;
|
||||
|
||||
#define DUCKY_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const ducky_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ DUCKY_VID, DUCKY_SHINE_7_ONE_2_RGB_PID, 1, "Ducky Shine 7/Ducky One 2 RGB" },
|
||||
{ DUCKY_VID, DUCKY_ONE_2_RGB_TKL_PID, 1, "Ducky One 2 RGB TKL" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectDuckyKeyboardControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Ducky RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectDuckyKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < DUCKY_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for Ducky RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
DuckyKeyboardController* controller = new DuckyKeyboardController(dev);
|
||||
|
||||
RGBController_DuckyKeyboard* rgb_controller = new RGBController_DuckyKeyboard(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| EKController.cpp |
|
||||
| |
|
||||
| Driver for EK Loop Connect |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Jul 2020 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "EKController.h"
|
||||
|
||||
EKController::EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
|
||||
{
|
||||
int tmp_size = wcslen(_vendor);
|
||||
|
||||
dev = dev_handle;
|
||||
|
||||
for(int i=0; (i < tmp_size) && (i < EK_DEVICE_NAME_SIZE); i++)
|
||||
{
|
||||
device_name[i] = (char)_vendor[i];
|
||||
}
|
||||
|
||||
for(int j=0; (j < wcslen(_vendor)) && ((tmp_size + j) < EK_DEVICE_NAME_SIZE); j++)
|
||||
{
|
||||
device_name[tmp_size+j] = (char)_device_name[j];
|
||||
}
|
||||
|
||||
location = _path;
|
||||
|
||||
current_mode = EK_MODE_STATIC;
|
||||
current_speed = EK_SPEED_NORMAL;
|
||||
}
|
||||
|
||||
EKController::~EKController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
char* EKController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
char* EKController::GetSerial()
|
||||
{
|
||||
return serial;
|
||||
}
|
||||
|
||||
std::string EKController::GetLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
void EKController::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EKController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EKController::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[EK_PACKET_LENGTH] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
for(int i = 0; i < EK_COLOUR_MODE_DATA_SIZE; i++)
|
||||
{
|
||||
buffer[i] = colour_mode_data[current_mode][i];
|
||||
}
|
||||
|
||||
//Set the relevant colour info
|
||||
buffer[EK_RED_BYTE] = current_red;
|
||||
buffer[EK_GREEN_BYTE] = current_green;
|
||||
buffer[EK_BLUE_BYTE] = current_blue;
|
||||
buffer[EK_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
|
||||
|
||||
buffer[10] = 0x10;
|
||||
buffer[47] = 0xFF;
|
||||
buffer[48] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| EKController.h |
|
||||
| |
|
||||
| Driver for EK Loop Connect |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Jul 2020 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#ifndef EKCONTROLLER_H
|
||||
#define EKCONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define EK_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define EK_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define EK_PACKET_LENGTH 0x3F
|
||||
|
||||
enum
|
||||
{
|
||||
EK_MODE_BYTE = 12,
|
||||
EK_SPEED_BYTE = 14,
|
||||
EK_RED_BYTE = 16,
|
||||
EK_GREEN_BYTE = 17,
|
||||
EK_BLUE_BYTE = 18
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EK_MODE_STATIC = 0x00, //Static Mode
|
||||
EK_MODE_BREATHING = 0x01, //Breathing Mode
|
||||
EK_MODE_FADING = 0x02, //Fading Mode
|
||||
EK_MODE_MARQUEE = 0x03, //Marquee Mode
|
||||
EK_MODE_COVERING_MARQUEE = 0x04, //Covering Marquee Mode
|
||||
EK_MODE_PULSE = 0x05, //Pulse Mode
|
||||
EK_MODE_SPECTRUM_WAVE = 0x06, //Spectrum Wave Mode
|
||||
EK_MODE_ALTERNATING = 0x07, //Alternating Mode
|
||||
EK_MODE_CANDLE = 0x08 //Candle Mode
|
||||
};
|
||||
|
||||
static unsigned char colour_mode_data[][16] =
|
||||
{
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x01, 0x00, 0xFF, 0x64}, // Static
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x02, 0x00, 0xFF, 0x64}, // Breathing
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x03, 0xFF, 0xFF, 0x64}, // Fading
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x04, 0x00, 0xFF, 0x64}, // Marquee
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x05, 0x00, 0xFF, 0x64}, // Covering Marquee
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x06, 0x00, 0xFF, 0x64}, // Pulse
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x07, 0x00, 0xFF, 0x64}, // Wave
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x08, 0x00, 0xFF, 0x64}, // Alternating
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x09, 0x00, 0xFF, 0x64}, // Candle
|
||||
};
|
||||
|
||||
static unsigned char speed_mode_data[][9] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Static
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Breathing
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Fading
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Marquee
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Covering Marquee
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Pulse
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Wave
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Alternating
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 } // Candle
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EK_SPEED_SLOWEST = 0x00, // Slowest speed
|
||||
EK_SPEED_SLOWER = 0x01, // Slower speed
|
||||
EK_SPEED_SLOW = 0x02, // Slow speed
|
||||
EK_SPEED_SLOWISH = 0x03, // Slowish speed
|
||||
EK_SPEED_NORMAL = 0x04, // Normal speed
|
||||
EK_SPEED_FASTISH = 0x05, // Fastish speed
|
||||
EK_SPEED_FAST = 0x06, // Fast speed
|
||||
EK_SPEED_FASTER = 0x07, // Faster speed
|
||||
EK_SPEED_FASTEST = 0x08, // Fastest speed
|
||||
};
|
||||
|
||||
class EKController
|
||||
{
|
||||
public:
|
||||
EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
|
||||
~EKController();
|
||||
|
||||
char* GetDeviceName();
|
||||
char* GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
char serial[32];
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
|
||||
void SendUpdate();
|
||||
};
|
||||
|
||||
#endif // EKCONTROLLER_H
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "EKController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_EKController.h"
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define EK_VID 0x0483
|
||||
|
||||
#define EK_LOOP_CONNECT 0x5750
|
||||
|
||||
#define EK_NUM_DEVICES (sizeof(ek_pids) / sizeof(ek_pids[ 0 ]))
|
||||
|
||||
enum
|
||||
{
|
||||
EK_PID = 0,
|
||||
EK_INTERFACE = 1
|
||||
};
|
||||
|
||||
static const unsigned int ek_pids[][2] =
|
||||
{ // PID, Interface
|
||||
{ EK_LOOP_CONNECT, 0x00 } //EK Loop Connect
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectEKControllers *
|
||||
* *
|
||||
* Tests the USB address to see if any EK Controllers exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectEKControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
|
||||
//Look for the passed in cm_pids
|
||||
hid_init();
|
||||
info = hid_enumerate(0x0, 0x0);
|
||||
|
||||
while(info)
|
||||
{
|
||||
hid_device* dev = NULL;
|
||||
if(info->vendor_id == EK_VID)
|
||||
{
|
||||
for(int ek_pid_idx = 0; ek_pid_idx < EK_NUM_DEVICES; ek_pid_idx++)
|
||||
{
|
||||
if((info->product_id == ek_pids[ek_pid_idx][EK_PID])
|
||||
&&(info->interface_number == ek_pids[ek_pid_idx][EK_INTERFACE]))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EKController* controller = new EKController(dev, info->manufacturer_string, info->product_string, info->path);
|
||||
RGBController_EKController* rgb_controller = new RGBController_EKController(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUController.cpp |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GalaxGPUController.h"
|
||||
#include <cstring>
|
||||
|
||||
GalaxGPUController::GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
strcpy(device_name, "Galax RTX GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
|
||||
}
|
||||
|
||||
GalaxGPUController::~GalaxGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string GalaxGPUController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string GalaxGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDRed()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_RED_REGISTER));
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDGreen()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_GREEN_REGISTER));
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDBlue()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_BLUE_REGISTER));
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
|
||||
{
|
||||
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
|
||||
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
|
||||
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
|
||||
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
|
||||
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetMode(unsigned char mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case 1:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_STATIC_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_STATIC_VALUE_2);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_BREATHING_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_BREATHING_VALUE_2);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_RAINBOW_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_RAINBOW_VALUE_2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_CYCLE_BREATHING_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_CYCLE_BREATHING_VALUE_2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GalaxGPURegisterRead(unsigned char reg)
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, reg));
|
||||
}
|
||||
|
||||
void GalaxGPUController::GalaxGPURegisterWrite(unsigned char reg, unsigned char val)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUController.h |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char galax_gpu_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
/* RGB Registers */
|
||||
GALAX_RED_REGISTER = 0x02, /* Red Register */
|
||||
GALAX_GREEN_REGISTER = 0x03, /* Green Register */
|
||||
GALAX_BLUE_REGISTER = 0x04, /* Blue Register */
|
||||
/* MODE Registers */
|
||||
GALAX_MODE_REGISTER_1 = 0x05, /* Mode Register 1 */
|
||||
GALAX_MODE_REGISTER_2 = 0x06, /* Mode Register 2 */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* Static Mode Values */
|
||||
GALAX_MODE_STATIC_VALUE_1 = 0x00,
|
||||
GALAX_MODE_STATIC_VALUE_2 = 0x01,
|
||||
/* Breathing Mode Values */
|
||||
GALAX_MODE_BREATHING_VALUE_1 = 0x04,
|
||||
GALAX_MODE_BREATHING_VALUE_2 = 0x00,
|
||||
/* Rainbow Mode Values */
|
||||
GALAX_MODE_RAINBOW_VALUE_1 = 0x84,
|
||||
GALAX_MODE_RAINBOW_VALUE_2 = 0x02,
|
||||
/* Cycle Breathing Mode Values */
|
||||
GALAX_MODE_CYCLE_BREATHING_VALUE_1 = 0x84,
|
||||
GALAX_MODE_CYCLE_BREATHING_VALUE_2 = 0x40,
|
||||
};
|
||||
|
||||
class GalaxGPUController
|
||||
{
|
||||
public:
|
||||
GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id);
|
||||
~GalaxGPUController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned char GetLEDRed();
|
||||
unsigned char GetLEDGreen();
|
||||
unsigned char GetLEDBlue();
|
||||
void SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char GalaxGPURegisterRead(unsigned char reg);
|
||||
void GalaxGPURegisterWrite(unsigned char reg, unsigned char val);
|
||||
|
||||
bool direct = false; // Temporary solution to check if we are in "Direct" mode
|
||||
|
||||
private:
|
||||
char device_name[16];
|
||||
i2c_smbus_interface * bus;
|
||||
galax_gpu_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GalaxGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_GalaxGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForGalaxGPUController *
|
||||
* *
|
||||
* Tests the given address to see if a Galax GPU controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForGalaxGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
unsigned char res = bus->i2c_smbus_read_byte_data(address, 0x00);
|
||||
unsigned char res2 = bus->i2c_smbus_read_byte_data(address, 0x01);
|
||||
if(res == 0x27 && res2 == 0x10)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForGalaxGPUController() */
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectGalaxGPUControllers *
|
||||
* *
|
||||
* Detect Galax GPU controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectGalaxGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
GalaxGPUController* new_GalaxGPU;
|
||||
RGBController_GalaxGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for GALAX controller at 0x23
|
||||
if (TestForGalaxGPUController(busses[bus], 0x23))
|
||||
{
|
||||
new_GalaxGPU = new GalaxGPUController(busses[bus], 0x23);
|
||||
new_controller = new RGBController_GalaxGPU(new_GalaxGPU);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectGalaxGPUControllers() */
|
||||
@@ -0,0 +1,278 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_GloriousModelO.cpp |
|
||||
| |
|
||||
| Definitions and types for Glorious |
|
||||
| and other Mice |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GloriousModelOController.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
GloriousModelOController::GloriousModelOController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
strcpy(device_name, "Glorious Mouse");
|
||||
led_count = 1;
|
||||
|
||||
current_mode = GLORIOUS_MODE_STATIC;
|
||||
current_speed = GLORIOUS_SPEED_NORMAL;
|
||||
current_direction = GLORIOUS_DIRECTION_UP;
|
||||
|
||||
}
|
||||
|
||||
GloriousModelOController::~GloriousModelOController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string GloriousModelOController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int GloriousModelOController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void GloriousModelOController::SetLEDColor(RGBColor* color_buf)
|
||||
{
|
||||
unsigned char usb_buf[520] =
|
||||
{
|
||||
0x04, 0x11, 0x00, 0x7b,
|
||||
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
|
||||
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
|
||||
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
usb_buf[0x0B] = 0x24;
|
||||
usb_buf[0x35] = GLORIOUS_MODE_STATIC;
|
||||
usb_buf[0x38] = 0x40; //max brightness
|
||||
usb_buf[0x39] = RGBGetRValue(color_buf[0]);
|
||||
usb_buf[0x3A] = RGBGetBValue(color_buf[0]);
|
||||
usb_buf[0x3B] = RGBGetGValue(color_buf[0]);
|
||||
|
||||
//DPI Button
|
||||
/*
|
||||
usb_buf[0x0B] = 0x44; //third DPI
|
||||
usb_buf[0x26] = red;
|
||||
usb_buf[0x27] = blue;
|
||||
usb_buf[0x28] = green;
|
||||
*/
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
void GloriousModelOController::SetMode(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
RGBColor* color_buf)
|
||||
{
|
||||
unsigned char usb_buf[520] =
|
||||
{
|
||||
0x04, 0x11, 0x00, 0x7b,
|
||||
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
|
||||
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
|
||||
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
usb_buf[0x35] = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GLORIOUS_MODE_OFF:
|
||||
usb_buf[0x81] = 0x00; //mode 0 either 0x00 or 0x03
|
||||
break;
|
||||
case GLORIOUS_MODE_RAINBOW:
|
||||
usb_buf[0x36] = speed;
|
||||
usb_buf[0x37] = direction;
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_BREATING:
|
||||
//colours not yet researched
|
||||
usb_buf[0x3C] = speed; //speed for mode 3
|
||||
usb_buf[0x3D] = 0x07; //maybe some kind of bank change?+
|
||||
//usb_buf[0x3D] = 0x06;
|
||||
usb_buf[0x3E] = RGBGetRValue(color_buf[0]); //mode 3 red 1
|
||||
usb_buf[0x3F] = RGBGetBValue(color_buf[0]); //mode 3 blue 1
|
||||
usb_buf[0x40] = RGBGetGValue(color_buf[0]); //mode 3 green 1
|
||||
usb_buf[0x41] = RGBGetRValue(color_buf[1]); //mode 3 red 2
|
||||
usb_buf[0x42] = RGBGetBValue(color_buf[1]); //mode 3 blue 2
|
||||
usb_buf[0x43] = RGBGetGValue(color_buf[1]); //mode 3 green 2
|
||||
usb_buf[0x44] = RGBGetRValue(color_buf[2]); //mode 3 red 3
|
||||
usb_buf[0x45] = RGBGetBValue(color_buf[2]); //mode 3 blue 3
|
||||
usb_buf[0x46] = RGBGetGValue(color_buf[2]); //mode 3 green 3
|
||||
usb_buf[0x47] = RGBGetRValue(color_buf[3]); //mode 3 red 4
|
||||
usb_buf[0x48] = RGBGetBValue(color_buf[3]); //mode 3 blue 4
|
||||
usb_buf[0x49] = RGBGetGValue(color_buf[3]); //mode 3 green 4
|
||||
usb_buf[0x4A] = RGBGetRValue(color_buf[4]); //mode 3 red 5
|
||||
usb_buf[0x4B] = RGBGetBValue(color_buf[4]); //mode 3 blue 5
|
||||
usb_buf[0x4C] = RGBGetGValue(color_buf[4]); //mode 3 green 5
|
||||
usb_buf[0x4D] = RGBGetRValue(color_buf[5]); //mode 3 red 6
|
||||
usb_buf[0x4E] = RGBGetBValue(color_buf[5]); //mode 3 blue 6
|
||||
usb_buf[0x4F] = RGBGetGValue(color_buf[5]); //mode 3 green 6
|
||||
usb_buf[0x50] = RGBGetRValue(color_buf[6]); //mode 3 red 7
|
||||
usb_buf[0x51] = RGBGetBValue(color_buf[6]); //mode 3 blue 7
|
||||
usb_buf[0x52] = RGBGetGValue(color_buf[6]); //mode 3 green 7
|
||||
break;
|
||||
case GLORIOUS_MODE_TAIL:
|
||||
usb_buf[0x53] = speed; //Speed for mode 4
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_CYCLE:
|
||||
usb_buf[0x54] = speed; //Speed for mode 1,2,5
|
||||
break;
|
||||
case GLORIOUS_MODE_RAVE:
|
||||
usb_buf[0x74] = speed; //Speed for mode 7
|
||||
usb_buf[0x75] = RGBGetRValue(color_buf[0]); //mode 7 red 1
|
||||
usb_buf[0x76] = RGBGetBValue(color_buf[0]); //mode 7 blue 1
|
||||
usb_buf[0x77] = RGBGetGValue(color_buf[0]); //mode 7 green 1
|
||||
usb_buf[0x78] = RGBGetRValue(color_buf[1]); //mode 7 red 2
|
||||
usb_buf[0x79] = RGBGetBValue(color_buf[1]); //mode 7 blue 2
|
||||
usb_buf[0x7A] = RGBGetGValue(color_buf[1]); //mode 7 green 2
|
||||
break;
|
||||
case GLORIOUS_MODE_WAVE:
|
||||
usb_buf[0x7C] = speed; //Speed for mode 9
|
||||
break;
|
||||
case GLORIOUS_MODE_BREATHING:
|
||||
usb_buf[0x7D] = speed;
|
||||
usb_buf[0x7E] = RGBGetRValue(color_buf[0]); //mode 0a red
|
||||
usb_buf[0x7F] = RGBGetBValue(color_buf[0]); //mode 0a blue
|
||||
usb_buf[0x80] = RGBGetGValue(color_buf[0]); //mode 0a green
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*-----------------------------------------*\
|
||||
| GloriousModelOController.h |
|
||||
| |
|
||||
| Definitions and types for Glorious |
|
||||
| and other Mice |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_MODE_OFF = 0x00, //does nothing
|
||||
GLORIOUS_MODE_RAINBOW = 0x01,
|
||||
GLORIOUS_MODE_STATIC = 0x02,
|
||||
GLORIOUS_MODE_SPECTRUM_BREATING = 0x03,
|
||||
GLORIOUS_MODE_TAIL = 0x04,
|
||||
GLORIOUS_MODE_SPECTRUM_CYCLE = 0x05,
|
||||
GLORIOUS_MODE_RAVE = 0x07,
|
||||
GLORIOUS_MODE_EPILEPSY = 0x08, //not in the official software
|
||||
GLORIOUS_MODE_WAVE = 0x09,
|
||||
GLORIOUS_MODE_BREATHING = 0x0a,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_SPEED_SLOW = 0x41,
|
||||
GLORIOUS_SPEED_NORMAL = 0x42,
|
||||
GLORIOUS_SPEED_FAST = 0x43,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_DIRECTION_UP = 0x00,
|
||||
GLORIOUS_DIRECTION_DOWN = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_MODE_BREATING_SLOW = 0x01,
|
||||
GLORIOUS_MODE_BREATING_NORMAL = 0x02,
|
||||
GLORIOUS_MODE_BREATING_FAST = 0x03,
|
||||
};
|
||||
|
||||
class GloriousModelOController
|
||||
{
|
||||
public:
|
||||
GloriousModelOController(hid_device* dev_handle);
|
||||
~GloriousModelOController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
unsigned int GetLEDCount();
|
||||
|
||||
void SetLEDColor(RGBColor* color_buf);
|
||||
void SetMode(unsigned char mode, unsigned char speed, unsigned char direction, RGBColor* color_buf);
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
unsigned char current_direction;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "GloriousModelOController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_GloriousModelO.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define Glorious_Model_O_VID 0x258A
|
||||
#define Glorious_Model_O_PID 0x0036
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectGloriousModelController *
|
||||
* *
|
||||
* Tests the USB address to see if a Glorious Model O controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectGloriousModelOControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(Glorious_Model_O_VID, Glorious_Model_O_PID);
|
||||
|
||||
//Look for Glorious Model O
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == Glorious_Model_O_VID)
|
||||
&&(info->product_id == Glorious_Model_O_PID)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == 1)
|
||||
&&(info->usage_page == 0xFF00))
|
||||
#else
|
||||
&&(info->interface_number == 1))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
GloriousModelOController* controller = new GloriousModelOController(dev);
|
||||
|
||||
RGBController_GloriousModelO* rgb_controller = new RGBController_GloriousModelO(controller);
|
||||
|
||||
rgb_controller->name = "Glorious Mouse";
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
@@ -9,128 +9,231 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
HuePlusController::HuePlusController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
HuePlusController::~HuePlusController()
|
||||
{
|
||||
}
|
||||
|
||||
void HuePlusController::Initialize(char* ledstring)
|
||||
void HuePlusController::Initialize(char* port)
|
||||
{
|
||||
strcpy(led_string, ledstring);
|
||||
strcpy(port_name, port);
|
||||
|
||||
serialport = new serial_port(port_name, HUE_PLUS_BAUD);
|
||||
|
||||
LPSTR source = NULL;
|
||||
LPSTR channels = NULL;
|
||||
LPSTR numleds = NULL;
|
||||
LPSTR next = NULL;
|
||||
channel_leds[HUE_PLUS_CHANNEL_1_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_1);
|
||||
channel_leds[HUE_PLUS_CHANNEL_2_IDX] = GetLEDsOnChannel(HUE_PLUS_CHANNEL_2);
|
||||
}
|
||||
|
||||
source = strtok_s(ledstring, ",", &next);
|
||||
char* HuePlusController::GetLocation()
|
||||
{
|
||||
return(port_name);
|
||||
}
|
||||
|
||||
//Check for selected channel 0=both, 1= Ch.1, 2= Ch.2
|
||||
if (strlen(next))
|
||||
unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
|
||||
{
|
||||
unsigned char serial_buf[] =
|
||||
{
|
||||
channels = strtok_s(next, ",", &next);
|
||||
0x8D, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set channel in serial packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x01] = channel;
|
||||
|
||||
serialport->serial_flush_rx();
|
||||
serialport->serial_write((char *)serial_buf, 2);
|
||||
serialport->serial_flush_tx();
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
|
||||
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
|
||||
|
||||
if(bytes_read == 5)
|
||||
{
|
||||
if(serial_buf[3] == 0x01)
|
||||
{
|
||||
ret_val = serial_buf[4] * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_val += serial_buf[4] * 10;
|
||||
}
|
||||
}
|
||||
|
||||
switch (atoi(channels))
|
||||
return(ret_val);
|
||||
}
|
||||
|
||||
void HuePlusController::SetChannelEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
)
|
||||
{
|
||||
unsigned char color_data[120];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If mode requires no colors, send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
if(num_colors == 0)
|
||||
{
|
||||
case 0:
|
||||
channel = 0x00;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
channel = 0x01;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
channel = 0x02;
|
||||
break;
|
||||
/*-----------------------------------------------------*\
|
||||
| Send mode without color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPacket(channel, mode, direction, 0, speed, 0, NULL);
|
||||
}
|
||||
|
||||
//Check for the number of LEDs, sets the corresponding variable with the counter for the fans
|
||||
if (strlen(next))
|
||||
/*-----------------------------------------------------*\
|
||||
| If mode requires indexed colors, send color index |
|
||||
| packets for each mode color |
|
||||
\*-----------------------------------------------------*/
|
||||
else if(num_colors <= 8)
|
||||
{
|
||||
numleds = strtok_s(next, ",", &next);
|
||||
for(std::size_t color_idx = 0; color_idx < num_colors; color_idx++)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data (40 entries per color) |
|
||||
\*-----------------------------------------------------*/
|
||||
for (std::size_t idx = 0; idx < 40; idx++)
|
||||
{
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[color_idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send mode and color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPacket(channel, mode, direction, color_idx, speed, 40, &color_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
switch (atoi(numleds) / 8)
|
||||
/*-----------------------------------------------------*\
|
||||
| If mode requires per-LED colors, fill colors array |
|
||||
\*-----------------------------------------------------*/
|
||||
else
|
||||
{
|
||||
case 1:
|
||||
fans = 0x00;
|
||||
break;
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data (up to 40 colors) |
|
||||
\*-----------------------------------------------------*/
|
||||
for (std::size_t idx = 0; idx < num_colors; idx++)
|
||||
{
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
case 2:
|
||||
fans = 0x01;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fans = 0x02;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fans = 0x03;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
fans = 0x04;
|
||||
break;
|
||||
}
|
||||
|
||||
//Initialize with default baud rate
|
||||
source = strtok(source, "\r");
|
||||
strcpy(port_name, source);
|
||||
baud_rate = 256000;
|
||||
serialport = new serial_port(port_name, baud_rate);
|
||||
|
||||
if (numleds != NULL && strlen(numleds))
|
||||
{
|
||||
num_leds = atoi(numleds);
|
||||
/*-----------------------------------------------------*\
|
||||
| Send mode and color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPacket(channel, mode, direction, 0, speed, num_colors, &color_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
char* HuePlusController::GetLEDString()
|
||||
void HuePlusController::SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
)
|
||||
{
|
||||
return(led_string);
|
||||
}
|
||||
unsigned char color_data[120];
|
||||
|
||||
void HuePlusController::SetLEDs(std::vector<RGBColor> colors)
|
||||
{
|
||||
if (serialport != NULL)
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data (up to 40 colors) |
|
||||
\*-----------------------------------------------------*/
|
||||
for (std::size_t idx = 0; idx < num_colors; idx++)
|
||||
{
|
||||
unsigned char *serial_buf;
|
||||
|
||||
serial_buf = new unsigned char[hueSize]; //Size of Message always 5 XX Blocks (Mode Selection) + 3 XX for each LED (1 color)
|
||||
//-> max of 40 LEDs per Channel (or 5 Fans a 8 LEDs) -> 125 Blocks (empty LEDs are written, too
|
||||
serial_buf[0] = 0x4b;
|
||||
serial_buf[1] = channel;
|
||||
serial_buf[2] = 0x0e;
|
||||
serial_buf[3] = fans;
|
||||
serial_buf[4] = 0x00;
|
||||
|
||||
for (int i = 5; i < hueSize; i++)
|
||||
{
|
||||
//clearing the buf otherwise sometimes strange things are written to the COM Port
|
||||
serial_buf[i] = 0x00;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < (num_leds * 3); idx += 3)
|
||||
{
|
||||
int pixel_idx = idx / 3;
|
||||
RGBColor color = colors[pixel_idx];
|
||||
serial_buf[idx + 5] = RGBGetGValue(color);
|
||||
serial_buf[idx + 6] = RGBGetRValue(color);
|
||||
serial_buf[idx + 7] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
serialport->serial_write((char *)serial_buf, hueSize);
|
||||
serialport->serial_flush_tx();
|
||||
|
||||
delete[] serial_buf;
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| Send color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SendPacket(channel, HUE_PLUS_MODE_FIXED, false, 0, 0, num_colors, &color_data[0]);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void HuePlusController::SendPacket
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char color_idx,
|
||||
unsigned char speed,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char serial_buf[125];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(serial_buf, 0x00, sizeof(serial_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x00] = 0x4B;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set channel in serial packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x01] = channel + 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set mode in serial packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x02] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set options bitfield in serial packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x03] = 0;
|
||||
serial_buf[0x03] |= direction ? ( 1 << 4 ) : 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set color index and speed in serial packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serial_buf[0x04] = ( color_idx << 5 ) | speed;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&serial_buf[0x05], color_data, color_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
serialport->serial_write((char *)serial_buf, HUE_PLUS_PACKET_SIZE);
|
||||
serialport->serial_flush_tx();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Delay to allow Hue+ device to ready for next packet |
|
||||
\*-----------------------------------------------------*/
|
||||
std::this_thread::sleep_for(20ms);
|
||||
}
|
||||
|
||||
@@ -22,27 +22,91 @@
|
||||
#define strtok_s strtok_r
|
||||
#endif
|
||||
|
||||
#define HUE_PLUS_BAUD 256000
|
||||
#define HUE_PLUS_PACKET_SIZE 125
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_PLUS_CHANNEL_BOTH = 0x00, /* Both channels */
|
||||
HUE_PLUS_CHANNEL_1 = 0x01, /* Channel 1 */
|
||||
HUE_PLUS_CHANNEL_2 = 0x02, /* Channel 2 */
|
||||
HUE_PLUS_NUM_CHANNELS = 0x02 /* Number of channels */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_PLUS_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
|
||||
HUE_PLUS_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_PLUS_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
HUE_PLUS_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
HUE_PLUS_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
HUE_PLUS_SPEED_FAST = 0x03, /* Fast speed */
|
||||
HUE_PLUS_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_PLUS_MODE_FIXED = 0x00, /* Fixed colors mode */
|
||||
HUE_PLUS_MODE_FADING = 0x01, /* Fading mode */
|
||||
HUE_PLUS_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
|
||||
HUE_PLUS_MODE_MARQUEE = 0x03, /* Marquee mode */
|
||||
HUE_PLUS_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
|
||||
HUE_PLUS_MODE_ALTERNATING = 0x05, /* Alternating mode */
|
||||
HUE_PLUS_MODE_PULSING = 0x06, /* Pulsing mode */
|
||||
HUE_PLUS_MODE_BREATHING = 0x07, /* Breathing mode */
|
||||
HUE_PLUS_MODE_ALERT = 0x08, /* Alert mode */
|
||||
HUE_PLUS_MODE_CANDLELIGHT = 0x09, /* Candlelight mode */
|
||||
HUE_PLUS_MODE_WINGS = 0x0C, /* Wings mode */
|
||||
HUE_PLUS_MODE_WAVE = 0x0D, /* Wave mode */
|
||||
};
|
||||
|
||||
class HuePlusController
|
||||
{
|
||||
public:
|
||||
HuePlusController();
|
||||
~HuePlusController();
|
||||
|
||||
void Initialize(char* ledstring);
|
||||
char* GetLEDString();
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
void Initialize(char* port);
|
||||
char* GetLocation();
|
||||
unsigned int GetLEDsOnChannel(unsigned int channel);
|
||||
|
||||
int num_leds;
|
||||
void SetChannelEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
unsigned int channel_leds[HUE_PLUS_NUM_CHANNELS];
|
||||
|
||||
private:
|
||||
int baud_rate;
|
||||
int fans;
|
||||
int channel;
|
||||
const int hueSize = 125;
|
||||
char port_name[128];
|
||||
serial_port *serialport;
|
||||
|
||||
char led_string[1024];
|
||||
char port_name[128];
|
||||
serial_port *serialport;
|
||||
void SendPacket
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char color_idx,
|
||||
unsigned char speed,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
#include "HuePlusController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HuePlus.h"
|
||||
#include "find_usb_serial_port.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#define NZXT_HUE_PLUS_VID 0x04D8
|
||||
#define NZXT_HUE_PLUS_PID 0x00DF
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHuePlusControllers *
|
||||
* *
|
||||
* Detect devices supported by the HuePlus driver *
|
||||
* * *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
@@ -29,61 +20,13 @@ void DetectHuePlusControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
HuePlusController* new_hueplus;
|
||||
RGBController_HuePlus* new_controller;
|
||||
|
||||
//Get file path in executable directory
|
||||
std::ifstream infile;
|
||||
char filename[2048];
|
||||
char arg1[64];
|
||||
|
||||
#ifdef WIN32
|
||||
GetModuleFileName(NULL, filename, 2048);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
strcat(filename, "\\settings.txt");
|
||||
#else
|
||||
snprintf(arg1, 64, "/proc/%d/exe", getpid());
|
||||
readlink(arg1, filename, 1024);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
#endif
|
||||
|
||||
strcat(filename, "/settings.txt");
|
||||
|
||||
//Open settings file
|
||||
infile.open(filename);
|
||||
|
||||
if (infile.good())
|
||||
std::string portname = find_usb_serial_port(NZXT_HUE_PLUS_VID, NZXT_HUE_PLUS_PID);
|
||||
if( portname != "" )
|
||||
{
|
||||
for (std::string line; std::getline(infile, line); )
|
||||
{
|
||||
if (line == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((line[0] != ';') && (line[0] != '#') && (line[0] != '/'))
|
||||
{
|
||||
char * argument;
|
||||
char * value;
|
||||
new_hueplus = new HuePlusController();
|
||||
new_hueplus->Initialize((char *)portname.c_str());
|
||||
|
||||
value = (char *)line.c_str();
|
||||
|
||||
argument = strtok_s(value, "=", &value);
|
||||
|
||||
//Strip off new line characters if present
|
||||
argument = strtok(argument, "\r\n");
|
||||
value = strtok(value, "\r\n");
|
||||
|
||||
if(argument)
|
||||
{
|
||||
if (strcmp(argument, "hueplus") == 0)
|
||||
{
|
||||
new_hueplus = new HuePlusController();
|
||||
new_hueplus->Initialize(value);
|
||||
|
||||
new_controller = new RGBController_HuePlus(new_hueplus);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
new_controller = new RGBController_HuePlus(new_hueplus);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
|
||||
} /* DetectHuePlusControllers() */
|
||||
} /* DetectHuePlusControllers() */
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXController.cpp |
|
||||
| |
|
||||
| Definitions and types for HyperX Predator|
|
||||
| RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/29/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXController.h"
|
||||
#include <cstring>
|
||||
|
||||
HyperXController::HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
strcpy(device_name, "HyperX Predator RGB");
|
||||
led_count = 1;
|
||||
}
|
||||
|
||||
HyperXController::~HyperXController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* HyperXController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
unsigned int HyperXController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void HyperXController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_RED, red);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_GREEN, green);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_BLUE, blue);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
void HyperXController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_RED, red);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_GREEN, green);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_BLUE, blue);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
void HyperXController::SetMode(unsigned char mode)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case HYPERX_MODE_STATIC:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_STATIC);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_RAINBOW:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_RAINBOW);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_COMET:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_COMET);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_HEARTBEAT:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_HEARTBEAT);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_CYCLE:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE1, HYPERX_MODE1_CYCLE);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BREATHING:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BREATHING);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BOUNCE:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BOUNCE);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BLINK:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE2, HYPERX_MODE2_BLINK);
|
||||
break;
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX Predator|
|
||||
| RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/29/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char hyperx_dev_id;
|
||||
typedef unsigned short hyperx_register;
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_REG_BRIGHTNESS = 0xDD, /* Brightness control register (0-100) */
|
||||
HYPERX_REG_APPLY = 0xE1, /* Apply changes register */
|
||||
HYPERX_REG_MODE1 = 0xE3, /* Mode control register 1 */
|
||||
HYPERX_REG_MODE2 = 0xE4, /* Mode control register 2 */
|
||||
HYPERX_REG_RED = 0xEC, /* Red color register */
|
||||
HYPERX_REG_GREEN = 0xED, /* Green color register */
|
||||
HYPERX_REG_BLUE = 0xEE, /* Blue color register */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE1_RAINBOW = 0x05, /* Mode 1 rainbow effect */
|
||||
HYPERX_MODE1_CYCLE = 0x04, /* Mode 1 cycle effect */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE2_BOUNCE = 0x02, /* Mode 2 bounce effect */
|
||||
HYPERX_MODE2_BREATHING = 0x03, /* Mode 2 breathing effect */
|
||||
HYPERX_MODE2_BLINK = 0x06, /* Mode 2 blink effect */
|
||||
HYPERX_MODE2_HEARTBEAT = 0x07, /* Mode 2 heartbeat effect */
|
||||
HYPERX_MODE2_COMET = 0x08, /* Mode 2 comet effect */
|
||||
HYPERX_MODE2_STATIC = 0x09, /* Mode 2 static effect */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE_STATIC = 0, /* Static color mode */
|
||||
HYPERX_MODE_RAINBOW = 1, /* Rainbow wave mode */
|
||||
HYPERX_MODE_COMET = 2, /* Comet (chase) mode */
|
||||
HYPERX_MODE_HEARTBEAT = 3, /* Heartbeat (pulsing) mode */
|
||||
HYPERX_MODE_CYCLE = 4, /* Spectrum cycle mode */
|
||||
HYPERX_MODE_BREATHING = 5, /* Breathing mode */
|
||||
HYPERX_MODE_BOUNCE = 6, /* Bounce mode */
|
||||
HYPERX_MODE_BLINK = 7, /* Blinking mode */
|
||||
HYPERX_NUMBER_MODES /* Number of HyperX modes */
|
||||
};
|
||||
|
||||
|
||||
class HyperXController
|
||||
{
|
||||
public:
|
||||
HyperXController(i2c_smbus_interface* bus, hyperx_dev_id dev);
|
||||
~HyperXController();
|
||||
|
||||
char* GetDeviceName();
|
||||
unsigned int GetLEDCount();
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
i2c_smbus_interface* bus;
|
||||
hyperx_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,287 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXDRAMController.cpp |
|
||||
| |
|
||||
| Definitions and types for HyperX Predator|
|
||||
| and Fury RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/29/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXDRAMController.h"
|
||||
#include <cstring>
|
||||
|
||||
HyperXDRAMController::HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
slots_valid = slots;
|
||||
|
||||
strcpy(device_name, "HyperX Predator RGB");
|
||||
|
||||
led_count = 0;
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
if((slots_valid & (1 << i)) != 0)
|
||||
{
|
||||
led_count += 5;
|
||||
}
|
||||
}
|
||||
|
||||
mode = HYPERX_MODE_DIRECT;
|
||||
}
|
||||
|
||||
HyperXDRAMController::~HyperXDRAMController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string HyperXDRAMController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string HyperXDRAMController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned int HyperXDRAMController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
unsigned int HyperXDRAMController::GetSlotCount()
|
||||
{
|
||||
unsigned int slot_count = 0;
|
||||
|
||||
for(int slot = 0; slot < 4; slot++)
|
||||
{
|
||||
if((slots_valid & (1 << slot)) != 0)
|
||||
{
|
||||
slot_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return(slot_count);
|
||||
}
|
||||
|
||||
unsigned int HyperXDRAMController::GetMode()
|
||||
{
|
||||
return(mode);
|
||||
}
|
||||
|
||||
void HyperXDRAMController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_RED, red );
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_GREEN, green);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_BLUE, blue );
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_EFFECT_BRIGHTNESS, 0x64 );
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
void HyperXDRAMController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Loop through all slots and only set those which are |
|
||||
| active. |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int slot = 0; slot < 4; slot++)
|
||||
{
|
||||
if((slots_valid & (1 << slot)) != 0)
|
||||
{
|
||||
unsigned char base = slot_base[slot];
|
||||
unsigned char red_base = base + 0x00;
|
||||
unsigned char green_base = base + 0x01;
|
||||
unsigned char blue_base = base + 0x02;
|
||||
unsigned char bright_base = base + 0x10;
|
||||
|
||||
if(mode == HYPERX_MODE_DIRECT)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
|
||||
}
|
||||
|
||||
for(int led = 0; led < 5; led++)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
|
||||
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
|
||||
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
|
||||
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
void HyperXDRAMController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| led_slot - the unmapped slot ID for the given LED |
|
||||
| led - the LED ID within that slot |
|
||||
| slot_id - counts enabled slots |
|
||||
| slot - the mapped slot ID for the given LED |
|
||||
\*-----------------------------------------------------*/
|
||||
int led_slot = led / 5;
|
||||
int slot_id = -1;
|
||||
int slot;
|
||||
|
||||
led -= (led_slot * 5);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Loop through all possible slots and only count those |
|
||||
| which are active. |
|
||||
\*-----------------------------------------------------*/
|
||||
for(slot = 0; slot < 4; slot++)
|
||||
{
|
||||
if((slots_valid & ( 1 << slot)) != 0)
|
||||
{
|
||||
slot_id++;
|
||||
}
|
||||
|
||||
if(slot_id == led_slot)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char base = slot_base[slot];
|
||||
unsigned char red_base = base + 0x00;
|
||||
unsigned char green_base = base + 0x01;
|
||||
unsigned char blue_base = base + 0x02;
|
||||
unsigned char bright_base = base + 0x10;
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
|
||||
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
|
||||
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
|
||||
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
|
||||
void HyperXDRAMController::SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char base = slot_base[slot];
|
||||
unsigned char red_base = base + 0x00;
|
||||
unsigned char green_base = base + 0x01;
|
||||
unsigned char blue_base = base + 0x02;
|
||||
unsigned char bright_base = base + 0x10;
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, red_base + (3 * led), red );
|
||||
bus->i2c_smbus_write_byte_data(dev, green_base + (3 * led), green);
|
||||
bus->i2c_smbus_write_byte_data(dev, blue_base + (3 * led), blue );
|
||||
bus->i2c_smbus_write_byte_data(dev, bright_base + (3 * led), 0x64 );
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
|
||||
void HyperXDRAMController::SetMode(unsigned char new_mode, bool random, unsigned short new_speed)
|
||||
{
|
||||
mode = new_mode;
|
||||
speed = new_speed;
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x01);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine which mode register to use. |
|
||||
| If set to random color mode, use Mode1. |
|
||||
| If set to fixed color mode, use Mode2. |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char mode_reg;
|
||||
|
||||
if(random)
|
||||
{
|
||||
mode_reg = HYPERX_REG_MODE_RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_reg = HYPERX_REG_MODE_CUSTOM;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case HYPERX_MODE_DIRECT:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_INDEPENDENT, HYPERX_MODE3_DIRECT);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_STATIC:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_CUSTOM, HYPERX_MODE2_STATIC);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_RAINBOW:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_RAINBOW);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_COMET:
|
||||
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_COMET);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_HEARTBEAT:
|
||||
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_HEARTBEAT);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_MSB, 0x03);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_DELAY_TIME_LSB, 0xE8);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_CYCLE:
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_MODE_RANDOM, HYPERX_MODE1_CYCLE);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_CHANGE_TIME_LSB, speed & 0xFF);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BREATHING:
|
||||
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BREATHING);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_IN_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_FADE_OUT_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, 0x00);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, 0x00);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BOUNCE:
|
||||
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BOUNCE);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_TIMER_LSB, speed & 0xFF);
|
||||
break;
|
||||
|
||||
case HYPERX_MODE_BLINK:
|
||||
bus->i2c_smbus_write_byte_data(dev, mode_reg, HYPERX_MODE2_BLINK);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_MSB, speed >> 8);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_OFF_TIME_LSB, speed & 0xFF);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_MSB, 0x07);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_ON_TIME_LSB, 0xD4);
|
||||
break;
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x02);
|
||||
bus->i2c_smbus_write_byte_data(dev, HYPERX_REG_APPLY, 0x03);
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXDRAMController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX Predator|
|
||||
| and Fury RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/29/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char hyperx_dev_id;
|
||||
typedef unsigned short hyperx_register;
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_REG_SLOT0_LED0_RED = 0x11, /* R color register for LED 0, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED0_GREEN = 0x12, /* G color register for LED 0, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED0_BLUE = 0x13, /* B color register for LED 0, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED1_RED = 0x14, /* R color register for LED 1, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED1_GREEN = 0x15, /* G color register for LED 1, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED1_BLUE = 0x16, /* B color register for LED 1, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED2_RED = 0x17, /* R color register for LED 2, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED2_GREEN = 0x18, /* G color register for LED 2, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED2_BLUE = 0x19, /* B color register for LED 2, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED3_RED = 0x1A, /* R color register for LED 3, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED3_GREEN = 0x1B, /* G color register for LED 3, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED3_BLUE = 0x1C, /* B color register for LED 3, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED4_RED = 0x1D, /* R color register for LED 4, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED4_GREEN = 0x1E, /* G color register for LED 4, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED4_BLUE = 0x1F, /* B color register for LED 4, Slot 0 */
|
||||
HYPERX_REG_SLOT0_LED0_BRIGHTNESS = 0x21, /* Brightness for LED 0, Slot 0 (0-100) */
|
||||
HYPERX_REG_SLOT0_LED1_BRIGHTNESS = 0x24, /* Brightness for LED 1, Slot 0 (0-100) */
|
||||
HYPERX_REG_SLOT0_LED2_BRIGHTNESS = 0x27, /* Brightness for LED 2, Slot 0 (0-100) */
|
||||
HYPERX_REG_SLOT0_LED3_BRIGHTNESS = 0x2A, /* Brightness for LED 3, Slot 0 (0-100) */
|
||||
HYPERX_REG_SLOT0_LED4_BRIGHTNESS = 0x2D, /* Brightness for LED 4, Slot 0 (0-100) */
|
||||
|
||||
HYPERX_REG_SLOT1_LED0_RED = 0x41, /* R color register for LED 0, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED0_GREEN = 0x42, /* G color register for LED 0, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED0_BLUE = 0x43, /* B color register for LED 0, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED1_RED = 0x44, /* R color register for LED 1, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED1_GREEN = 0x45, /* G color register for LED 1, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED1_BLUE = 0x46, /* B color register for LED 1, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED2_RED = 0x47, /* R color register for LED 2, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED2_GREEN = 0x48, /* G color register for LED 2, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED2_BLUE = 0x49, /* B color register for LED 2, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED3_RED = 0x4A, /* R color register for LED 3, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED3_GREEN = 0x4B, /* G color register for LED 3, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED3_BLUE = 0x4C, /* B color register for LED 3, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED4_RED = 0x4D, /* R color register for LED 4, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED4_GREEN = 0x4E, /* G color register for LED 4, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED4_BLUE = 0x4F, /* B color register for LED 4, Slot 1 */
|
||||
HYPERX_REG_SLOT1_LED0_BRIGHTNESS = 0x51, /* Brightness for LED 0, Slot 1 (0-100) */
|
||||
HYPERX_REG_SLOT1_LED1_BRIGHTNESS = 0x54, /* Brightness for LED 1, Slot 1 (0-100) */
|
||||
HYPERX_REG_SLOT1_LED2_BRIGHTNESS = 0x57, /* Brightness for LED 2, Slot 1 (0-100) */
|
||||
HYPERX_REG_SLOT1_LED3_BRIGHTNESS = 0x5A, /* Brightness for LED 3, Slot 1 (0-100) */
|
||||
HYPERX_REG_SLOT1_LED4_BRIGHTNESS = 0x5D, /* Brightness for LED 4, Slot 1 (0-100) */
|
||||
|
||||
HYPERX_REG_SLOT2_LED0_RED = 0x71, /* R color register for LED 0, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED0_GREEN = 0x72, /* G color register for LED 0, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED0_BLUE = 0x73, /* B color register for LED 0, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED1_RED = 0x74, /* R color register for LED 1, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED1_GREEN = 0x75, /* G color register for LED 1, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED1_BLUE = 0x76, /* B color register for LED 1, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED2_RED = 0x77, /* R color register for LED 2, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED2_GREEN = 0x78, /* G color register for LED 2, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED2_BLUE = 0x79, /* B color register for LED 2, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED3_RED = 0x7A, /* R color register for LED 3, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED3_GREEN = 0x7B, /* G color register for LED 3, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED3_BLUE = 0x7C, /* B color register for LED 3, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED4_RED = 0x7D, /* R color register for LED 4, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED4_GREEN = 0x7E, /* G color register for LED 4, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED4_BLUE = 0x7F, /* B color register for LED 4, Slot 2 */
|
||||
HYPERX_REG_SLOT2_LED0_BRIGHTNESS = 0x81, /* Brightness for LED 0, Slot 2 (0-100) */
|
||||
HYPERX_REG_SLOT2_LED1_BRIGHTNESS = 0x84, /* Brightness for LED 1, Slot 2 (0-100) */
|
||||
HYPERX_REG_SLOT2_LED2_BRIGHTNESS = 0x87, /* Brightness for LED 2, Slot 2 (0-100) */
|
||||
HYPERX_REG_SLOT2_LED3_BRIGHTNESS = 0x8A, /* Brightness for LED 3, Slot 2 (0-100) */
|
||||
HYPERX_REG_SLOT2_LED4_BRIGHTNESS = 0x8D, /* Brightness for LED 4, Slot 2 (0-100) */
|
||||
|
||||
HYPERX_REG_SLOT3_LED0_RED = 0xA1, /* R color register for LED 0, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED0_GREEN = 0xA2, /* G color register for LED 0, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED0_BLUE = 0xA3, /* B color register for LED 0, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED1_RED = 0xA4, /* R color register for LED 1, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED1_GREEN = 0xA5, /* G color register for LED 1, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED1_BLUE = 0xA6, /* B color register for LED 1, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED2_RED = 0xA7, /* R color register for LED 2, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED2_GREEN = 0xA8, /* G color register for LED 2, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED2_BLUE = 0xA9, /* B color register for LED 2, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED3_RED = 0xAA, /* R color register for LED 3, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED3_GREEN = 0xAB, /* G color register for LED 3, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED3_BLUE = 0xAC, /* B color register for LED 3, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED4_RED = 0xAD, /* R color register for LED 4, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED4_GREEN = 0xAE, /* G color register for LED 4, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED4_BLUE = 0xAF, /* B color register for LED 4, Slot 3 */
|
||||
HYPERX_REG_SLOT3_LED0_BRIGHTNESS = 0xB1, /* Brightness for LED 0, Slot 3 (0-100) */
|
||||
HYPERX_REG_SLOT3_LED1_BRIGHTNESS = 0xB4, /* Brightness for LED 1, Slot 3 (0-100) */
|
||||
HYPERX_REG_SLOT3_LED2_BRIGHTNESS = 0xB7, /* Brightness for LED 2, Slot 3 (0-100) */
|
||||
HYPERX_REG_SLOT3_LED3_BRIGHTNESS = 0xBA, /* Brightness for LED 3, Slot 3 (0-100) */
|
||||
HYPERX_REG_SLOT3_LED4_BRIGHTNESS = 0xBD, /* Brightness for LED 4, Slot 3 (0-100) */
|
||||
|
||||
HYPERX_REG_TIMER_MSB = 0xD1, /* Timer MSB */
|
||||
HYPERX_REG_TIMER_LSB = 0xD2, /* Timer LSB */
|
||||
HYPERX_REG_ON_TIME_MSB = 0xD3, /* Effect on time MSB */
|
||||
HYPERX_REG_ON_TIME_LSB = 0xD4, /* Effect on time LSB */
|
||||
HYPERX_REG_CHANGE_TIME_MSB = 0xD5, /* Change time MSB */
|
||||
HYPERX_REG_CHANGE_TIME_LSB = 0xD6, /* Change time LSB */
|
||||
HYPERX_REG_FADE_IN_TIME_MSB = 0xD7, /* Fade in time MSB */
|
||||
HYPERX_REG_FADE_IN_TIME_LSB = 0xD8, /* Fade in time LSB */
|
||||
HYPERX_REG_FADE_OUT_TIME_MSB = 0xD9, /* Fade out time MSB */
|
||||
HYPERX_REG_FADE_OUT_TIME_LSB = 0xDA, /* Fade out time LSB */
|
||||
HYPERX_REG_OFF_TIME_MSB = 0xDB, /* Effect off time MSB */
|
||||
HYPERX_REG_OFF_TIME_LSB = 0xDC, /* Effect off time LSB */
|
||||
HYPERX_REG_EFFECT_BRIGHTNESS = 0xDD, /* Brightness for effects (0-100) */
|
||||
HYPERX_REG_APPLY = 0xE1, /* Apply changes register */
|
||||
HYPERX_REG_MODE_RANDOM = 0xE3, /* Mode control register, random colors */
|
||||
HYPERX_REG_MODE_CUSTOM = 0xE4, /* Mode control register, custom colors */
|
||||
HYPERX_REG_MODE_INDEPENDENT = 0xE5, /* Mode control register, independent */
|
||||
HYPERX_REG_DELAY_TIME_MSB = 0xEA, /* Delay time MSB */
|
||||
HYPERX_REG_DELAY_TIME_LSB = 0xEB, /* Delay time LSB */
|
||||
HYPERX_REG_EFFECT_RED = 0xEC, /* Red color register for effects */
|
||||
HYPERX_REG_EFFECT_GREEN = 0xED, /* Green color register for effects */
|
||||
HYPERX_REG_EFFECT_BLUE = 0xEE, /* Blue color register for effects */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE1_RAINBOW = 0x05, /* Mode 1 rainbow effect */
|
||||
HYPERX_MODE1_CYCLE = 0x04, /* Mode 1 cycle effect */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE2_BOUNCE = 0x02, /* Mode 2 bounce effect */
|
||||
HYPERX_MODE2_BREATHING = 0x03, /* Mode 2 breathing effect */
|
||||
HYPERX_MODE2_BLINK = 0x06, /* Mode 2 blink effect */
|
||||
HYPERX_MODE2_HEARTBEAT = 0x07, /* Mode 2 heartbeat effect */
|
||||
HYPERX_MODE2_COMET = 0x08, /* Mode 2 comet effect */
|
||||
HYPERX_MODE2_STATIC = 0x09, /* Mode 2 static effect */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE3_DIRECT = 0x21, /* Mode 3 direct control */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE_DIRECT = 0, /* Direct control mode */
|
||||
HYPERX_MODE_STATIC = 1, /* Static color mode */
|
||||
HYPERX_MODE_RAINBOW = 2, /* Rainbow wave mode */
|
||||
HYPERX_MODE_COMET = 3, /* Comet (chase) mode */
|
||||
HYPERX_MODE_HEARTBEAT = 4, /* Heartbeat (pulsing) mode */
|
||||
HYPERX_MODE_CYCLE = 5, /* Spectrum cycle mode */
|
||||
HYPERX_MODE_BREATHING = 6, /* Breathing mode */
|
||||
HYPERX_MODE_BOUNCE = 7, /* Bounce mode */
|
||||
HYPERX_MODE_BLINK = 8, /* Blinking mode */
|
||||
HYPERX_NUMBER_MODES /* Number of HyperX modes */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_SPEED_BOUNCE_SLOW = 0x07D0, /* Slowest speed for bounce mode */
|
||||
HYPERX_SPEED_BOUNCE_NORMAL = 0x07D0, /* Normal speed for bounce mode */
|
||||
HYPERX_SPEED_BOUNCE_FAST = 0x0064, /* Fastest speed for bounce mode */
|
||||
HYPERX_SPEED_BREATHING_SLOW = 0x07D0, /* Slowest speed for breathing mode */
|
||||
HYPERX_SPEED_BREATHING_NORMAL = 0x07D0, /* Normal speed for breathing mode */
|
||||
HYPERX_SPEED_BREATHING_FAST = 0x0064, /* Fastest speed for breathing mode */
|
||||
HYPERX_SPEED_CYCLE_SLOW = 0x05DC, /* Slowest speed for cycle mode */
|
||||
HYPERX_SPEED_CYCLE_NORMAL = 0x05DC, /* Normal speed for cycle mode */
|
||||
HYPERX_SPEED_CYCLE_FAST = 0x00FA, /* Fastest speed for cycle mode */
|
||||
HYPERX_SPEED_RAINBOW_SLOW = 0x07D0, /* Slowest speed for rainbow mode */
|
||||
HYPERX_SPEED_RAINBOW_NORMAL = 0x07D0, /* Normal speed for rainbow mode */
|
||||
HYPERX_SPEED_RAINBOW_FAST = 0x0064, /* Fastest speed for rainbow mode */
|
||||
HYPERX_SPEED_BLINK_SLOW = 0x07D0, /* Slowest speed for blink mode */
|
||||
HYPERX_SPEED_BLINK_NORMAL = 0x07D0, /* Normal speed for blink mode */
|
||||
HYPERX_SPEED_BLINK_FAST = 0x01F4, /* Fastest speed for blink mode */
|
||||
HYPERX_SPEED_HEARTBEAT_SLOW = 0x07D0, /* Slowest speed for heartbeat mode */
|
||||
HYPERX_SPEED_HEARTBEAT_NORMAL = 0x07D0, /* Normal speed for heartbeat mode */
|
||||
HYPERX_SPEED_HEARTBEAT_FAST = 0x01F4, /* Fastest speed for heartbeat mode */
|
||||
HYPERX_SPEED_COMET_SLOW = 0x07D0, /* Slowest speed for comet mode */
|
||||
HYPERX_SPEED_COMET_NORMAL = 0x07D0, /* Normal speed for comet mode */
|
||||
HYPERX_SPEED_COMET_FAST = 0x0064, /* Fastest speed for comet mode */
|
||||
};
|
||||
|
||||
static const unsigned char slot_base[4] =
|
||||
{
|
||||
HYPERX_REG_SLOT0_LED0_RED, /* SPD 0x50 maps to slot 0 */
|
||||
HYPERX_REG_SLOT1_LED0_RED, /* SPD 0x51 maps to slot 1 */
|
||||
HYPERX_REG_SLOT2_LED0_RED, /* SPD 0x52 maps to slot 2 */
|
||||
HYPERX_REG_SLOT3_LED0_RED /* SPD 0x53 maps to slot 3 */
|
||||
};
|
||||
|
||||
class HyperXDRAMController
|
||||
{
|
||||
public:
|
||||
HyperXDRAMController(i2c_smbus_interface* bus, hyperx_dev_id dev, unsigned char slots);
|
||||
~HyperXDRAMController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
unsigned int GetSlotCount();
|
||||
unsigned int GetMode();
|
||||
void SetMode(unsigned char new_mode, bool random, unsigned short new_speed);
|
||||
|
||||
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetEffectColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
unsigned char slots_valid;
|
||||
i2c_smbus_interface* bus;
|
||||
hyperx_dev_id dev;
|
||||
unsigned int mode;
|
||||
unsigned short speed;
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "HyperXDRAMController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HyperXDRAM.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForHyperXDRAMController *
|
||||
* *
|
||||
* Tests the given address to see if a HyperX controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForHyperXDRAMController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
for (int i = 0xA0; i < 0xB0; i++)
|
||||
{
|
||||
res = bus->i2c_smbus_read_byte_data(address, i);
|
||||
|
||||
if (res != i)
|
||||
{
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForHyperXDRAMController() */
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHyperXDRAMControllers *
|
||||
* *
|
||||
* Detect HyperX DRAM controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
HyperXDRAMController* new_hyperx;
|
||||
RGBController_HyperXDRAM* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
unsigned char slots_valid = 0x00;
|
||||
|
||||
// Check for HyperX controller at 0x27
|
||||
if (TestForHyperXDRAMController(busses[bus], 0x27))
|
||||
{
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
|
||||
{
|
||||
// Test for HyperX SPD at slot_addr
|
||||
// This test was copied from NGENUITY software
|
||||
// Tests SPD addresses in order: 0x40, 0x41
|
||||
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x01)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x98))
|
||||
{
|
||||
slots_valid |= (1 << (slot_addr - 0x50));
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
if(slots_valid != 0)
|
||||
{
|
||||
new_hyperx = new HyperXDRAMController(busses[bus], 0x27, slots_valid);
|
||||
new_controller = new RGBController_HyperXDRAM(new_hyperx);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectHyperXDRAMControllers() */
|
||||
@@ -0,0 +1,131 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXAlloyOriginsController.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Origins RGB |
|
||||
| Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// Skip these indices in the color output
|
||||
static unsigned int skip_idx[] = { 6, 23, 29, 41, 47, 59, 70, 71, 75, 76, 87, 88, 93, 99, 100, 102, 108, 113, 114, 120, 123, 124 };
|
||||
|
||||
HyperXAlloyOriginsController::HyperXAlloyOriginsController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
HyperXAlloyOriginsController::~HyperXAlloyOriginsController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Insert color data for unused positions |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int skip_cnt = 0; skip_cnt < (sizeof(skip_idx) / sizeof(skip_idx[0])); skip_cnt++)
|
||||
{
|
||||
colors.insert(colors.begin() + skip_idx[skip_cnt], 0x00000000);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up variables to track progress of color transmit |
|
||||
| Do this after inserting blanks |
|
||||
\*-----------------------------------------------------*/
|
||||
int colors_to_send = colors.size();
|
||||
int colors_sent = 0;
|
||||
|
||||
SendDirectInitialization();
|
||||
|
||||
for(int pkt_idx = 0; pkt_idx < 9; pkt_idx++)
|
||||
{
|
||||
if(colors_to_send > 16)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], 16);
|
||||
colors_sent += 16;
|
||||
colors_to_send -= 16;
|
||||
}
|
||||
else if(colors_to_send > 0)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], colors_to_send);
|
||||
colors_sent += colors_to_send;
|
||||
colors_to_send -= colors_to_send;
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor temp = 0x00000000;
|
||||
SendDirectColorPacket(&temp, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SendDirectInitialization()
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x00;
|
||||
buf[0x01] = 0x04;
|
||||
buf[0x02] = 0xF2;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 65);
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count
|
||||
)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The maximum number of colors per packet is 16 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(color_count > 16)
|
||||
{
|
||||
color_count = 16;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int color_idx = 0; color_idx < color_count; color_idx++)
|
||||
{
|
||||
buf[(color_idx * 4) + 1] = 0x81;
|
||||
buf[(color_idx * 4) + 2] = RGBGetRValue(color_data[color_idx]);
|
||||
buf[(color_idx * 4) + 3] = RGBGetGValue(color_data[color_idx]);
|
||||
buf[(color_idx * 4) + 4] = RGBGetBValue(color_data[color_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXAlloyOriginsController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX Alloy |
|
||||
| Origins RGB Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class HyperXAlloyOriginsController
|
||||
{
|
||||
public:
|
||||
HyperXAlloyOriginsController(hid_device* dev_handle);
|
||||
~HyperXAlloyOriginsController();
|
||||
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
void SendDirectInitialization();
|
||||
void SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,482 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for HyperX RGB Keyboard lighting |
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/30/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXKeyboardController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
|
||||
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22,
|
||||
0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||
0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41,
|
||||
0x44, 0x45, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55,
|
||||
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A,
|
||||
0x6B, 0x6C, 0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
|
||||
0x7F, 0x81, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91,
|
||||
0x94, 0x95 };
|
||||
|
||||
static unsigned int extended_red[] = {0x08, 0x48, 0x88, 0x09, 0x89, 0x0A, 0x8A, 0x0B, 0x8B, 0x0C, 0x8C, 0x0D, 0x8D, 0x0E, 0x8F, 0x8E, 0x0F, 0x4F, 0x92, 0x13, 0x93, 0x12 };
|
||||
static unsigned int extended_grn[] = {0x29, 0x28, 0x78, 0x19, 0x79, 0x1A, 0x7A, 0x1B, 0x7B, 0x1C, 0x7C, 0x1D, 0x7D, 0x1E, 0x6E, 0x7E, 0x1F, 0x6F, 0x82, 0x23, 0x83, 0x22 };
|
||||
static unsigned int extended_blu[] = {0x39, 0x38, 0x68, 0x3A, 0x69, 0x2A, 0x6A, 0x2B, 0x6B, 0x2C, 0x6C, 0x2D, 0x6D, 0x2E, 0x5E, 0x5D, 0x2F, 0x5F, 0x72, 0x33, 0x73, 0x32 };
|
||||
|
||||
HyperXKeyboardController::HyperXKeyboardController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
HyperXKeyboardController::~HyperXKeyboardController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char direction,
|
||||
unsigned char speed,
|
||||
std::vector<RGBColor> colors
|
||||
)
|
||||
{
|
||||
unsigned char color_mode;
|
||||
unsigned char mode_colors[9];
|
||||
|
||||
active_mode = mode;
|
||||
active_direction = direction;
|
||||
active_speed = speed;
|
||||
|
||||
memset(mode_colors, 0x00, sizeof(mode_colors));
|
||||
|
||||
switch(colors.size())
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
color_mode = HYPERX_COLOR_MODE_SPECTRUM;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
color_mode = HYPERX_COLOR_MODE_SINGLE;
|
||||
mode_colors[0] = RGBGetRValue(colors[0]);
|
||||
mode_colors[1] = RGBGetGValue(colors[0]);
|
||||
mode_colors[2] = RGBGetBValue(colors[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
color_mode = HYPERX_COLOR_MODE_DUAL;
|
||||
mode_colors[3] = RGBGetRValue(colors[0]);
|
||||
mode_colors[4] = RGBGetGValue(colors[0]);
|
||||
mode_colors[5] = RGBGetBValue(colors[0]);
|
||||
mode_colors[6] = RGBGetRValue(colors[1]);
|
||||
mode_colors[7] = RGBGetGValue(colors[1]);
|
||||
mode_colors[8] = RGBGetBValue(colors[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
SendEffect
|
||||
(
|
||||
0x01,
|
||||
active_mode,
|
||||
active_direction,
|
||||
HYPERX_REACTIVE_MODE_NONE,
|
||||
active_speed,
|
||||
color_mode,
|
||||
mode_colors[0],
|
||||
mode_colors[1],
|
||||
mode_colors[2],
|
||||
mode_colors[3],
|
||||
mode_colors[4],
|
||||
mode_colors[5],
|
||||
mode_colors[6],
|
||||
mode_colors[7],
|
||||
mode_colors[8]
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(100ms);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char red_color_data[106];
|
||||
unsigned char grn_color_data[106];
|
||||
unsigned char blu_color_data[106];
|
||||
unsigned char ext_color_data[150];
|
||||
|
||||
for(std::size_t i = 0; i < 106; i++)
|
||||
{
|
||||
red_color_data[i] = RGBGetRValue(colors[i]);
|
||||
grn_color_data[i] = RGBGetGValue(colors[i]);
|
||||
blu_color_data[i] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
for(std::size_t i = 0; i < 22; i++)
|
||||
{
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
|
||||
}
|
||||
|
||||
SendDirect
|
||||
(
|
||||
HYPERX_COLOR_CHANNEL_RED,
|
||||
red_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirect
|
||||
(
|
||||
HYPERX_COLOR_CHANNEL_GREEN,
|
||||
grn_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirect
|
||||
(
|
||||
HYPERX_COLOR_CHANNEL_BLUE,
|
||||
blu_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirectExtended
|
||||
(
|
||||
ext_color_data
|
||||
);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char red_color_data[106];
|
||||
unsigned char grn_color_data[106];
|
||||
unsigned char blu_color_data[106];
|
||||
unsigned char ext_color_data[150];
|
||||
|
||||
for(std::size_t i = 0; i < 106; i++)
|
||||
{
|
||||
red_color_data[i] = RGBGetRValue(colors[i]);
|
||||
grn_color_data[i] = RGBGetGValue(colors[i]);
|
||||
blu_color_data[i] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
for(std::size_t i = 0; i < 22; i++)
|
||||
{
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
|
||||
}
|
||||
|
||||
SendColor
|
||||
(
|
||||
0x01,
|
||||
HYPERX_COLOR_CHANNEL_RED,
|
||||
red_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
0x01,
|
||||
HYPERX_COLOR_CHANNEL_GREEN,
|
||||
grn_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
0x01,
|
||||
HYPERX_COLOR_CHANNEL_BLUE,
|
||||
blu_color_data
|
||||
);
|
||||
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendExtendedColor
|
||||
(
|
||||
0x01,
|
||||
ext_color_data
|
||||
);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void HyperXKeyboardController::SelectProfile
|
||||
(
|
||||
unsigned char profile
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Select Profile packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = 0x01;
|
||||
buf[0x02] = profile;
|
||||
|
||||
buf[0x06] = 0x03;
|
||||
buf[0x07] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SendEffect
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char mode,
|
||||
unsigned char direction,
|
||||
unsigned char reactive_mode,
|
||||
unsigned char speed,
|
||||
unsigned char color_mode,
|
||||
unsigned char red_single,
|
||||
unsigned char grn_single,
|
||||
unsigned char blu_single,
|
||||
unsigned char red_dual_1,
|
||||
unsigned char grn_dual_1,
|
||||
unsigned char blu_dual_1,
|
||||
unsigned char red_dual_2,
|
||||
unsigned char grn_dual_2,
|
||||
unsigned char blu_dual_2
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Effect packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_SET_EFFECT;
|
||||
buf[0x02] = profile;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set mode |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x09] = 0x01;
|
||||
buf[0x0A] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set direction |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x0D] = direction;
|
||||
buf[0x0E] = direction;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set reactive mode |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x1B] = reactive_mode;
|
||||
buf[0x1C] = reactive_mode;
|
||||
buf[0x1D] = reactive_mode;
|
||||
buf[0x1E] = reactive_mode;
|
||||
buf[0x1F] = reactive_mode;
|
||||
buf[0x20] = reactive_mode;
|
||||
buf[0x21] = reactive_mode;
|
||||
buf[0x22] = reactive_mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set mode-specific colors |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x29] = red_single;
|
||||
buf[0x41] = grn_single;
|
||||
buf[0x59] = blu_single;
|
||||
buf[0x2A] = red_dual_1;
|
||||
buf[0x42] = grn_dual_1;
|
||||
buf[0x5A] = blu_dual_1;
|
||||
buf[0x2B] = red_dual_2;
|
||||
buf[0x43] = grn_dual_2;
|
||||
buf[0x5B] = blu_dual_2;
|
||||
|
||||
buf[0x6B] = 0x09;
|
||||
buf[0x6C] = 0x09;
|
||||
buf[0x6D] = 0x05;
|
||||
buf[0x6E] = 0x05;
|
||||
buf[0x6F] = 0x06;
|
||||
buf[0x70] = 0x05;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set speed |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x71] = speed;
|
||||
|
||||
buf[0x72] = 0x09;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set color mode |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x73] = color_mode;
|
||||
buf[0x74] = color_mode;
|
||||
buf[0x75] = color_mode;
|
||||
buf[0x76] = color_mode;
|
||||
buf[0x77] = color_mode;
|
||||
buf[0x78] = color_mode;
|
||||
buf[0x79] = color_mode;
|
||||
buf[0x7A] = color_mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SendColor
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
|
||||
buf[0x02] = profile;
|
||||
buf[0x03] = color_channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < 106; i++)
|
||||
{
|
||||
buf[keys[i]] = color_data[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SendExtendedColor
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_SET_COLOR;
|
||||
buf[0x02] = profile;
|
||||
buf[0x03] = HYPERX_COLOR_CHANNEL_EXTENDED;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0x08; i <= 0x93; i++)
|
||||
{
|
||||
buf[i] = color_data[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SendDirect
|
||||
(
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
|
||||
buf[0x02] = color_channel;
|
||||
buf[0x03] = 0xA0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < 106; i++)
|
||||
{
|
||||
buf[keys[i]] = color_data[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SendDirectExtended
|
||||
(
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char buf[264];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
|
||||
buf[0x02] = HYPERX_COLOR_CHANNEL_EXTENDED;
|
||||
buf[0x03] = 0xA0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0x08; i <= 0x93; i++)
|
||||
{
|
||||
buf[i] = color_data[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 264);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXKeyboardController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX RGB |
|
||||
| Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/30/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_PACKET_ID_SET_EFFECT = 0x02, /* Set profile effect packet */
|
||||
HYPERX_PACKET_ID_SET_COLOR = 0x06, /* Set profile color packet */
|
||||
HYPERX_PACKET_ID_DIRECT = 0x16, /* Direct control packet */
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_DIRECTION_RIGHT = 0x00,
|
||||
HYPERX_DIRECTION_LEFT = 0x01,
|
||||
HYPERX_DIRECTION_UP = 0x02,
|
||||
HYPERX_DIRECTION_DOWN = 0x03,
|
||||
HYPERX_DIRECTION_IN = 0x04,
|
||||
HYPERX_DIRECTION_OUT = 0x05
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_MODE_WAVE = 0x00,
|
||||
HYPERX_MODE_STATIC = 0x01,
|
||||
HYPERX_MODE_BREATHING = 0x02,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_REACTIVE_MODE_TRIGGER = 0x03,
|
||||
HYPERX_REACTIVE_MODE_EXPLOSION = 0x04,
|
||||
HYPERX_REACTIVE_MODE_HYPERX_FLAME = 0x05,
|
||||
HYPERX_REACTIVE_MODE_NONE = 0xFF
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_COLOR_MODE_SINGLE = 0x00,
|
||||
HYPERX_COLOR_MODE_DUAL = 0x01,
|
||||
HYPERX_COLOR_MODE_SPECTRUM = 0x02
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HYPERX_COLOR_CHANNEL_RED = 0x01,
|
||||
HYPERX_COLOR_CHANNEL_GREEN = 0x02,
|
||||
HYPERX_COLOR_CHANNEL_BLUE = 0x03,
|
||||
HYPERX_COLOR_CHANNEL_EXTENDED = 0x04
|
||||
};
|
||||
|
||||
class HyperXKeyboardController
|
||||
{
|
||||
public:
|
||||
HyperXKeyboardController(hid_device* dev_handle);
|
||||
~HyperXKeyboardController();
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char direction,
|
||||
unsigned char speed,
|
||||
std::vector<RGBColor> colors
|
||||
);
|
||||
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
unsigned char active_mode;
|
||||
unsigned char active_direction;
|
||||
unsigned char active_speed;
|
||||
|
||||
void SelectProfile
|
||||
(
|
||||
unsigned char profile
|
||||
);
|
||||
|
||||
void SendEffect
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char mode,
|
||||
unsigned char direction,
|
||||
unsigned char reactive_mode,
|
||||
unsigned char speed,
|
||||
unsigned char color_mode,
|
||||
unsigned char red_single,
|
||||
unsigned char grn_single,
|
||||
unsigned char blu_single,
|
||||
unsigned char red_dual_1,
|
||||
unsigned char grn_dual_1,
|
||||
unsigned char blu_dual_1,
|
||||
unsigned char red_dual_2,
|
||||
unsigned char grn_dual_2,
|
||||
unsigned char blu_dual_2
|
||||
);
|
||||
|
||||
void SendColor
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendExtendedColor
|
||||
(
|
||||
unsigned char profile,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char color_channel,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendDirectExtended
|
||||
(
|
||||
unsigned char* color_data
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
#include "HyperXKeyboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HyperXAlloyOrigins.h"
|
||||
#include "RGBController_HyperXKeyboard.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| HyperX keyboard vendor IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ELITE_PID 0x16BE
|
||||
#define HYPERX_ALLOY_FPS_RGB_PID 0x16DC
|
||||
#define HYPERX_ALLOY_ORIGINS_PID 0x16E5
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} hyperx_device;
|
||||
|
||||
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const hyperx_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, "HyperX Alloy Elite RGB" },
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, "HyperX Alloy FPS RGB" },
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3, "HyperX Alloy Origins" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHyperXKeyboardControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a HyperX Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHyperXKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for HyperX RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((device_list[device_idx].usb_pid != HYPERX_ALLOY_ORIGINS_PID)
|
||||
&&(info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF01))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
|
||||
|
||||
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
if((device_list[device_idx].usb_pid == HYPERX_ALLOY_ORIGINS_PID)
|
||||
&&(info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXAlloyOriginsController* controller = new HyperXAlloyOriginsController(dev);
|
||||
|
||||
RGBController_HyperXAlloyOrigins* rgb_controller = new RGBController_HyperXAlloyOrigins(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "HyperXPulsefireSurgeController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HyperXPulsefireSurge.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| HyperX keyboard vendor IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define HYPERX_VID 0x0951
|
||||
#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} hyperx_device;
|
||||
|
||||
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const hyperx_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, "HyperX Pulsefire Surge" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHyperXMouseControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a HyperX Mouse controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHyperXMouseControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for HyperX RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXPulsefireSurgeController* controller = new HyperXPulsefireSurgeController(dev);
|
||||
|
||||
RGBController_HyperXPulsefireSurge* rgb_controller = new RGBController_HyperXPulsefireSurge(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXPulsefireSurgeController.cpp |
|
||||
| |
|
||||
| Driver for HyperX Pulsefire Surge |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXPulsefireSurgeController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
HyperXPulsefireSurgeController::HyperXPulsefireSurgeController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
HyperXPulsefireSurgeController::~HyperXPulsefireSurgeController()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXPulsefireSurgeController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX |
|
||||
| Pulsefire Surge lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class HyperXPulsefireSurgeController
|
||||
{
|
||||
public:
|
||||
HyperXPulsefireSurgeController(hid_device* dev_handle);
|
||||
~HyperXPulsefireSurgeController();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -37,12 +37,12 @@ void DetectLEDStripControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
#ifdef WIN32
|
||||
GetModuleFileName(NULL, filename, 2048);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
strcat(filename, "\\settings.txt");
|
||||
strcat(filename, "\\ledstrip.txt");
|
||||
#else
|
||||
snprintf(arg1, 64, "/proc/%d/exe", getpid());
|
||||
readlink(arg1, filename, 1024);
|
||||
strcpy(filename, std::string(filename).substr(0, std::string(filename).find_last_of("\\/")).c_str());
|
||||
strcat(filename, "/settings.txt");
|
||||
strcat(filename, "/ledstrip.txt");
|
||||
#endif
|
||||
|
||||
//Open settings file
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "LogitechG203Controller.h"
|
||||
#include "LogitechG403Controller.h"
|
||||
#include "LogitechG810Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_LogitechG203.h"
|
||||
#include "RGBController_LogitechG403.h"
|
||||
#include "RGBController_LogitechG810.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Logitech vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_VID 0x046D
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_G810_1_PID 0xC337
|
||||
#define LOGITECH_G810_2_PID 0xC331
|
||||
#define LOGITECH_G512_PID 0xC342
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_G203_PID 0xC084
|
||||
#define LOGITECH_G403_PID 0xC083
|
||||
#define LOGITECH_G403H_PID 0xC08F
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
device_type type;
|
||||
const char * name;
|
||||
} logitech_device;
|
||||
|
||||
#define LOGITECH_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const logitech_device device_list[] =
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
{ LOGITECH_VID, LOGITECH_G810_1_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
|
||||
{ LOGITECH_VID, LOGITECH_G810_2_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
|
||||
{ LOGITECH_VID, LOGITECH_G512_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G512" },
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
{ LOGITECH_VID, LOGITECH_G203_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G203 Prodigy" },
|
||||
{ LOGITECH_VID, LOGITECH_G403_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Prodigy" },
|
||||
{ LOGITECH_VID, LOGITECH_G403H_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Hero" },
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectLogitechControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Logitech RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectLogitechControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_init();
|
||||
|
||||
for(int device_idx = 0; device_idx < LOGITECH_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
switch(device_list[device_idx].type)
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Logitech keyboards use two different usages, one for 20-byte packets and one for 64-byte packets |
|
||||
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
{
|
||||
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF43)
|
||||
&&(info->usage == 0x0602))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
hid_device* dev_usage_0x0602 = hid_open_path(info->path);
|
||||
|
||||
if(dev_usage_0x0602)
|
||||
{
|
||||
#ifdef USE_HID_USAGE
|
||||
hid_device_info* tmp_info_0x0604 = info;
|
||||
|
||||
while(tmp_info_0x0604)
|
||||
{
|
||||
if((tmp_info_0x0604->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(tmp_info_0x0604->product_id == device_list[device_idx].usb_pid)
|
||||
&&(tmp_info_0x0604->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(tmp_info_0x0604->usage_page == 0xFF43)
|
||||
&&(tmp_info_0x0604->usage == 0x0604))
|
||||
{
|
||||
hid_device* dev_usage_0x0604 = hid_open_path(tmp_info_0x0604->path);
|
||||
|
||||
if(dev_usage_0x0604)
|
||||
{
|
||||
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0604);
|
||||
|
||||
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
tmp_info_0x0604 = tmp_info_0x0604->next;
|
||||
}
|
||||
#else
|
||||
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0602);
|
||||
|
||||
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
break;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Logitech mice use a single usage on page 0xFF00 |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
{
|
||||
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF00)
|
||||
&&(info->usage == 2))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
switch(device_list[device_idx].usb_pid)
|
||||
{
|
||||
case LOGITECH_G203_PID:
|
||||
{
|
||||
LogitechG203Controller* controller = new LogitechG203Controller(dev);
|
||||
|
||||
RGBController_LogitechG203* rgb_controller = new RGBController_LogitechG203(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOGITECH_G403_PID:
|
||||
case LOGITECH_G403H_PID:
|
||||
{
|
||||
LogitechG403Controller* controller = new LogitechG403Controller(dev);
|
||||
|
||||
RGBController_LogitechG403* rgb_controller = new RGBController_LogitechG403(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG203Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203 Prodigy mouse |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 5/17/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "LogitechG203Controller.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
LogitechG203Controller::LogitechG203Controller(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG203Controller::SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x3C;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 1000 + 4750 * (LOGITECH_G203_SPEED_FASTEST - speed);
|
||||
if(mode == LOGITECH_G203_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G203_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 20);
|
||||
hid_read(dev, (unsigned char *)usb_buf, 20);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG203Controller.h |
|
||||
| |
|
||||
| Definitions and types for Logitech G203 |
|
||||
| Prodigy mouse lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 5/17/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G203_MODE_OFF = 0x00,
|
||||
LOGITECH_G203_MODE_STATIC = 0x01,
|
||||
LOGITECH_G203_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G203_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G203_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G203_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G203_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G203_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G203_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG203Controller
|
||||
{
|
||||
public:
|
||||
LogitechG203Controller(hid_device* dev_handle);
|
||||
~LogitechG203Controller();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG403Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G403 Prodigy mouse |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 5/19/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "LogitechG403Controller.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
LogitechG403Controller::LogitechG403Controller(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
LogitechG403Controller::~LogitechG403Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void LogitechG403Controller::SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
std::uint16_t speed,
|
||||
unsigned char channel,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x3C;
|
||||
usb_buf[0x04] = channel;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 1000 + 4750 * (LOGITECH_G403_SPEED_FASTEST - speed);
|
||||
if(mode == LOGITECH_G403_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G403_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG403Controller.h |
|
||||
| |
|
||||
| Definitions and types for Logitech G403 |
|
||||
| Prodigy mouse lighting controller |
|
||||
| |
|
||||
| Martin Hartl (inlart) 5/19/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G403_MODE_OFF = 0x00,
|
||||
LOGITECH_G403_MODE_STATIC = 0x01,
|
||||
LOGITECH_G403_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G403_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G403_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G403_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G403_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G403_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G403_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG403Controller
|
||||
{
|
||||
public:
|
||||
LogitechG403Controller(hid_device* dev_handle);
|
||||
~LogitechG403Controller();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char channel,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG810Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| keyboard light controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "LogitechG810Controller.h"
|
||||
#include <cstring>
|
||||
|
||||
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
}
|
||||
|
||||
LogitechG810Controller::~LogitechG810Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LogitechG810Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG810Controller::SendCommit()
|
||||
{
|
||||
char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, (unsigned char *)usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 1000 + 4750 * (LOGITECH_G810_SPEED_FASTEST - speed);
|
||||
if(mode == LOGITECH_G810_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G810_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG810Controller.h |
|
||||
| |
|
||||
| Definitions and types for Logitech G810 |
|
||||
| Orion Spectrum keyboard light controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_MODE_OFF = 0x00,
|
||||
LOGITECH_G810_MODE_STATIC = 0x01,
|
||||
LOGITECH_G810_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G810_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G810_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G810_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G810_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G810_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G810_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG810Controller
|
||||
{
|
||||
public:
|
||||
LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12);
|
||||
~LogitechG810Controller();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSI3ZoneController.cpp |
|
||||
| |
|
||||
| Driver for MSI/Steelseries 3-Zone |
|
||||
| Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12/25/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSI3ZoneController.h"
|
||||
|
||||
MSI3ZoneController::MSI3ZoneController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
//strcpy(device_name, "MSI 3-Zone Keyboard");
|
||||
}
|
||||
|
||||
MSI3ZoneController::~MSI3ZoneController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* MSI3ZoneController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
void MSI3ZoneController::SetLEDs(std::vector<RGBColor> colors)
|
||||
{
|
||||
//Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol!
|
||||
// https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation
|
||||
unsigned char buf[8] = { 0 };
|
||||
|
||||
buf[0] = 1;
|
||||
buf[1] = 2;
|
||||
buf[2] = 64;
|
||||
buf[3] = 1;
|
||||
buf[4] = RGBGetRValue(colors[0]);
|
||||
buf[5] = RGBGetGValue(colors[0]);
|
||||
buf[6] = RGBGetBValue(colors[0]);
|
||||
buf[7] = 236;
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 2;
|
||||
buf[4] = RGBGetRValue(colors[1]);
|
||||
buf[5] = RGBGetGValue(colors[1]);
|
||||
buf[6] = RGBGetBValue(colors[1]);
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 3;
|
||||
buf[4] = RGBGetRValue(colors[2]);
|
||||
buf[5] = RGBGetGValue(colors[2]);
|
||||
buf[6] = RGBGetBValue(colors[2]);
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 4;
|
||||
buf[4] = RGBGetRValue(colors[3]);
|
||||
buf[5] = RGBGetGValue(colors[3]);
|
||||
buf[6] = RGBGetBValue(colors[3]);
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 5;
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 6;
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
|
||||
buf[3] = 7;
|
||||
|
||||
hid_send_feature_report(dev, buf, 8);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSI3ZoneController.h |
|
||||
| |
|
||||
| Definitions and types for MSI/Steelseries|
|
||||
| 3-Zone Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12/25/2019 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class MSI3ZoneController
|
||||
{
|
||||
public:
|
||||
MSI3ZoneController(hid_device* dev_handle);
|
||||
~MSI3ZoneController();
|
||||
|
||||
char* GetDeviceName();
|
||||
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "MSI3ZoneController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_MSI3Zone.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define MSI_3_ZONE_KEYBOARD_VID 0x1770
|
||||
#define MSI_3_ZONE_KEYBOARD_PID 0xFF00
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectMSI3ZoneControllers *
|
||||
* *
|
||||
* Tests the USB address to see if an MSI/SteelSeries 3-zone Keyboard controller *
|
||||
* exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectMSI3ZoneControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device* dev;
|
||||
|
||||
//Look for MSI/Steelseries 3-zone Keyboard
|
||||
hid_init();
|
||||
|
||||
dev = hid_open(MSI_3_ZONE_KEYBOARD_VID, MSI_3_ZONE_KEYBOARD_PID, 0);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
MSI3ZoneController* controller = new MSI3ZoneController(dev);
|
||||
|
||||
RGBController_MSI3Zone* rgb_controller = new RGBController_MSI3Zone(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUController.cpp |
|
||||
| |
|
||||
| Driver for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIGPUController.h"
|
||||
#include <cstring>
|
||||
|
||||
MSIGPUController::MSIGPUController(i2c_smbus_interface* bus)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = 0x68;
|
||||
}
|
||||
|
||||
MSIGPUController::~MSIGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string MSIGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB1(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R1, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G1, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B1, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB2(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R2, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G2, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B2, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB3(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R3, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G3, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B3, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetMode(unsigned char mode)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_MODE, mode);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_APPLY, 0x01);
|
||||
}
|
||||
|
||||
unsigned char MSIGPUController::MSIGPURegisterRead(unsigned char reg)
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, reg));
|
||||
}
|
||||
|
||||
void MSIGPUController::MSIGPURegisterWrite(unsigned char reg, unsigned char val)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUController.h |
|
||||
| |
|
||||
| Definitions for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char msi_gpu_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_GPU_REG_BRIGHTNESS = 0x36, /* MSI GPU Brightness Register */
|
||||
MSI_GPU_REG_SPEED = 0x38, /* MSI GPU Speed Register */
|
||||
MSI_GPU_REG_UNKNOWN = 0x26, /* MSI GPU Unknown Register */
|
||||
MSI_GPU_REG_R1 = 0x30, /* MSI GPU R1 Register */
|
||||
MSI_GPU_REG_G1 = 0x31, /* MSI GPU G1 Register */
|
||||
MSI_GPU_REG_B1 = 0x32, /* MSI GPU B1 Register */
|
||||
MSI_GPU_REG_R2 = 0x27, /* MSI GPU R2 Register */
|
||||
MSI_GPU_REG_G2 = 0x28, /* MSI GPU G2 Register */
|
||||
MSI_GPU_REG_B2 = 0x29, /* MSI GPU B2 Register */
|
||||
MSI_GPU_REG_R3 = 0x2a, /* MSI GPU R3 Register */
|
||||
MSI_GPU_REG_G3 = 0x2b, /* MSI GPU G3 Register */
|
||||
MSI_GPU_REG_B3 = 0x2c, /* MSI GPU B3 Register */
|
||||
MSI_GPU_REG_MODE = 0x22, /* MSI GPU Mode Selection Register */
|
||||
MSI_GPU_REG_APPLY = 0x3f, /* MSI GPU Apply Changes Register */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_GPU_MODE_OFF = 0x01, /* OFF mode */
|
||||
MSI_GPU_MODE_RAINBOW = 0x08, /* Rainbow effect mode */
|
||||
MSI_GPU_MODE_STATIC = 0x13, /* Static color mode */
|
||||
MSI_GPU_MODE_RAINDROP = 0x1a, /* Raindrop effect mode */
|
||||
MSI_GPU_MODE_MAGIC = 0x07, /* Magic effect mode */
|
||||
MSI_GPU_MODE_PATROLLING = 0x05, /* Patrolling effect mode */
|
||||
MSI_GPU_MODE_STREAMING = 0x06, /* Streaming effect mode */
|
||||
MSI_GPU_MODE_LIGHTNING = 0x15, /* Lightning effect mode */
|
||||
MSI_GPU_MODE_WAVE = 0x1f, /* Wave effect mode */
|
||||
MSI_GPU_MODE_METEOR = 0x16, /* Meteor effect mode */
|
||||
MSI_GPU_MODE_STACK = 0x0d, /* Stack effect mode */
|
||||
MSI_GPU_MODE_RHYTHM = 0x0b, /* Rhythm effect mode */
|
||||
MSI_GPU_MODE_FLOWING = 0x09, /* Flowing effect mode */
|
||||
MSI_GPU_MODE_WHIRLING = 0x0f, /* Whirling effect mode */
|
||||
MSI_GPU_MODE_TWISTING = 0x11, /* Twisting effect mode */
|
||||
MSI_GPU_MODE_LAMINATING = 0x1d, /* Laminating effect mode */
|
||||
MSI_GPU_MODE_FADEIN = 0x14, /* Fadein effect mode */
|
||||
MSI_GPU_MODE_BREATHING = 0x04, /* Breathing effect mode */
|
||||
MSI_GPU_MODE_FLASHING = 0x02, /* Flashing effect mode */
|
||||
MSI_GPU_MODE_DOUBLEFLASHING = 0x03, /* Doubleflashing effect mode */
|
||||
};
|
||||
|
||||
class MSIGPUController
|
||||
{
|
||||
public:
|
||||
MSIGPUController(i2c_smbus_interface* bus);
|
||||
~MSIGPUController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
void SetRGB1(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetRGB2(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetRGB3(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char MSIGPURegisterRead(unsigned char reg);
|
||||
void MSIGPURegisterWrite(unsigned char reg, unsigned char val);
|
||||
|
||||
private:
|
||||
i2c_smbus_interface * bus;
|
||||
msi_gpu_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_MSIGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| NVidia vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define NVIDIA_VEN 0x10DE
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| NVidia device IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define NVIDIA_RTX2060_DEV 0x1F08
|
||||
#define NVIDIA_RTX2060S_DEV 0x1F06
|
||||
#define NVIDIA_RTX2070_DEV 0x1F02
|
||||
#define NVIDIA_RTX2070S_DEV 0x1E84
|
||||
#define NVIDIA_RTX2080_DEV 0x1E87
|
||||
#define NVIDIA_RTX2080S_DEV 0x1E81
|
||||
#define NVIDIA_RTX2080TI_DEV 0x1E07
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| MSI sub-vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define MSI_SUB_VEN 0x1462
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| MSI sub-device IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define MSI_RTX2060S_GAMING_X_SUB_DEV 0xC752
|
||||
#define MSI_RTX2070S_GAMING_X_SUB_DEV 0x373e
|
||||
#define MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV 0xC726
|
||||
#define MSI_RTX2080_GAMING_X_TRIO_SUB_DEV 0x3726
|
||||
#define MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV 0xC724
|
||||
#define MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV 0x3715
|
||||
#define MSI_RTX2060_GAMING_Z_6G_SUB_DEV 0x3754
|
||||
#define MSI_RTX2070_ARMOR_SUB_DEV 0x3734
|
||||
#define MSI_RTX2060S_ARMOR_OC_SUB_DEV 0xC754
|
||||
#define MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV 0x3728
|
||||
#define MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV 0x3717
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pci_vendor;
|
||||
int pci_device;
|
||||
int pci_subsystem_vendor;
|
||||
int pci_subsystem_device;
|
||||
const char * name;
|
||||
} msi_gpu_pci_device;
|
||||
|
||||
#define MSI_GPU_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const msi_gpu_pci_device device_list[] =
|
||||
{
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2060 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080S_DEV, MSI_SUB_VEN, MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Super Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080Ti Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV, "MSI GeForce RTX 2060 Gaming Z 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_ARMOR_OC_SUB_DEV, "MSI GeForce RTX 2060 Super ARMOR OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, MSI_SUB_VEN, MSI_RTX2070_ARMOR_SUB_DEV, "MSI GeForce RTX 2070 ARMOR" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080 Sea Hawk EK X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080Ti Sea Hawk EK X" },
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectMSIGPUControllers *
|
||||
* *
|
||||
* Detect MSI GPU controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectMSIGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
MSIGPUController* new_msi_gpu;
|
||||
RGBController_MSIGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
for(unsigned int dev_idx = 0; dev_idx < MSI_GPU_NUM_DEVICES; dev_idx++)
|
||||
{
|
||||
if (busses[bus]->port_id != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(busses[bus]->pci_vendor == device_list[dev_idx].pci_vendor &&
|
||||
busses[bus]->pci_device == device_list[dev_idx].pci_device &&
|
||||
busses[bus]->pci_subsystem_vendor == device_list[dev_idx].pci_subsystem_vendor &&
|
||||
busses[bus]->pci_subsystem_device == device_list[dev_idx].pci_subsystem_device)
|
||||
{
|
||||
new_msi_gpu = new MSIGPUController(busses[bus]);
|
||||
new_controller = new RGBController_MSIGPU(new_msi_gpu);
|
||||
new_controller->name = device_list[dev_idx].name;
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* DetectMSIGPUControllers() */
|
||||
@@ -0,0 +1,580 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIMysticLightController.cpp |
|
||||
| |
|
||||
| Driver for MSI Mystic Light USB |
|
||||
| lighting controller |
|
||||
| |
|
||||
| T-bond 3/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIMysticLightController.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
|
||||
MSIMysticLightController::MSIMysticLightController(hid_device* handle, const char *path)
|
||||
{
|
||||
dev = handle;
|
||||
|
||||
if(dev)
|
||||
{
|
||||
loc = path;
|
||||
|
||||
ReadName();
|
||||
ReadSerial();
|
||||
ReadFwVersion();
|
||||
ReadSettings();
|
||||
}
|
||||
}
|
||||
|
||||
MSIMysticLightController::~MSIMysticLightController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneMinLedCount
|
||||
(
|
||||
MSI_ZONE /*zone*/
|
||||
)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneMaxLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch(zone)
|
||||
{
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
return 4; // TODO: It can be different by zone and by mobo
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
if (!requestedZone)
|
||||
{
|
||||
return GetZoneMaxLedCount(zone);
|
||||
}
|
||||
|
||||
return requestedZone->cycle_or_led_num;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned int led_count
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
if (!requestedZone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
led_count = std::min(GetZoneMaxLedCount(zone), std::max(GetZoneMinLedCount(zone), led_count));
|
||||
requestedZone->cycle_or_led_num = led_count;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
)
|
||||
{
|
||||
ZoneData* zoneData = GetZoneData(zone);
|
||||
if(!zoneData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
zoneData->effect = mode;
|
||||
zoneData->speedAndBrightnessFlags = (zoneData->speedAndBrightnessFlags & 128u) | brightness << 2u | speed;
|
||||
zoneData->colorFlags = BitSet(zoneData->colorFlags, !rainbow_color, 7u);
|
||||
}
|
||||
|
||||
std::string MSIMysticLightController::GetDeviceName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string MSIMysticLightController::GetFWVersion()
|
||||
{
|
||||
return std::string("AP/LD ").append(version_APROM).append(" / ").append(version_LDROM);
|
||||
}
|
||||
|
||||
std::string MSIMysticLightController::GetDeviceLocation()
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
std::string MSIMysticLightController::GetSerial()
|
||||
{
|
||||
return chip_id;
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::ReadSettings()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet from hardware, return true if successful |
|
||||
\*-----------------------------------------------------*/
|
||||
return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::Update()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet to hardware, return true if successful |
|
||||
\*-----------------------------------------------------*/
|
||||
return(hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SaveOnUpdate(bool save)
|
||||
{
|
||||
data.save_data = save;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
)
|
||||
{
|
||||
ZoneData* zoneData = GetZoneData(zone);
|
||||
|
||||
if(!zoneData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
zoneData->color.R = red1;
|
||||
zoneData->color.G = grn1;
|
||||
zoneData->color.B = blu1;
|
||||
|
||||
zoneData->color2.R = red2;
|
||||
zoneData->color2.G = grn2;
|
||||
zoneData->color2.B = blu2;
|
||||
}
|
||||
|
||||
std::pair<Color, Color> MSIMysticLightController::GetZoneColor
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
ZoneData *zoneData = GetZoneData(zone);
|
||||
|
||||
if (!zoneData)
|
||||
{
|
||||
return std::make_pair(Color{}, Color{});
|
||||
}
|
||||
|
||||
return std::make_pair(Color{
|
||||
zoneData->color.R,
|
||||
zoneData->color.G,
|
||||
zoneData->color.B},
|
||||
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
|
||||
}
|
||||
|
||||
ZoneData *MSIMysticLightController::GetZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch(zone)
|
||||
{
|
||||
case MSI_ZONE_J_RGB_1:
|
||||
return &data.j_rgb_1;
|
||||
case MSI_ZONE_J_RGB_2:
|
||||
return &data.j_rgb_2;
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
return &data.j_rainbow_1;
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
return &data.j_rainbow_2;
|
||||
case MSI_ZONE_J_PIPE_1:
|
||||
return &data.j_pipe_1;
|
||||
case MSI_ZONE_J_PIPE_2:
|
||||
return &data.j_pipe_2;
|
||||
case MSI_ZONE_ON_BOARD_LED:
|
||||
return &data.on_board_led;
|
||||
case MSI_ZONE_ON_BOARD_LED_1:
|
||||
return &data.on_board_led_1;
|
||||
case MSI_ZONE_ON_BOARD_LED_2:
|
||||
return &data.on_board_led_2;
|
||||
case MSI_ZONE_ON_BOARD_LED_3:
|
||||
return &data.on_board_led_3;
|
||||
case MSI_ZONE_ON_BOARD_LED_4:
|
||||
return &data.on_board_led_4;
|
||||
case MSI_ZONE_ON_BOARD_LED_5:
|
||||
return &data.on_board_led_5;
|
||||
case MSI_ZONE_ON_BOARD_LED_6:
|
||||
return &data.on_board_led_6;
|
||||
case MSI_ZONE_ON_BOARD_LED_7:
|
||||
return &data.on_board_led_7;
|
||||
case MSI_ZONE_ON_BOARD_LED_8:
|
||||
return &data.on_board_led_8;
|
||||
case MSI_ZONE_ON_BOARD_LED_9:
|
||||
return &data.on_board_led_9;
|
||||
case MSI_ZONE_J_CORSAIR_OUTERLL120:
|
||||
return &data.j_corsair_outerll120;
|
||||
default:
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch(zone)
|
||||
{
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
return &data.j_rainbow_1;
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
return &data.j_rainbow_2;
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::ReadFwVersion()
|
||||
{
|
||||
unsigned char request[64];
|
||||
unsigned char response[64];
|
||||
int ret_val = 64;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First read the APROM |
|
||||
| Checksum also available at report ID 180, with MSB |
|
||||
| stored at index 0x08 and LSB at 0x09 |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffers |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(request, 0x00, sizeof(request));
|
||||
memset(response, 0x00, sizeof(response));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up APROM Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
request[0x00] = 0x01;
|
||||
request[0x01] = 0xB0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill request from 0x02 to 0x61 with 0xCC |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(&request[0x02], 0xCC, sizeof(request) - 2);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send request and receive response packets |
|
||||
\*-----------------------------------------------------*/
|
||||
ret_val &= hid_write(dev, request, 64);
|
||||
ret_val &= hid_read(dev, response, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract high and low values from response |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char highValue = response[2] >> 4;
|
||||
unsigned char lowValue = response[2] & 0x0F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build firmware string <high>.<low> |
|
||||
\*-----------------------------------------------------*/
|
||||
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First read the LDROM |
|
||||
| Checksum also available at report ID 184, with MSB |
|
||||
| stored at index 0x08 and LSB at 0x09 |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LDROM Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
request[0x00] = 0x01;
|
||||
request[0x01] = 0xB6;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send request and receive response packets |
|
||||
\*-----------------------------------------------------*/
|
||||
ret_val &= hid_write(dev, request, 64);
|
||||
ret_val &= hid_read(dev, response, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract high and low values from response |
|
||||
\*-----------------------------------------------------*/
|
||||
highValue = response[2] >> 4;
|
||||
lowValue = response[2] & 0x0F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build firmware string <high>.<low> |
|
||||
\*-----------------------------------------------------*/
|
||||
version_LDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If return value is zero it means an HID transfer |
|
||||
| failed |
|
||||
\*-----------------------------------------------------*/
|
||||
return(ret_val > 0);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::ReadSerial()
|
||||
{
|
||||
wchar_t serial[256];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the serial number string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_serial_number_string(dev, serial, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert wchar_t into std::wstring into std::string |
|
||||
\*-----------------------------------------------------*/
|
||||
std::wstring wserial = std::wstring(serial);
|
||||
chip_id = std::string(wserial.begin(), wserial.end());
|
||||
}
|
||||
|
||||
void MSIMysticLightController::ReadName()
|
||||
{
|
||||
wchar_t tname[256];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the manufacturer string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_manufacturer_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert wchar_t into std::wstring into std::string |
|
||||
\*-----------------------------------------------------*/
|
||||
std::wstring wname = std::wstring(tname);
|
||||
name = std::string(wname.begin(), wname.end());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the product string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_product_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Append the product string to the manufacturer string |
|
||||
\*-----------------------------------------------------*/
|
||||
wname = std::wstring(tname);
|
||||
name.append(" ").append(std::string(wname.begin(), wname.end()));
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetDeviceSettings
|
||||
(
|
||||
bool is_fan,
|
||||
MSI_FAN_TYPE fan_type,
|
||||
unsigned char corsair_device_quantity,
|
||||
bool is_LL120Outer_individual
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| If is_fan is false, it is an LED strip |
|
||||
\*-----------------------------------------------------*/
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
settingsZone.fan_flags = (settingsZone.fan_flags & 0x80) | fan_type << 1 | is_fan;
|
||||
settingsZone.corsair_quantity = corsair_device_quantity << 2;
|
||||
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0);
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::SetVolume
|
||||
(
|
||||
unsigned char main,
|
||||
unsigned char left,
|
||||
unsigned char right
|
||||
)
|
||||
{
|
||||
unsigned char packet[64];
|
||||
std::fill_n(packet, sizeof packet, 204u);
|
||||
|
||||
if(main > 100u)
|
||||
{
|
||||
main = 100u;
|
||||
}
|
||||
|
||||
if(left > 100u)
|
||||
{
|
||||
left = 100u;
|
||||
}
|
||||
|
||||
if(right > 100u)
|
||||
{
|
||||
right = 100u;
|
||||
}
|
||||
|
||||
packet[0] = 1u;
|
||||
packet[1] = 192u;
|
||||
packet[3] = main;
|
||||
packet[4] = left;
|
||||
packet[5] = right;
|
||||
|
||||
return hid_write(dev, packet, sizeof packet);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetBoardSyncSettings
|
||||
(
|
||||
bool onboard_sync,
|
||||
bool combine_JRGB,
|
||||
bool combine_JPIPE1,
|
||||
bool combine_JPIPE2,
|
||||
bool combine_JRAINBOW1,
|
||||
bool combine_JRAINBOW2,
|
||||
bool combine_crossair
|
||||
)
|
||||
{
|
||||
ZoneData &syncZone = data.on_board_led;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set sync flags for on-board LED zone |
|
||||
\*-----------------------------------------------------*/
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5);
|
||||
|
||||
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get data for given zone |
|
||||
\*-----------------------------------------------------*/
|
||||
ZoneData *zoneData = GetZoneData(zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Return if zone is invalid |
|
||||
\*-----------------------------------------------------*/
|
||||
if (!zoneData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update pointers with data |
|
||||
\*-----------------------------------------------------*/
|
||||
mode = (MSI_MODE)(zoneData->effect);
|
||||
speed = (MSI_SPEED)(zoneData->speedAndBrightnessFlags & 0x03);
|
||||
brightness = (MSI_BRIGHTNESS)((zoneData->speedAndBrightnessFlags >> 2) & 0x1F);
|
||||
rainbow_color = (zoneData->colorFlags & 0x80) >> 7;
|
||||
}
|
||||
|
||||
unsigned char MSIMysticLightController::BitSet
|
||||
(
|
||||
unsigned char value,
|
||||
bool bit,
|
||||
unsigned int position
|
||||
)
|
||||
{
|
||||
return static_cast<unsigned char>(std::bitset<8>(value).set(position, bit).to_ulong());
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
if (!requestedZone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
requestedZone->cycle_or_led_num = cycle_num;
|
||||
}
|
||||
|
||||
unsigned char MSIMysticLightController::GetCycleCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
if (!requestedZone)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return requestedZone->cycle_or_led_num;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetBoardSyncSettings
|
||||
(
|
||||
bool &onboard_sync,
|
||||
bool &combine_JRGB,
|
||||
bool &combine_JPIPE1,
|
||||
bool &combine_JPIPE2,
|
||||
bool &combine_JRAINBOW1,
|
||||
bool &combine_JRAINBOW2,
|
||||
bool &combine_crossair
|
||||
)
|
||||
{
|
||||
ZoneData &syncZone = data.on_board_led;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get sync flags for on-board LED zone |
|
||||
\*-----------------------------------------------------*/
|
||||
onboard_sync = (syncZone.colorFlags >> 0) & 0x01;
|
||||
combine_JRAINBOW1 = (syncZone.colorFlags >> 1) & 0x01;
|
||||
combine_JRAINBOW2 = (syncZone.colorFlags >> 2) & 0x01;
|
||||
combine_crossair = (syncZone.colorFlags >> 3) & 0x01;
|
||||
combine_JPIPE1 = (syncZone.colorFlags >> 4) & 0x01;
|
||||
combine_JPIPE2 = (syncZone.colorFlags >> 5) & 0x01;
|
||||
|
||||
combine_JRGB = (syncZone.speedAndBrightnessFlags & 0x80) >> 7;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetDeviceSettings
|
||||
(
|
||||
bool &stripe_or_fan,
|
||||
MSI_FAN_TYPE &fan_type,
|
||||
unsigned char &corsair_device_quantity,
|
||||
bool &is_LL120Outer_individual
|
||||
)
|
||||
{
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
stripe_or_fan = settingsZone.fan_flags & 0x01;
|
||||
fan_type = (MSI_FAN_TYPE )((settingsZone.fan_flags & 14u) >> 1);
|
||||
corsair_device_quantity = (settingsZone.corsair_quantity & 0xFC) >> 2;
|
||||
is_LL120Outer_individual = settingsZone.is_individual & 0x01;
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIMysticLightController.h |
|
||||
| |
|
||||
| Definitions and types for MSI Mystic |
|
||||
| Light USB lighting controllers |
|
||||
| |
|
||||
| T-bond 3/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <cstring>
|
||||
#include <hidapi/hidapi.h>
|
||||
#include <limits>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum MSI_ZONE
|
||||
{
|
||||
MSI_ZONE_J_RGB_1 = 1,
|
||||
MSI_ZONE_J_RGB_2 = 174,
|
||||
MSI_ZONE_J_PIPE_1 = 11,
|
||||
MSI_ZONE_J_PIPE_2 = 21,
|
||||
MSI_ZONE_J_RAINBOW_1 = 31,
|
||||
MSI_ZONE_J_RAINBOW_2 = 42,
|
||||
MSI_ZONE_J_CORSAIR = 53,
|
||||
MSI_ZONE_J_CORSAIR_OUTERLL120 = 64,
|
||||
MSI_ZONE_ON_BOARD_LED = 74,
|
||||
MSI_ZONE_ON_BOARD_LED_1 = 84,
|
||||
MSI_ZONE_ON_BOARD_LED_2 = 94,
|
||||
MSI_ZONE_ON_BOARD_LED_3 = 104,
|
||||
MSI_ZONE_ON_BOARD_LED_4 = 114,
|
||||
MSI_ZONE_ON_BOARD_LED_5 = 124,
|
||||
MSI_ZONE_ON_BOARD_LED_6 = 134,
|
||||
MSI_ZONE_ON_BOARD_LED_7 = 144,
|
||||
MSI_ZONE_ON_BOARD_LED_8 = 154,
|
||||
MSI_ZONE_ON_BOARD_LED_9 = 164
|
||||
};
|
||||
|
||||
struct ZoneDescription
|
||||
{
|
||||
std::string name;
|
||||
MSI_ZONE value;
|
||||
};
|
||||
|
||||
enum MSI_MODE
|
||||
{
|
||||
MSI_MODE_DISABLE = 0,
|
||||
MSI_MODE_STATIC = 1,
|
||||
MSI_MODE_BREATHING = 2,
|
||||
MSI_MODE_FLASHING = 3,
|
||||
MSI_MODE_DOUBLE_FLASHING = 4,
|
||||
MSI_MODE_LIGHTNING = 5,
|
||||
MSI_MODE_MSI_MARQUEE = 6,
|
||||
MSI_MODE_METEOR = 7,
|
||||
MSI_MODE_WATER_DROP = 8,
|
||||
MSI_MODE_MSI_RAINBOW = 9,
|
||||
MSI_MODE_POP = 10,
|
||||
MSI_MODE_RAP = 11,
|
||||
MSI_MODE_JAZZ = 12,
|
||||
MSI_MODE_PLAY = 13,
|
||||
MSI_MODE_MOVIE = 14,
|
||||
MSI_MODE_COLOR_RING = 15,
|
||||
MSI_MODE_PLANETARY = 16,
|
||||
MSI_MODE_DOUBLE_METEOR = 17,
|
||||
MSI_MODE_ENERGY = 18,
|
||||
MSI_MODE_BLINK = 19,
|
||||
MSI_MODE_CLOCK = 20,
|
||||
MSI_MODE_COLOR_PULSE = 21,
|
||||
MSI_MODE_COLOR_SHIFT = 22,
|
||||
MSI_MODE_COLOR_WAVE = 23,
|
||||
MSI_MODE_MARQUEE = 24,
|
||||
MSI_MODE_RAINBOW = 25,
|
||||
MSI_MODE_RAINBOW_WAVE = 26,
|
||||
MSI_MODE_VISOR = 27,
|
||||
MSI_MODE_JRAINBOW = 28,
|
||||
MSI_MODE_RAINBOW_FLASHING = 29,
|
||||
MSI_MODE_RAINBOW_DOUBLE_FLASHING = 30,
|
||||
MSI_MODE_RANDOM = 31,
|
||||
MSI_MODE_FAN_CONTROL = 32,
|
||||
MSI_MODE_DISABLE_2 = 33,
|
||||
MSI_MODE_COLOR_RING_FLASHING = 34,
|
||||
MSI_MODE_COLOR_RING_DOUBLE_FLASHING = 35,
|
||||
MSI_MODE_STACK = 36,
|
||||
MSI_MODE_CORSAIR_QUE = 37,
|
||||
MSI_MODE_FIRE = 38,
|
||||
MSI_MODE_LAVA = 39,
|
||||
};
|
||||
|
||||
enum MSI_SPEED
|
||||
{
|
||||
MSI_SPEED_LOW = 0,
|
||||
MSI_SPEED_MEDIUM = 1,
|
||||
MSI_SPEED_HIGH = 2,
|
||||
};
|
||||
|
||||
enum MSI_FAN_TYPE
|
||||
{
|
||||
MSI_FAN_TYPE_SP = 0,
|
||||
MSI_FAN_TYPE_HD = 1,
|
||||
MSI_FAN_TYPE_LL = 2,
|
||||
};
|
||||
|
||||
enum MSI_BRIGHTNESS
|
||||
{
|
||||
MSI_BRIGHTNESS_OFF = 0,
|
||||
MSI_BRIGHTNESS_LEVEL_10 = 1,
|
||||
MSI_BRIGHTNESS_LEVEL_20 = 2,
|
||||
MSI_BRIGHTNESS_LEVEL_30 = 3,
|
||||
MSI_BRIGHTNESS_LEVEL_40 = 4,
|
||||
MSI_BRIGHTNESS_LEVEL_50 = 5,
|
||||
MSI_BRIGHTNESS_LEVEL_60 = 6,
|
||||
MSI_BRIGHTNESS_LEVEL_70 = 7,
|
||||
MSI_BRIGHTNESS_LEVEL_80 = 8,
|
||||
MSI_BRIGHTNESS_LEVEL_90 = 9,
|
||||
MSI_BRIGHTNESS_LEVEL_100 = 10,
|
||||
};
|
||||
|
||||
struct Color
|
||||
{
|
||||
unsigned char R;
|
||||
unsigned char G;
|
||||
unsigned char B;
|
||||
};
|
||||
|
||||
struct CorsairZoneData
|
||||
{
|
||||
unsigned char effect = MSI_MODE_STATIC;
|
||||
Color color { 0, 0, 0 };
|
||||
unsigned char fan_flags = 40;
|
||||
unsigned char corsair_quantity;
|
||||
unsigned char padding[3];
|
||||
unsigned char is_individual = 0;
|
||||
};
|
||||
|
||||
struct ZoneData
|
||||
{
|
||||
unsigned char effect = MSI_MODE_STATIC;
|
||||
Color color { 0, 0, 0 };
|
||||
unsigned char speedAndBrightnessFlags = 40;
|
||||
Color color2 { 0, 0, 0 };
|
||||
unsigned char colorFlags = 128;
|
||||
const unsigned char padding = 0;
|
||||
};
|
||||
|
||||
struct RainbowZoneData : ZoneData
|
||||
{
|
||||
unsigned char cycle_or_led_num = 20;
|
||||
};
|
||||
|
||||
struct FeaturePacket
|
||||
{
|
||||
const unsigned char report_id = 0x52; // Report ID
|
||||
ZoneData j_rgb_1; // 1
|
||||
ZoneData j_pipe_1; // 11
|
||||
ZoneData j_pipe_2; // 21
|
||||
RainbowZoneData j_rainbow_1; // 31
|
||||
RainbowZoneData j_rainbow_2; // 42
|
||||
CorsairZoneData j_corsair; // 53
|
||||
ZoneData j_corsair_outerll120; // 64
|
||||
ZoneData on_board_led; // 74
|
||||
ZoneData on_board_led_1; // 84
|
||||
ZoneData on_board_led_2; // 94
|
||||
ZoneData on_board_led_3; // 104
|
||||
ZoneData on_board_led_4; // 114
|
||||
ZoneData on_board_led_5; // 124
|
||||
ZoneData on_board_led_6; // 134
|
||||
ZoneData on_board_led_7; // 144
|
||||
ZoneData on_board_led_8; // 154
|
||||
ZoneData on_board_led_9; // 164
|
||||
ZoneData j_rgb_2; // 174
|
||||
unsigned char save_data = 0; // 184
|
||||
};
|
||||
|
||||
|
||||
class MSIMysticLightController
|
||||
{
|
||||
public:
|
||||
MSIMysticLightController(hid_device* handle, const char *path);
|
||||
~MSIMysticLightController();
|
||||
|
||||
unsigned int GetZoneMinLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
unsigned int GetZoneMaxLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
unsigned int GetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
void SetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned int led_count
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
);
|
||||
|
||||
void GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color
|
||||
);
|
||||
|
||||
void SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
);
|
||||
|
||||
void SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
);
|
||||
|
||||
unsigned char GetCycleCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
std::pair<Color, Color>
|
||||
GetZoneColor(MSI_ZONE zone);
|
||||
|
||||
bool Update();
|
||||
|
||||
void SetDeviceSettings
|
||||
(
|
||||
bool stripe_or_fan,
|
||||
MSI_FAN_TYPE fan_type,
|
||||
unsigned char corsair_device_quantity,
|
||||
bool is_LL120Outer_individual
|
||||
);
|
||||
|
||||
void GetDeviceSettings
|
||||
(
|
||||
bool &stripe_or_fan,
|
||||
MSI_FAN_TYPE &fan_type,
|
||||
unsigned char &corsair_device_quantity,
|
||||
bool &is_LL120Outer_individual
|
||||
);
|
||||
|
||||
bool SetVolume
|
||||
(
|
||||
unsigned char main,
|
||||
unsigned char left,
|
||||
unsigned char right
|
||||
);
|
||||
|
||||
void SetBoardSyncSettings
|
||||
(
|
||||
bool onboard_sync,
|
||||
bool combine_JRGB,
|
||||
bool combine_JPIPE1,
|
||||
bool combine_JPIPE2,
|
||||
bool combine_JRAINBOW1,
|
||||
bool combine_JRAINBOW2,
|
||||
bool combine_crossair
|
||||
);
|
||||
|
||||
void GetBoardSyncSettings
|
||||
(
|
||||
bool &onboard_sync,
|
||||
bool &combine_JRGB,
|
||||
bool &combine_JPIPE1,
|
||||
bool &combine_JPIPE2,
|
||||
bool &combine_JRAINBOW1,
|
||||
bool &combine_JRAINBOW2,
|
||||
bool &combine_crossair
|
||||
);
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFWVersion();
|
||||
std::string GetSerial();
|
||||
|
||||
private:
|
||||
bool ReadSettings();
|
||||
void SaveOnUpdate(bool send);
|
||||
bool ReadFwVersion();
|
||||
void ReadSerial();
|
||||
void ReadName();
|
||||
ZoneData* GetZoneData(MSI_ZONE zone);
|
||||
RainbowZoneData*
|
||||
GetRainbowZoneData(MSI_ZONE zone);
|
||||
static unsigned char BitSet(unsigned char value, bool bit, unsigned int position);
|
||||
|
||||
hid_device* dev;
|
||||
std::string name;
|
||||
std::string loc;
|
||||
std::string version_APROM;
|
||||
std::string version_LDROM;
|
||||
std::string chip_id;
|
||||
|
||||
FeaturePacket data;
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "MSIMysticLightController.h"
|
||||
#include "RGBController_MSIMysticLight.h"
|
||||
|
||||
#define MSI_USB_VID 0x1462
|
||||
|
||||
#define NUM_MSI_PIDS 41
|
||||
|
||||
static const unsigned short msi_pid_table[] =
|
||||
{
|
||||
0x3EA4, // MS_3EA4
|
||||
0x4559, // MS_4459
|
||||
|
||||
0x7B10, // MS_7B10
|
||||
0x7B93, // MSI B450 Gaming Pro Carbon AC
|
||||
0x7B94, // MS_7B94
|
||||
0x7B96, // MS_7B96
|
||||
|
||||
0x7C34, // MS_7C34
|
||||
0x7C35, // MS_7C35
|
||||
0x7C36, // MS_7C36
|
||||
0x7C37, // MS_7C37
|
||||
0x7C42, // MS_7C42
|
||||
0x7C56, // MS_7C56
|
||||
0x7C59, // MS_7C59
|
||||
0x7C60, // MS_7C60
|
||||
0x7C67, // MS_7C67
|
||||
0x7C70, // MS_7C70
|
||||
0x7C71, // MS_7C71
|
||||
0x7C73, // MS_7C73
|
||||
0x7C75, // MS_7C75
|
||||
0x7C76, // MS_7C76
|
||||
0x7C77, // MS_7C77
|
||||
0x7C79, // MS_7C79
|
||||
0x7C80, // MS_7C80
|
||||
0x7C81, // MS_7C81
|
||||
0x7C82, // MS_7C82
|
||||
0x7C83, // MS_7C83
|
||||
0x7C84, // MS_7C84
|
||||
0x7C85, // MS_7C85
|
||||
0x7C86, // MS_7C86
|
||||
0x7C87, // MS_7C87
|
||||
0x7C88, // MS_7C88
|
||||
0x7C89, // MS_7C89
|
||||
0x7C90, // MS_7C90
|
||||
0x7C91, // MS_7C91
|
||||
0x7C92, // MS_7C92
|
||||
0x7C94, // MS_7C94
|
||||
0x7C95, // MS_7C95
|
||||
0x7C96, // MS_7C96
|
||||
0x7C98, // MS_7C98
|
||||
0x7C99, // MS_7C99
|
||||
|
||||
0x905D // MS_905D
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectMSIMysticLightControllers *
|
||||
* *
|
||||
* Detect MSI Mystic Light devices that use NCT6775 RGB controllers *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectMSIMysticLightControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(int device_idx = 0; device_idx < NUM_MSI_PIDS; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(MSI_USB_VID, msi_pid_table[device_idx]);
|
||||
|
||||
//Look for MSI Mystic Light Controller
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == MSI_USB_VID)
|
||||
&&(info->product_id == msi_pid_table[device_idx]))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
MSIMysticLightController * controller = new MSIMysticLightController(dev, info->path);
|
||||
|
||||
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIRGBController.cpp |
|
||||
| |
|
||||
| Driver for MSI-RGB lighting controller |
|
||||
| |
|
||||
| Logic adapted from: |
|
||||
| https://github.com/nagisa/msi-rgb |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 2/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIRGBController.h"
|
||||
#include "super_io.h"
|
||||
|
||||
MSIRGBController::MSIRGBController(int sioaddr)
|
||||
{
|
||||
msi_sioaddr = sioaddr;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This setup step isn't well documented |
|
||||
| Without this, pulsing does not work |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, 0x09);
|
||||
|
||||
int val_at_2c = superio_inb(msi_sioaddr, 0x2C);
|
||||
|
||||
val_at_2c &= 0b11110111;
|
||||
val_at_2c |= 0b00010000;
|
||||
|
||||
superio_outb(msi_sioaddr, 0x2C, val_at_2c);
|
||||
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set logical device register to RGB controller |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Test if RGB is enabled. If it is not, enable it. |
|
||||
\*-----------------------------------------------------*/
|
||||
int enable = superio_inb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE);
|
||||
|
||||
if((enable & MSI_SIO_RGB_ENABLE_MASK) != MSI_SIO_RGB_ENABLE_MASK)
|
||||
{
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_ENABLE, MSI_SIO_RGB_ENABLE_MASK & (enable & !MSI_SIO_RGB_ENABLE_MASK));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Lighting enabled, no pulsing or blinking |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_1, 0x00);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Lighting enabled, RGB non-inverted, header on |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_CFG_3, 0xE2);
|
||||
}
|
||||
|
||||
MSIRGBController::~MSIRGBController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MSIRGBController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| The MSI RGB controller uses 4 bits per color rather |
|
||||
| than 8. Shift the values by 4 so that the 4 most |
|
||||
| significant bits of each color are the new color value|
|
||||
\*-----------------------------------------------------*/
|
||||
red = red >> 4;
|
||||
green = green >> 4;
|
||||
blue = blue >> 4;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set logical device register to RGB controller |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, SIO_REG_LOGDEV, MSI_SIO_LOGDEV_RGB);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Write the colors to the color sequence registers |
|
||||
| Only static mode is supported right now - all colors |
|
||||
| are the same. |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_1_0, (red | (red << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_3_2, (red | (red << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_5_4, (red | (red << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_RED_7_6, (red | (red << 4)));
|
||||
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_1_0, (green | (green << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_3_2, (green | (green << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_5_4, (green | (green << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_GREEN_7_6, (green | (green << 4)));
|
||||
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_1_0, (blue | (blue << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_3_2, (blue | (blue << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_5_4, (blue | (blue << 4)));
|
||||
superio_outb(msi_sioaddr, MSI_SIO_RGB_REG_BLUE_7_6, (blue | (blue << 4)));
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIRGBController.h |
|
||||
| |
|
||||
| Definitions and types for MSI-RGB |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Logic adapted from: |
|
||||
| https://github.com/nagisa/msi-rgb |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 2/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MSI_SIO_LOGDEV_RGB 0x12
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_SIO_RGB_REG_ENABLE = 0xE0,
|
||||
MSI_SIO_RGB_REG_CFG_1 = 0xE4,
|
||||
MSI_SIO_RGB_REG_RED_1_0 = 0xF0,
|
||||
MSI_SIO_RGB_REG_RED_3_2 = 0xF1,
|
||||
MSI_SIO_RGB_REG_RED_5_4 = 0xF2,
|
||||
MSI_SIO_RGB_REG_RED_7_6 = 0xF3,
|
||||
MSI_SIO_RGB_REG_GREEN_1_0 = 0xF4,
|
||||
MSI_SIO_RGB_REG_GREEN_3_2 = 0xF5,
|
||||
MSI_SIO_RGB_REG_GREEN_5_4 = 0xF6,
|
||||
MSI_SIO_RGB_REG_GREEN_7_6 = 0xF7,
|
||||
MSI_SIO_RGB_REG_BLUE_1_0 = 0xF8,
|
||||
MSI_SIO_RGB_REG_BLUE_3_2 = 0xF9,
|
||||
MSI_SIO_RGB_REG_BLUE_5_4 = 0xFA,
|
||||
MSI_SIO_RGB_REG_BLUE_7_6 = 0xFB,
|
||||
MSI_SIO_RGB_REG_CFG_2 = 0xFE,
|
||||
MSI_SIO_RGB_REG_CFG_3 = 0xFF,
|
||||
};
|
||||
|
||||
#define MSI_SIO_RGB_ENABLE_MASK 0xE0
|
||||
|
||||
class MSIRGBController
|
||||
{
|
||||
public:
|
||||
MSIRGBController(int sioaddr);
|
||||
~MSIRGBController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
unsigned int GetMode();
|
||||
void SetMode(unsigned char new_mode, unsigned char new_speed);
|
||||
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
private:
|
||||
int msi_sioaddr;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "MSIRGBController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_MSIRGB.h"
|
||||
#include "super_io.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectMSIRGBControllers *
|
||||
* *
|
||||
* Detect MSI-RGB compatible Super-IO chips. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectMSIRGBControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
int sio_addrs[2] = {0x2E, 0x4E};
|
||||
|
||||
for(int sioaddr_idx = 0; sioaddr_idx < 2; sioaddr_idx++)
|
||||
{
|
||||
int sioaddr = sio_addrs[sioaddr_idx];
|
||||
|
||||
superio_enter(sioaddr);
|
||||
|
||||
int val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1);
|
||||
|
||||
switch (val & SIO_ID_MASK)
|
||||
{
|
||||
case SIO_NCT6795_ID:
|
||||
case SIO_NCT6797_ID:
|
||||
MSIRGBController* new_msi = new MSIRGBController(sioaddr);
|
||||
RGBController_MSIRGB* new_rgb = new RGBController_MSIRGB(new_msi);
|
||||
|
||||
rgb_controllers.push_back(new_rgb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* DetectMSIRGBControllers() */
|
||||
@@ -0,0 +1,417 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Processing Code for NZXT Hue 2 |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 12/29/2016 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "NZXTHue2Controller.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
num_fan_channels = fan_channels;
|
||||
num_rgb_channels = rgb_channels;
|
||||
|
||||
SendFirmwareRequest();
|
||||
UpdateDeviceList();
|
||||
|
||||
fan_cmd.resize(num_fan_channels);
|
||||
fan_rpm.resize(num_fan_channels);
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
NZXTHue2Controller::~NZXTHue2Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned char NZXTHue2Controller::GetFanCommand
|
||||
(
|
||||
unsigned char fan_channel
|
||||
)
|
||||
{
|
||||
return(fan_cmd[fan_channel]);
|
||||
}
|
||||
|
||||
unsigned short NZXTHue2Controller::GetFanRPM
|
||||
(
|
||||
unsigned char fan_channel
|
||||
)
|
||||
{
|
||||
return(fan_rpm[fan_channel]);
|
||||
}
|
||||
|
||||
unsigned int NZXTHue2Controller::GetNumFanChannels()
|
||||
{
|
||||
return(num_fan_channels);
|
||||
}
|
||||
|
||||
unsigned int NZXTHue2Controller::GetNumRGBChannels()
|
||||
{
|
||||
return(num_rgb_channels);
|
||||
}
|
||||
|
||||
std::string NZXTHue2Controller::GetFirmwareVersion()
|
||||
{
|
||||
return(firmware_version);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendFan
|
||||
(
|
||||
unsigned char port,
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up RGB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x62;
|
||||
usb_buf[0x01] = 0x01;
|
||||
usb_buf[0x02] = 1 << port;
|
||||
usb_buf[port + 3] = speed;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::UpdateDeviceList()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Device Information Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x20;
|
||||
usb_buf[0x01] = 0x03;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Receive packets until 0x21 0x03 is received |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x21) || (usb_buf[1] != 0x03) );
|
||||
|
||||
for(int chan = 0; chan < num_rgb_channels; chan++)
|
||||
{
|
||||
unsigned int start = 0x0F + (6 * chan);
|
||||
unsigned int num_leds_on_channel = 0;
|
||||
for(int dev = 0; dev < 6; dev++)
|
||||
{
|
||||
switch(usb_buf[start + dev])
|
||||
{
|
||||
case 0x01: //Hue 1 strip
|
||||
num_leds_on_channel += 10;
|
||||
break;
|
||||
|
||||
case 0x02: //Aer 1 fan
|
||||
num_leds_on_channel += 8;
|
||||
break;
|
||||
|
||||
case 0x04: //Hue 2 strip
|
||||
num_leds_on_channel += 10;
|
||||
break;
|
||||
|
||||
case 0x0B: //Aer 2 fan (120mm)
|
||||
num_leds_on_channel += 8;
|
||||
break;
|
||||
|
||||
case 0x0C: //Aer 2 fan (140mm)
|
||||
num_leds_on_channel += 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
channel_leds[chan] = num_leds_on_channel;
|
||||
}
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::UpdateStatus()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
if(false)//num_fan_channels > 0)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x67) || (usb_buf[1] != 0x02) );
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract fan information |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int fan_idx = 0; fan_idx < num_fan_channels; fan_idx++)
|
||||
{
|
||||
unsigned char cmd;
|
||||
unsigned short rpm;
|
||||
|
||||
cmd = usb_buf[40 + fan_idx];
|
||||
rpm = ( usb_buf[25 + (2 * fan_idx)] << 8 ) | usb_buf[24 + (2 * fan_idx)];
|
||||
|
||||
fan_cmd[fan_idx] = cmd;
|
||||
fan_rpm[fan_idx] = rpm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SetChannelEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
)
|
||||
{
|
||||
unsigned char color_data[24];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data (up to 8 colors) |
|
||||
\*-----------------------------------------------------*/
|
||||
for (std::size_t idx = 0; idx < num_colors; idx++)
|
||||
{
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send effect packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendEffect(channel, mode, speed, direction, num_colors, &color_data[0]);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
)
|
||||
{
|
||||
unsigned char color_data[120];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data (up to 40 colors) |
|
||||
\*-----------------------------------------------------*/
|
||||
for (std::size_t idx = 0; idx < num_colors; idx++)
|
||||
{
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send first group of color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SendDirect(channel, 0, 20, &color_data[0]);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send second group of color data if necessary |
|
||||
\*-----------------------------------------------------*/
|
||||
if(num_colors > 20)
|
||||
{
|
||||
SendDirect(channel, 1, 20, &color_data[60]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send apply packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendApply(channel);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void NZXTHue2Controller::SendApply
|
||||
(
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Apply packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x22;
|
||||
usb_buf[0x01] = 0xA0;
|
||||
usb_buf[0x02] = (unsigned char)(1 << channel);
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x07] = 0x28;
|
||||
usb_buf[0x0A] = 0x80;
|
||||
usb_buf[0x0C] = 0x32;
|
||||
usb_buf[0x0F] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendDirect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char group,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x22;
|
||||
usb_buf[0x01] = 0x10 | group;
|
||||
usb_buf[0x02] = (unsigned char)(1 << channel);
|
||||
usb_buf[0x03] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], color_data, color_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Effect packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x28;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = (unsigned char)(1 << channel);
|
||||
usb_buf[0x03] = 0x28;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set mode in USB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set speed in USB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x05] = speed;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set direction in USB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = direction ? 0x01 : 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set color count in USB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x08] = color_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x0A], color_data, color_count * 3);
|
||||
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendFirmwareRequest()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Firmware Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x10;
|
||||
usb_buf[0x01] = 0x01;
|
||||
|
||||
hid_write(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Receive packets until 0x11 0x01 is received |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x11) || (usb_buf[1] != 0x01) );
|
||||
|
||||
snprintf(firmware_version, 16, "%u.%u.%u", usb_buf[0x11], usb_buf[0x12], usb_buf[0x13]);
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for NZXT Hue 2 |
|
||||
| |
|
||||
| Adam Honse ([email protected]), 12/29/2016 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_2_CHANNEL_ALL = 0x00, /* All channels */
|
||||
HUE_2_CHANNEL_1 = 0x01, /* Channel 1 */
|
||||
HUE_2_CHANNEL_2 = 0x02, /* Channel 2 */
|
||||
HUE_2_CHANNEL_3 = 0x03, /* Channel 3 */
|
||||
HUE_2_CHANNEL_4 = 0x04, /* Channel 4 */
|
||||
HUE_2_NUM_CHANNELS = 0x04 /* Number of channels */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_2_CHANNEL_1_IDX = 0x00, /* Channel 1 array index */
|
||||
HUE_2_CHANNEL_2_IDX = 0x01, /* Channel 2 array index */
|
||||
HUE_2_CHANNEL_3_IDX = 0x01, /* Channel 3 array index */
|
||||
HUE_2_CHANNEL_4_IDX = 0x01, /* Channel 4 array index */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_2_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
HUE_2_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
HUE_2_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
HUE_2_SPEED_FAST = 0x03, /* Fast speed */
|
||||
HUE_2_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HUE_2_MODE_FIXED = 0x00, /* Fixed colors mode */
|
||||
HUE_2_MODE_FADING = 0x01, /* Fading mode */
|
||||
HUE_2_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
|
||||
HUE_2_MODE_MARQUEE = 0x03, /* Marquee mode */
|
||||
HUE_2_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
|
||||
HUE_2_MODE_ALTERNATING = 0x05, /* Alternating mode */
|
||||
HUE_2_MODE_PULSING = 0x06, /* Pulsing mode */
|
||||
HUE_2_MODE_BREATHING = 0x07, /* Breathing mode */
|
||||
HUE_2_NUM_MODES /* Number of Hue 2 modes */
|
||||
};
|
||||
|
||||
class NZXTHue2Controller
|
||||
{
|
||||
public:
|
||||
NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels);
|
||||
~NZXTHue2Controller();
|
||||
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
unsigned char GetFanCommand
|
||||
(
|
||||
unsigned char fan_channel
|
||||
);
|
||||
|
||||
unsigned short GetFanRPM
|
||||
(
|
||||
unsigned char fan_channel
|
||||
);
|
||||
|
||||
unsigned int GetNumFanChannels();
|
||||
|
||||
unsigned int GetNumRGBChannels();
|
||||
|
||||
void SendFan
|
||||
(
|
||||
unsigned char port,
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
);
|
||||
|
||||
void SetChannelEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void UpdateDeviceList();
|
||||
|
||||
void UpdateStatus();
|
||||
|
||||
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
std::vector<unsigned char> fan_cmd;
|
||||
std::vector<unsigned short> fan_rpm;
|
||||
|
||||
char firmware_version[16];
|
||||
unsigned int num_fan_channels;
|
||||
unsigned int num_rgb_channels;
|
||||
|
||||
void SendApply
|
||||
(
|
||||
unsigned char channel
|
||||
);
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char group,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
bool direction,
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendFirmwareRequest();
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "NZXTHue2Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_NZXTHue2.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define NZXT_VID 0x1E71
|
||||
#define NZXT_HUE_2_PID 0x2001
|
||||
#define NZXT_HUE_2_AMBIENT_PID 0x2002
|
||||
#define NZXT_SMART_DEVICE_V2_PID 0x2006
|
||||
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned int num_rgb_channels;
|
||||
unsigned int num_fan_channels;
|
||||
const char * name;
|
||||
} nzxt_hue_2_device;
|
||||
|
||||
#define NZXT_HUE_2_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const nzxt_hue_2_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| NZXT Hue 2 devices |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ NZXT_VID, NZXT_HUE_2_PID, 4, 0, "NZXT Hue 2" },
|
||||
{ NZXT_VID, NZXT_HUE_2_AMBIENT_PID, 2, 0, "NZXT Hue 2 Ambient" },
|
||||
{ NZXT_VID, NZXT_SMART_DEVICE_V2_PID, 2, 3, "NZXT Smart Device V2" },
|
||||
{ NZXT_VID, NZXT_RGB_FAN_CONTROLLER_PID, 2, 3, "NZXT RGB & Fan Controller" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectNZXTHue2Controllers *
|
||||
* *
|
||||
* Detect devices supported by the NZXT Hue 2 driver *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectNZXTHue2Controllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < NZXT_HUE_2_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for NZXT Hue 2 devices
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
NZXTHue2Controller* controller = new NZXTHue2Controller(dev, device_list[device_idx].num_rgb_channels, device_list[device_idx].num_fan_channels);
|
||||
|
||||
RGBController_NZXTHue2* rgb_controller = new RGBController_NZXTHue2(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
} /* DetectNZXTHue2Controllers() */
|
||||
@@ -0,0 +1,174 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Driver for NZXT Kraken |
|
||||
| |
|
||||
| Martin Hartl (inlart), 04/04/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "NZXTKrakenController.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
static void SetColor(const std::vector<RGBColor>& colors, unsigned char* color_data)
|
||||
{
|
||||
for (std::size_t idx = 0; idx < colors.size(); idx++)
|
||||
{
|
||||
int pixel_idx = idx * 3;
|
||||
RGBColor color = colors[idx];
|
||||
color_data[pixel_idx + 0x00] = RGBGetRValue(color);
|
||||
color_data[pixel_idx + 0x01] = RGBGetGValue(color);
|
||||
color_data[pixel_idx + 0x02] = RGBGetBValue(color);
|
||||
}
|
||||
}
|
||||
|
||||
static RGBColor ToLogoColor(RGBColor rgb)
|
||||
{
|
||||
return ToRGBColor(RGBGetGValue(rgb), RGBGetRValue(rgb), RGBGetBValue(rgb));
|
||||
}
|
||||
|
||||
NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the firmware version |
|
||||
\*-----------------------------------------------------*/
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
NZXTKrakenController::~NZXTKrakenController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string NZXTKrakenController::GetFirmwareVersion()
|
||||
{
|
||||
return firmware_version;
|
||||
}
|
||||
|
||||
void NZXTKrakenController::UpdateStatus()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract cooler information |
|
||||
\*-----------------------------------------------------*/
|
||||
liquid_temperature = usb_buf[0x1] + (usb_buf[0x2] * 0.1);
|
||||
fan_speed = usb_buf[0x3] << 8 | usb_buf[0x4];
|
||||
pump_speed = usb_buf[0x5] << 8 | usb_buf[0x6];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract firmware version |
|
||||
\*-----------------------------------------------------*/
|
||||
int major = usb_buf[0xb];
|
||||
int minor = usb_buf[0xc] << 8 | usb_buf[0xd];
|
||||
int patch = usb_buf[0xe];
|
||||
std::stringstream ss;
|
||||
ss << major << '.' << minor << '.' << patch;
|
||||
firmware_version = ss.str();
|
||||
}
|
||||
|
||||
void NZXTKrakenController::UpdateEffect
|
||||
(
|
||||
NZXTKrakenChannel_t channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char speed,
|
||||
int seq,
|
||||
std::vector<RGBColor> colors
|
||||
)
|
||||
{
|
||||
unsigned char color_data[9 * 3];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(color_data, 0, sizeof(color_data));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!colors.empty() && channel != NZXT_KRAKEN_CHANNEL_RING)
|
||||
{
|
||||
colors[0] = ToLogoColor(colors[0]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SetColor(colors, color_data);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send update packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendEffect(channel, mode, direction, color_data, speed, false, seq);
|
||||
}
|
||||
|
||||
void NZXTKrakenController::SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char* color_data,
|
||||
unsigned char speed /* = 0x02 */,
|
||||
bool movement /* = false */,
|
||||
int cis /* = 0 */,
|
||||
int size /* = 0 */
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set effect mode |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x02;
|
||||
usb_buf[0x01] = 0x4c;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set effect channel, movement and direction |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x02] |= movement ? ( 1 << 3 ) : 0;
|
||||
usb_buf[0x02] |= direction ? ( 1 << 4 ) : 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set mode |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set effect speed, size and color in set |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = speed;
|
||||
usb_buf[0x04] |= size << 3;
|
||||
usb_buf[0x04] |= cis << 5;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
if(color_data)
|
||||
{
|
||||
memcpy(usb_buf + 0x05, color_data, 9 * 3);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send effect |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Definitions for NZXT Kraken |
|
||||
| |
|
||||
| Martin Hartl (inlart), 04/04/2020 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
enum NZXTKrakenChannel_t
|
||||
{
|
||||
NZXT_KRAKEN_CHANNEL_SYNC = 0x00, /* Sync Channel */
|
||||
NZXT_KRAKEN_CHANNEL_LOGO = 0x01, /* Logo Channel */
|
||||
NZXT_KRAKEN_CHANNEL_RING = 0x02, /* Ring Channel */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NZXT_KRAKEN_MODE_FIXED = 0x00, /* Fixed colors mode */
|
||||
NZXT_KRAKEN_MODE_FADING = 0x01, /* Fading mode */
|
||||
NZXT_KRAKEN_MODE_SPECTRUM = 0x02, /* Spectrum cycle mode */
|
||||
NZXT_KRAKEN_MODE_MARQUEE = 0x03, /* Marquee mode */
|
||||
NZXT_KRAKEN_MODE_COVER_MARQUEE = 0x04, /* Cover marquee mode */
|
||||
NZXT_KRAKEN_MODE_ALTERNATING = 0x05, /* Alternating mode */
|
||||
NZXT_KRAKEN_MODE_BREATHING = 0x06, /* Breathing mode */
|
||||
NZXT_KRAKEN_MODE_PULSE = 0x07, /* Pulse mode */
|
||||
NZXT_KRAKEN_MODE_TAI_CHI = 0x08, /* Tai Chi mode */
|
||||
NZXT_KRAKEN_MODE_WATER_COOLER = 0x09, /* Water color mode */
|
||||
NZXT_KRAKEN_MODE_LOADING = 0x0a, /* Loading mode */
|
||||
NZXT_KRAKEN_MODE_WINGS = 0x0c, /* Wings mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NZXT_KRAKEN_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
NZXT_KRAKEN_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
NZXT_KRAKEN_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
NZXT_KRAKEN_SPEED_FAST = 0x03, /* Fast speed */
|
||||
NZXT_KRAKEN_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class NZXTKrakenController
|
||||
{
|
||||
public:
|
||||
NZXTKrakenController(hid_device* dev_handle);
|
||||
~NZXTKrakenController();
|
||||
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void UpdateEffect
|
||||
(
|
||||
NZXTKrakenChannel_t channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char speed,
|
||||
int seq,
|
||||
std::vector<RGBColor> colors
|
||||
);
|
||||
|
||||
private:
|
||||
void UpdateStatus();
|
||||
|
||||
void SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
bool direction,
|
||||
unsigned char* color_data,
|
||||
unsigned char speed = 0x02,
|
||||
bool movement = false,
|
||||
int cis = 0 ,
|
||||
int size = 0
|
||||
);
|
||||
|
||||
hid_device* dev;
|
||||
|
||||
// -- status
|
||||
std::string firmware_version;
|
||||
double liquid_temperature;
|
||||
unsigned int fan_speed;
|
||||
unsigned int pump_speed;
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "NZXTKrakenController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_NZXTKraken.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define NZXT_KRAKEN_VID 0x1E71
|
||||
#define NZXT_KRAKEN_PID 0x170E
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectNZXTKrakenControllers *
|
||||
* *
|
||||
* Detect devices supported by the NZXTKraken driver *
|
||||
* * *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectNZXTKrakenControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < 1; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
|
||||
|
||||
//Look for NZXT Kraken devices
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == NZXT_KRAKEN_VID)
|
||||
&&(info->product_id == NZXT_KRAKEN_PID))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
NZXTKrakenController* controller = new NZXTKrakenController(dev);
|
||||
|
||||
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*-----------------------------------------*\
|
||||
| PatriotViperController.cpp |
|
||||
| |
|
||||
| Definitions and types for Patriot Viper |
|
||||
| RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/1/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "PatriotViperController.h"
|
||||
#include <cstring>
|
||||
|
||||
PatriotViperController::PatriotViperController(i2c_smbus_interface* bus, viper_dev_id dev, unsigned char slots)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
slots_valid = slots;
|
||||
|
||||
strcpy(device_name, "Patriot Viper RGB");
|
||||
|
||||
led_count = 0;
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
if((slots_valid & (1 << i)) != 0)
|
||||
{
|
||||
led_count += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatriotViperController::~PatriotViperController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string PatriotViperController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string PatriotViperController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned int PatriotViperController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
unsigned int PatriotViperController::GetSlotCount()
|
||||
{
|
||||
unsigned int slot_count = 0;
|
||||
|
||||
for(int slot = 0; slot < 4; slot++)
|
||||
{
|
||||
if((slots_valid & (1 << slot)) != 0)
|
||||
{
|
||||
slot_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return(slot_count);
|
||||
}
|
||||
|
||||
unsigned int PatriotViperController::GetMode()
|
||||
{
|
||||
return(mode);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetEffectColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED1_EFFECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED2_EFFECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED3_EFFECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED4_EFFECT_COLOR, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED1_DIRECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED2_DIRECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED3_DIRECT_COLOR, red, blue, green);
|
||||
ViperRegisterWrite(VIPER_REG_LED4_DIRECT_COLOR, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetLEDEffectColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetLEDColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_DIRECT_COLOR + led, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetLEDEffectColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_LED0_EFFECT_COLOR + led, red, blue, green);
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetMode(unsigned char new_mode, unsigned char new_speed)
|
||||
{
|
||||
direct = false;
|
||||
mode = new_mode;
|
||||
speed = new_speed;
|
||||
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, mode, 0x00, speed);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xAA, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_MODE, 0xFA, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::SetDirect()
|
||||
{
|
||||
direct = true;
|
||||
ViperRegisterWrite(VIPER_REG_START, 0xFF, 0xFF, 0xFF);
|
||||
ViperRegisterWrite(VIPER_REG_STATIC, 0x04, 0x00, 0x00);
|
||||
ViperRegisterWrite(VIPER_REG_APPLY, 0x01, 0x00, 0x00);
|
||||
}
|
||||
|
||||
void PatriotViperController::ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val0);
|
||||
bus->i2c_smbus_write_byte_data(dev, val2, val1);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*-----------------------------------------*\
|
||||
| PatriotViperController.h |
|
||||
| |
|
||||
| Definitions and types for Patriot Viper |
|
||||
| RGB RAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 1/1/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char viper_dev_id;
|
||||
typedef unsigned short viper_register;
|
||||
|
||||
enum
|
||||
{
|
||||
VIPER_REG_STATIC = 0x01, /* Set static mode */
|
||||
VIPER_REG_MODE = 0x03, /* Mode register */
|
||||
VIPER_REG_LED0_DIRECT_COLOR = 0x30, /* LED 0 Color (R, B, G) */
|
||||
VIPER_REG_LED1_DIRECT_COLOR = 0x31, /* LED 1 Color (R, B, G) */
|
||||
VIPER_REG_LED2_DIRECT_COLOR = 0x32, /* LED 2 Color (R, B, G) */
|
||||
VIPER_REG_LED3_DIRECT_COLOR = 0x33, /* LED 3 Color (R, B, G) */
|
||||
VIPER_REG_LED4_DIRECT_COLOR = 0x34, /* LED 4 Color (R, B, G) */
|
||||
VIPER_REG_APPLY = 0x35, /* Apply Changes (0x01, 0x00, 0x00) */
|
||||
VIPER_REG_LED0_EFFECT_COLOR = 0x3B, /* LED 0 Color (R, B, G) */
|
||||
VIPER_REG_LED1_EFFECT_COLOR = 0x3C, /* LED 1 Color (R, B, G) */
|
||||
VIPER_REG_LED2_EFFECT_COLOR = 0x3D, /* LED 2 Color (R, B, G) */
|
||||
VIPER_REG_LED3_EFFECT_COLOR = 0x3E, /* LED 3 Color (R, B, G) */
|
||||
VIPER_REG_LED4_EFFECT_COLOR = 0x3F, /* LED 4 Color (R, B, G) */
|
||||
VIPER_REG_START = 0xFF, /* Start Frame (0xFF, 0xFF, 0xFF) */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VIPER_MODE_DARK = 0x00, /* Dark mode */
|
||||
VIPER_MODE_BREATHING = 0x01, /* Breathing mode */
|
||||
VIPER_MODE_VIPER = 0x02, /* Viper mode */
|
||||
VIPER_MODE_HEARTBEAT = 0x03, /* Heartbeat mode */
|
||||
VIPER_MODE_MARQUEE = 0x04, /* Marquee mode */
|
||||
VIPER_MODE_RAINDROP = 0x05, /* Raindrop mode */
|
||||
VIPER_MODE_AURORA = 0x06, /* Aurora mode */
|
||||
VIPER_MODE_NEON = 0x08, /* Neon mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VIPER_SPEED_MIN = 0xC8, /* Slowest speed for non-breathing mode */
|
||||
VIPER_SPEED_DEFAULT = 0x64, /* Default speed for non-breathing mode */
|
||||
VIPER_SPEED_MAX = 0x14, /* Fastest speed for non-breathing mode */
|
||||
VIPER_SPEED_BREATHING_MIN = 0xFF, /* Slowest speed for breathing mode */
|
||||
VIPER_SPEED_BREATHING_DEFAULT = 0x0C, /* Default speed for breathing mode */
|
||||
VIPER_SPEED_BREATHING_MAX = 0x00, /* Fastest speed for breathing mode */
|
||||
};
|
||||
|
||||
class PatriotViperController
|
||||
{
|
||||
public:
|
||||
PatriotViperController(i2c_smbus_interface* bus, viper_dev_id dev, unsigned char slots);
|
||||
~PatriotViperController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
unsigned int GetSlotCount();
|
||||
unsigned int GetMode();
|
||||
void SetMode(unsigned char new_mode, unsigned char new_speed);
|
||||
void SetDirect();
|
||||
|
||||
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetEffectColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDEffectColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDEffectColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
void ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2);
|
||||
bool direct;
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
unsigned char slots_valid;
|
||||
i2c_smbus_interface* bus;
|
||||
viper_dev_id dev;
|
||||
unsigned char mode;
|
||||
unsigned char speed;
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "PatriotViperController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_PatriotViper.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectPatriotViperControllers *
|
||||
* *
|
||||
* Detect Patriot Viper RGB controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Aura device is connected *
|
||||
* dev - I2C address of Aura device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
PatriotViperController* new_viper;
|
||||
RGBController_PatriotViper* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
unsigned char slots_valid = 0x00;
|
||||
|
||||
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
|
||||
{
|
||||
// Test for Patriot Viper RGB SPD at slot_addr
|
||||
// This test was copied from Viper RGB software
|
||||
// Tests SPD addresses in order: 0x00, 0x40, 0x41, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x36, 0x00, 0xFF);
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
if(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x00) == 0x23)
|
||||
{
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x85)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x02)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x61) == 0x4D)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x62) == 0x49)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x63) == 0x43)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x64) == 0x53)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x65) == 0x59)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x66) == 0x53)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x67) == 0x5f)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x68) == 0x44))
|
||||
{
|
||||
slots_valid |= (1 << (slot_addr - 0x50));
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
if(slots_valid != 0)
|
||||
{
|
||||
new_viper = new PatriotViperController(busses[bus], 0x77, slots_valid);
|
||||
new_controller = new RGBController_PatriotViper(new_viper);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectPatriotViperControllers() */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user