Compare commits
723 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01b6e645b3 | ||
|
|
db8c41cdaa | ||
|
|
b0fe84070f | ||
|
|
4d91d2baff | ||
|
|
c6fdb637ca | ||
|
|
bdd9e48606 | ||
|
|
25a7544010 | ||
|
|
821ad23341 | ||
|
|
981c986b3f | ||
|
|
09b3e47ac8 | ||
|
|
d2684f66a1 | ||
|
|
964381854e | ||
|
|
d8670fbd87 | ||
|
|
3c81ac91df | ||
|
|
147c82e0e2 | ||
|
|
339ce2d861 | ||
|
|
a7f0701cbf | ||
|
|
65b3b87c99 | ||
|
|
8d3700b76b | ||
|
|
d2595a00b6 | ||
|
|
c4bf129d5e | ||
|
|
503f4d4cd6 | ||
|
|
31d6c7d85d | ||
|
|
9a17ca2628 | ||
|
|
49bcaf3914 | ||
|
|
82d0346615 | ||
|
|
808da1bce0 | ||
|
|
6992ece762 | ||
|
|
734e70b755 | ||
|
|
681182540e | ||
|
|
9c29ee437a | ||
|
|
785baad5ea | ||
|
|
91b08f10fd | ||
|
|
c801ef8dda | ||
|
|
b47c01981f | ||
|
|
7e4c71748f | ||
|
|
a1910156d8 | ||
|
|
99d15eaac8 | ||
|
|
e31d6446db | ||
|
|
05ce867064 | ||
|
|
609a76045a | ||
|
|
000ea3096a | ||
|
|
0160df7fb9 | ||
|
|
05c989a1ce | ||
|
|
ebefd1c2d3 | ||
|
|
983d661da5 | ||
|
|
da08d00d21 | ||
|
|
6bd4c31965 | ||
|
|
af7bee2231 | ||
|
|
d61be73bca | ||
|
|
768b3ba2d9 | ||
|
|
0ff121284a | ||
|
|
bcc2512cb6 | ||
|
|
a2d18f0848 | ||
|
|
7fb10b0242 | ||
|
|
bcec028b0f | ||
|
|
8f9d52aa89 | ||
|
|
d368b93fdd | ||
|
|
d5322f384b | ||
|
|
03d027615c | ||
|
|
7fbab0122d | ||
|
|
f3f5687bc8 | ||
|
|
bbffcc20d7 | ||
|
|
197ed8c319 | ||
|
|
9363494c3f | ||
|
|
d8d32f7932 | ||
|
|
d575586d77 | ||
|
|
4326dcdc6c | ||
|
|
792a3511da | ||
|
|
9ba867f19e | ||
|
|
49943ee46f | ||
|
|
2a8c58af31 | ||
|
|
66cf88b967 | ||
|
|
f61e284ac0 | ||
|
|
9d69c9bd3f | ||
|
|
9258025eea | ||
|
|
063abb3e23 | ||
|
|
f5ec4a3a37 | ||
|
|
e9edcfeeb0 | ||
|
|
4b7e1f699d | ||
|
|
134f3dac52 | ||
|
|
1afb1a50c3 | ||
|
|
4914ce1d49 | ||
|
|
70a06a6cae | ||
|
|
5044f014bf | ||
|
|
7c72c9777a | ||
|
|
73df5e6743 | ||
|
|
9cf0b0f484 | ||
|
|
9541d1bbd3 | ||
|
|
3e15eb44ab | ||
|
|
bf89d9b841 | ||
|
|
d8995ee9c0 | ||
|
|
42f86cf82c | ||
|
|
a704679990 | ||
|
|
5876e1765d | ||
|
|
dcdf687a07 | ||
|
|
e94bd23d6f | ||
|
|
cd5b93feb1 | ||
|
|
f231173ebe | ||
|
|
561a96c62a | ||
|
|
57e6623d74 | ||
|
|
57623acc99 | ||
|
|
4f8d29d0b7 | ||
|
|
8eda2d805f | ||
|
|
432d4a4ffa | ||
|
|
539caf3d83 | ||
|
|
ce6926c36c | ||
|
|
8058d550ab | ||
|
|
9a21ff6976 | ||
|
|
1f4f41b6e6 | ||
|
|
a959196c2a | ||
|
|
3f22601022 | ||
|
|
a80a7ecba9 | ||
|
|
7c450f4a5f | ||
|
|
6316d3076d | ||
|
|
7181683d8e | ||
|
|
7d7134dd9e | ||
|
|
c29db97f73 | ||
|
|
05833bb38c | ||
|
|
253de81a6b | ||
|
|
21e6a0cf7e | ||
|
|
d0fefabad7 | ||
|
|
44db160ab1 | ||
|
|
cb633a8f32 | ||
|
|
66b7130641 | ||
|
|
80d9718770 | ||
|
|
dfbbca4c9f | ||
|
|
f4d08b2d9b | ||
|
|
588a834ae4 | ||
|
|
833dda7e7c | ||
|
|
6a4ab55930 | ||
|
|
d7ce2a81db | ||
|
|
4d90fa4830 | ||
|
|
501fdda138 | ||
|
|
678e8d34e3 | ||
|
|
07d1982abf | ||
|
|
fd05f83636 | ||
|
|
94e119fb51 | ||
|
|
c2ff4bf623 | ||
|
|
faf5651607 | ||
|
|
978e8344cf | ||
|
|
160d6eacc0 | ||
|
|
075d8e6393 | ||
|
|
28008ac7ac | ||
|
|
345d36287e | ||
|
|
edff6c551d | ||
|
|
d42a94f148 | ||
|
|
c01b8aa89c | ||
|
|
4958bd6a52 | ||
|
|
46038032a4 | ||
|
|
f66ddca100 | ||
|
|
6981c59de3 | ||
|
|
f21f13b15d | ||
|
|
ef5a01433d | ||
|
|
0e12d8545b | ||
|
|
9dbf745649 | ||
|
|
e8f73a42b8 | ||
|
|
dbe431095a | ||
|
|
513f77a2ad | ||
|
|
e8cf85bd65 | ||
|
|
be23d1fa15 | ||
|
|
4e7e5081a7 | ||
|
|
fff750e609 | ||
|
|
38ce46a158 | ||
|
|
7a27a7b3b5 | ||
|
|
c6ec175045 | ||
|
|
3b9ab66cf1 | ||
|
|
b6e458e97b | ||
|
|
c5152f6a9d | ||
|
|
e5689cfe57 | ||
|
|
f3f1d4d4f0 | ||
|
|
796b15a861 | ||
|
|
add351289a | ||
|
|
a4a056128a | ||
|
|
6e314933d9 | ||
|
|
a31bedda97 | ||
|
|
a25c82a8ce | ||
|
|
8ccc47dfa5 | ||
|
|
9de5a4ba66 | ||
|
|
84e437ae5b | ||
|
|
9e34c5995d | ||
|
|
497bbdf3cd | ||
|
|
8683a0ff58 | ||
|
|
874c801772 | ||
|
|
eea5463a5c | ||
|
|
af790aeaf8 | ||
|
|
a8a45b215a | ||
|
|
38f456a2ee | ||
|
|
a980eac647 | ||
|
|
ea83566fc9 | ||
|
|
0857d7ff0e | ||
|
|
48e98ab8c9 | ||
|
|
8cd438146d | ||
|
|
a80cc0ae2c | ||
|
|
2428736bfa | ||
|
|
a7bf8bf118 | ||
|
|
8038e1faa9 | ||
|
|
15a7e49dde | ||
|
|
8b30bd4b57 | ||
|
|
63d03303a2 | ||
|
|
0e40fef049 | ||
|
|
1a50425475 | ||
|
|
8fc5267110 | ||
|
|
f6a3b2c9ac | ||
|
|
7aa1e77642 | ||
|
|
2370ca0a44 | ||
|
|
abcf7f6f57 | ||
|
|
d1f0ea3de7 | ||
|
|
dbc8f4a4c2 | ||
|
|
c6c396ce2a | ||
|
|
74b91b0085 | ||
|
|
53c9ca8072 | ||
|
|
13e5216a4e | ||
|
|
147ccd3070 | ||
|
|
dc5c26e7c6 | ||
|
|
4914af1200 | ||
|
|
b57d26e99a | ||
|
|
f196b8bb0e | ||
|
|
7b460f7e56 | ||
|
|
9daa14abec | ||
|
|
bf8fd9a33b | ||
|
|
1f37b96359 | ||
|
|
46921aca22 | ||
|
|
41f96d4305 | ||
|
|
0959dc3a2d | ||
|
|
31baf3d19a | ||
|
|
f4696da0ef | ||
|
|
83ab79c51e | ||
|
|
745ac609d2 | ||
|
|
0f9aa51afe | ||
|
|
9fbb28e887 | ||
|
|
adf2045896 | ||
|
|
1a797bf93a | ||
|
|
1a9372b4ce | ||
|
|
87b91174ec | ||
|
|
26fff275ce | ||
|
|
53b44a525d | ||
|
|
8ce5d55eb8 | ||
|
|
afb749560a | ||
|
|
7a66e0298a | ||
|
|
e491a4cf57 | ||
|
|
b7789f1edb | ||
|
|
4949331f4c | ||
|
|
2c695e9a96 | ||
|
|
faaf801534 | ||
|
|
3fa775e3ad | ||
|
|
6663330de3 | ||
|
|
ed916360eb | ||
|
|
e4bc5c41ce | ||
|
|
d0d943c9c3 | ||
|
|
60b629e57f | ||
|
|
df80339060 | ||
|
|
cbbd427d3a | ||
|
|
dfcdb2e1e6 | ||
|
|
11ca6caf5f | ||
|
|
15afdf53e4 | ||
|
|
d15f958b48 | ||
|
|
5fd3bdede7 | ||
|
|
e2dd218f33 | ||
|
|
a85891ae00 | ||
|
|
2628044ba8 | ||
|
|
e620783a89 | ||
|
|
2fba9848ae | ||
|
|
52c65661d8 | ||
|
|
601c85c23e | ||
|
|
9d79f39897 | ||
|
|
2a7a3452ba | ||
|
|
f1386c60af | ||
|
|
b6ec217484 | ||
|
|
ad560b650e | ||
|
|
14a048a496 | ||
|
|
ba984d02eb | ||
|
|
fce59fba43 | ||
|
|
685663dcf6 | ||
|
|
cb61e856ad | ||
|
|
5b8fb9fb6b | ||
|
|
8249d9e1a2 | ||
|
|
4a152504cb | ||
|
|
b8eff953c6 | ||
|
|
cf1f94662c | ||
|
|
d4d6730c20 | ||
|
|
d287d40208 | ||
|
|
7e5e365f18 | ||
|
|
7bebec1304 | ||
|
|
2aa1ce5390 | ||
|
|
aaaf470dcf | ||
|
|
cf175fc00d | ||
|
|
c13eabcde8 | ||
|
|
8e45fcc069 | ||
|
|
d1e3a0fdff | ||
|
|
19ddff299a | ||
|
|
0954eb2b09 | ||
|
|
0a9931ddb3 | ||
|
|
0ccea3aa83 | ||
|
|
a1188505e8 | ||
|
|
2424ecc4f0 | ||
|
|
202540c7f7 | ||
|
|
1ceb380f6f | ||
|
|
da0cdf1bd0 | ||
|
|
708863358e | ||
|
|
a862b85a46 | ||
|
|
495907b8a4 | ||
|
|
f9a1935762 | ||
|
|
8ef9f888f6 | ||
|
|
9b3e9724b7 | ||
|
|
8880dfab24 | ||
|
|
5ffbbf40a5 | ||
|
|
a36fec5696 | ||
|
|
7acad84932 | ||
|
|
8d2230dc51 | ||
|
|
528ddbe12c | ||
|
|
e4c0756ded | ||
|
|
1c9efa327c | ||
|
|
fbbfeb2d1c | ||
|
|
ccaf49bece | ||
|
|
147fed39c8 | ||
|
|
d0a73bdc72 | ||
|
|
29dc122dd4 | ||
|
|
293c47774d | ||
|
|
795ed8aadc | ||
|
|
377825d4fb | ||
|
|
b89bb35054 | ||
|
|
caae685fab | ||
|
|
bd4517abab | ||
|
|
095b234fce | ||
|
|
b1c09f8a9c | ||
|
|
cabaa6cfb8 | ||
|
|
94486873c1 | ||
|
|
89a4eadab0 | ||
|
|
55395ea4fd | ||
|
|
4166a3c128 | ||
|
|
cabb8cd33a | ||
|
|
ab7a81081c | ||
|
|
8a352bdfe2 | ||
|
|
721e926a75 | ||
|
|
0b314d7f21 | ||
|
|
8305058cf5 | ||
|
|
6dddb968fa | ||
|
|
d3c318d0c9 | ||
|
|
604ec4416d | ||
|
|
c7fcea5f35 | ||
|
|
a84f1e5ee5 | ||
|
|
6a4161fdc4 | ||
|
|
e45ffab5d8 | ||
|
|
669e42960c | ||
|
|
55568b037f | ||
|
|
b5df428e43 | ||
|
|
1c19a69e35 | ||
|
|
67a03bbd85 | ||
|
|
32955380c7 | ||
|
|
93b4514343 | ||
|
|
68d57861cd | ||
|
|
485edb4883 | ||
|
|
bbc3f41493 | ||
|
|
5a6608dff4 | ||
|
|
8f222fd0bd | ||
|
|
1f5b371608 | ||
|
|
ce156ab4e7 | ||
|
|
94235dd005 | ||
|
|
cb471162d2 | ||
|
|
9d1c0ce308 | ||
|
|
27b1f0e843 | ||
|
|
dae7be8ec4 | ||
|
|
2f5b52223c | ||
|
|
bf222290b8 | ||
|
|
d825be5eb2 | ||
|
|
9da0e0358b | ||
|
|
216d97aada | ||
|
|
e3421fd44e | ||
|
|
85d43147ee | ||
|
|
e3e5dab0fc | ||
|
|
8b837dd81b | ||
|
|
8f7bdd45b1 | ||
|
|
0142ac1697 | ||
|
|
e8fb6624c0 | ||
|
|
bdb21ce3fd | ||
|
|
2ca4fb6d8f | ||
|
|
e7900b11b4 | ||
|
|
d71f6d0b99 | ||
|
|
926bd5d2fb | ||
|
|
461d14c39a | ||
|
|
6714cae498 | ||
|
|
b20a0e74c2 | ||
|
|
9686eaf3f1 | ||
|
|
7b03a24196 | ||
|
|
98555b24f8 | ||
|
|
3d05b58856 | ||
|
|
15b46ddb27 | ||
|
|
78c4e6510d | ||
|
|
cd76d5ac09 | ||
|
|
9c2a064817 | ||
|
|
db2da89f69 | ||
|
|
0652d6b3f1 | ||
|
|
1111125aab | ||
|
|
4fc420616d | ||
|
|
fb7c83a66c | ||
|
|
f021665089 | ||
|
|
6c887c15be | ||
|
|
2b7722da7d | ||
|
|
4f65697522 | ||
|
|
5140992a7b | ||
|
|
af0cd34f92 | ||
|
|
b8ca88ee0a | ||
|
|
fac1884a43 | ||
|
|
46fa330bdd | ||
|
|
adfa7c0780 | ||
|
|
11df6030f9 | ||
|
|
45ca2938f5 | ||
|
|
88fa4fa861 | ||
|
|
100d6cc4a5 | ||
|
|
32e58d2bb3 | ||
|
|
638a3909c5 | ||
|
|
82da1aaf2a | ||
|
|
3c2d86ef7b | ||
|
|
f559017aeb | ||
|
|
e158d9bc00 | ||
|
|
3ddd1c26ad | ||
|
|
ab5b59e10d | ||
|
|
1f67251331 | ||
|
|
4eecdfa553 | ||
|
|
80dd0f1580 | ||
|
|
4e0c70a402 | ||
|
|
ffd5a198f9 | ||
|
|
ddc89c9f49 | ||
|
|
9673d5524a | ||
|
|
3214fc2f93 | ||
|
|
3b0925b912 | ||
|
|
c5f032fcb2 | ||
|
|
98e05d941d | ||
|
|
90ab1e5656 | ||
|
|
564f36fc8b | ||
|
|
6159284be6 | ||
|
|
9afc6f0a4e | ||
|
|
f689bb253e | ||
|
|
0738c96867 | ||
|
|
edba8ca986 | ||
|
|
2aa9055fae | ||
|
|
1369d66043 | ||
|
|
9e48d64b27 | ||
|
|
d37fe213d7 | ||
|
|
029d66bd95 | ||
|
|
c73b4ad6ba | ||
|
|
6e256d29c7 | ||
|
|
185526d134 | ||
|
|
9b1c61fbcf | ||
|
|
ae7ef7d79a | ||
|
|
273f11cd59 | ||
|
|
f5092bc981 | ||
|
|
9489eca487 | ||
|
|
3aa195943d | ||
|
|
3c6c92aa9c | ||
|
|
c2160ae367 | ||
|
|
d607a8830b | ||
|
|
f7f99bddab | ||
|
|
4564db0b6d | ||
|
|
0a44a31f2c | ||
|
|
0692e4de8d | ||
|
|
92d013dd65 | ||
|
|
242bbdada5 | ||
|
|
d90f5b7e7c | ||
|
|
d95449c22d | ||
|
|
28f2fb1468 | ||
|
|
ad5a50ecd9 | ||
|
|
4d8dbe068d | ||
|
|
157e415636 | ||
|
|
48f84c5cf4 | ||
|
|
1d3d1c8454 | ||
|
|
bb2b339b54 | ||
|
|
5790c585f5 | ||
|
|
a2655912d4 | ||
|
|
e2c905e9b2 | ||
|
|
9619417b07 | ||
|
|
b0bcdeafac | ||
|
|
7b76015fd1 | ||
|
|
465955c8f5 | ||
|
|
90a759b98e | ||
|
|
0096b91146 | ||
|
|
125f000894 | ||
|
|
f9a0e6ce4f | ||
|
|
0d5a1416d0 | ||
|
|
43f3132069 | ||
|
|
3d00a1be21 | ||
|
|
87ce09f4b1 | ||
|
|
31f90a0a47 | ||
|
|
af30904624 | ||
|
|
f2f995af17 | ||
|
|
1c213d73c9 | ||
|
|
3dcd2ad15f | ||
|
|
accf226214 | ||
|
|
71df1e2da1 | ||
|
|
d49a40b0da | ||
|
|
75c6b01696 | ||
|
|
eb2c8a032f | ||
|
|
416db840ec | ||
|
|
b0c4cef077 | ||
|
|
58d12e5754 | ||
|
|
bcda64a5df | ||
|
|
ba77de3dc5 | ||
|
|
53325617bb | ||
|
|
8e836d958f | ||
|
|
fa72d1154d | ||
|
|
27926b0d55 | ||
|
|
8ce6bf82a9 | ||
|
|
36aeb36c90 | ||
|
|
780d17e61c | ||
|
|
c613acb31d | ||
|
|
21548545fc | ||
|
|
7dd3178d48 | ||
|
|
c9ee530205 | ||
|
|
cc54df87d7 | ||
|
|
9698cbc9d7 | ||
|
|
f085cbc4a4 | ||
|
|
d8b6aa3831 | ||
|
|
3e5ef39686 | ||
|
|
bc7c65447d | ||
|
|
a91378b9c1 | ||
|
|
7543234401 | ||
|
|
5b91c54936 | ||
|
|
322280757f | ||
|
|
b1636fbb96 | ||
|
|
cc18a7b146 | ||
|
|
5fe84a78ac | ||
|
|
822e0dcd98 | ||
|
|
a6be3714a3 | ||
|
|
f56d1bad04 | ||
|
|
c7ab404fc1 | ||
|
|
e8f41a03f3 | ||
|
|
8edc9971f9 | ||
|
|
54c36a7e46 | ||
|
|
afb820202d | ||
|
|
0ce973966f | ||
|
|
da8c040c08 | ||
|
|
ee8854fa14 | ||
|
|
11ca71cbc7 | ||
|
|
3794c61ab2 | ||
|
|
dde3ca2d73 | ||
|
|
9850dc305c | ||
|
|
4d1b59c05b | ||
|
|
a0c3323b7c | ||
|
|
c9e53d4b1d | ||
|
|
1a89246e7f | ||
|
|
2094ac2bba | ||
|
|
f9b0ff70f7 | ||
|
|
d2d3597c29 | ||
|
|
4b62b1f69f | ||
|
|
91c2c891fd | ||
|
|
1ba0a7d264 | ||
|
|
5f6bf332d3 | ||
|
|
448cc49cff | ||
|
|
81f0c0a0dc | ||
|
|
95c1046765 | ||
|
|
2a8c27115c | ||
|
|
b6933013be | ||
|
|
a2bb576c03 | ||
|
|
c8d6da5a23 | ||
|
|
f09263d3be | ||
|
|
fdfd383c34 | ||
|
|
39a32fc83d | ||
|
|
c072041039 | ||
|
|
6d75f96ed5 | ||
|
|
ab304c9178 | ||
|
|
abcb1dec46 | ||
|
|
ac4bf9cf2c | ||
|
|
72a51f9506 | ||
|
|
d50a77f861 | ||
|
|
0ecd6b16b0 | ||
|
|
4dcbaa8c2b | ||
|
|
2261dbce83 | ||
|
|
53ff1102df | ||
|
|
b01b49aff4 | ||
|
|
c9a7659d93 | ||
|
|
4f75cd62e5 | ||
|
|
2a74715c3c | ||
|
|
1210c3e689 | ||
|
|
a3f430c224 | ||
|
|
2f7be43ccb | ||
|
|
f5432c734c | ||
|
|
5ca35aa4fc | ||
|
|
2dd474ad26 | ||
|
|
97e45346ea | ||
|
|
6c1ce41900 | ||
|
|
4a57901746 | ||
|
|
c32636b8cb | ||
|
|
190ffdaa5a | ||
|
|
bdd2b40c96 | ||
|
|
53f54cf23b | ||
|
|
474d531788 | ||
|
|
3db55df0a6 | ||
|
|
1483a61f11 | ||
|
|
7b715f7be9 | ||
|
|
56034f9aac | ||
|
|
7e96a4dd3a | ||
|
|
523c81f797 | ||
|
|
f540c8250b | ||
|
|
e89b7f12dd | ||
|
|
279b67fa49 | ||
|
|
11f1f65ed1 | ||
|
|
071dfa9792 | ||
|
|
3cecb03dac | ||
|
|
a7c64f8ba2 | ||
|
|
6749dad1a4 | ||
|
|
91b4c86bbe | ||
|
|
aadb88eeea | ||
|
|
2c4d6552e9 | ||
|
|
c2e8d51115 | ||
|
|
1d69809022 | ||
|
|
093f14923c | ||
|
|
63768ccc99 | ||
|
|
a00f25d2f9 | ||
|
|
54faa38920 | ||
|
|
ae1bb909b6 | ||
|
|
ecb616e411 | ||
|
|
8c762c52e2 | ||
|
|
e14a7d1d4d | ||
|
|
08c81fe1f8 | ||
|
|
63be93be64 | ||
|
|
de4891e133 | ||
|
|
8fd398f213 | ||
|
|
ec53aa86dd | ||
|
|
51985ed2ca | ||
|
|
67ae7b9dcb | ||
|
|
96654d9620 | ||
|
|
ce97b97c8d | ||
|
|
034f680a8e | ||
|
|
7d17e34dee | ||
|
|
d0a16a49b6 | ||
|
|
5442547a59 | ||
|
|
10e7e06048 | ||
|
|
eac6426125 | ||
|
|
88b01994bd | ||
|
|
66780bb4c2 | ||
|
|
7f26981fa1 | ||
|
|
5b0a0070c7 | ||
|
|
0462f3b252 | ||
|
|
9a5cfdff4c | ||
|
|
cb3b1bf6e1 | ||
|
|
b4d2df8111 | ||
|
|
cadb95e3ce | ||
|
|
f148757110 | ||
|
|
6e538cd291 | ||
|
|
62a73ee612 | ||
|
|
4160037c81 | ||
|
|
3fa537e54a | ||
|
|
f35c18a0c2 | ||
|
|
aff137ac34 | ||
|
|
6236b0ab00 | ||
|
|
ae656a0f81 | ||
|
|
6a6648d3b3 | ||
|
|
a4c90aeff3 | ||
|
|
bfe13981bc | ||
|
|
ef11dd883a | ||
|
|
da149c296f | ||
|
|
9af4c717a8 | ||
|
|
281e5a138e | ||
|
|
e7f8b2c6c2 | ||
|
|
3d9c64d548 | ||
|
|
5f142b4c86 | ||
|
|
52c506af9a | ||
|
|
dc9c7fd95c | ||
|
|
4ec7befe82 | ||
|
|
dd4dd91152 | ||
|
|
a39ba2cd71 | ||
|
|
9c2202fa39 | ||
|
|
9c6931a17c | ||
|
|
976925c697 | ||
|
|
d50af46b03 | ||
|
|
3405910f4c | ||
|
|
52874f9113 | ||
|
|
91a241dafa | ||
|
|
a8db070755 | ||
|
|
76676f3a2e | ||
|
|
f5040f1e41 | ||
|
|
c9c3c8f716 | ||
|
|
144d6fd3f6 | ||
|
|
9697067466 | ||
|
|
8539095bdb | ||
|
|
95e3159fe9 | ||
|
|
8b74c487eb | ||
|
|
8abda7f259 | ||
|
|
8d5c52f087 | ||
|
|
e6c1d9bf66 | ||
|
|
a52af1bf41 | ||
|
|
3f10cc774b | ||
|
|
ac92ca220f | ||
|
|
ab8801d0de | ||
|
|
f3802ec464 | ||
|
|
bc7a7bcfa0 | ||
|
|
6a52d44da6 | ||
|
|
03a8a11933 | ||
|
|
c474e35732 | ||
|
|
4c1f67d022 | ||
|
|
91759aba95 | ||
|
|
5a9bbaf900 | ||
|
|
01a767cbfa | ||
|
|
8552a7282c | ||
|
|
2a161b572b | ||
|
|
422852795f | ||
|
|
4d53f21387 | ||
|
|
9263e2192f | ||
|
|
c99a87dd09 | ||
|
|
009db77426 | ||
|
|
4e5ded7cb3 | ||
|
|
50f31cad14 | ||
|
|
2f43145131 | ||
|
|
e3fca2bce5 | ||
|
|
da112a0ae9 | ||
|
|
90060d1d83 | ||
|
|
1ccce5f1a2 | ||
|
|
8584493c7f | ||
|
|
9b2d906648 | ||
|
|
2aaa0331ac | ||
|
|
7604239237 | ||
|
|
562a6fb61d | ||
|
|
938562cc0a | ||
|
|
1e4d63731b | ||
|
|
8ff01301cb | ||
|
|
a664118fc7 | ||
|
|
87d376654b | ||
|
|
c6e92311f9 | ||
|
|
24d30a40f9 | ||
|
|
ae283aef59 | ||
|
|
e4f7928513 | ||
|
|
bd8a5ece58 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@
|
||||
.vscode
|
||||
build/*
|
||||
output/*
|
||||
loader/payload_00.h
|
||||
loader/payload_01.h
|
||||
tools/bin2c/bin2c
|
||||
tools/lz/lz77
|
||||
|
||||
102
Makefile
102
Makefile
@@ -8,11 +8,7 @@ include $(DEVKITARM)/base_rules
|
||||
|
||||
IPL_LOAD_ADDR := 0x40008000
|
||||
IPL_MAGIC := 0x43544349 #"ICTC"
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 1
|
||||
BLVERSION_HOTFX := 0
|
||||
|
||||
BL_RESERVED := 0
|
||||
include ./Versions.inc
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -20,11 +16,14 @@ TARGET := hekate
|
||||
BUILDDIR := build
|
||||
OUTPUTDIR := output
|
||||
SOURCEDIR = bootloader
|
||||
VPATH = $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
BDKDIR := bdk
|
||||
BDKINC := -I./$(BDKDIR)
|
||||
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
|
||||
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
start.o \
|
||||
start.o exception_handlers.o \
|
||||
main.o heap.o \
|
||||
gfx.o tui.o \
|
||||
fe_emmc_tools.o fe_info.o fe_tools.o \
|
||||
@@ -32,9 +31,10 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o clock.o cluster.o di.o gpio.o i2c.o mc.o sdram.o pinmux.o se.o smmu.o tsec.o uart.o \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
|
||||
pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o minerva.o \
|
||||
sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o \
|
||||
sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o nx_sd.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
hw_init.o \
|
||||
)
|
||||
@@ -47,66 +47,108 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
# Horizon.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o sept.o \
|
||||
hos.o hos_config.o pkg1.o pkg2.o pkg2_ini_kippatch.o fss.o secmon_exo.o \
|
||||
)
|
||||
|
||||
# Libraries.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
lz.o blz.o \
|
||||
lz.o lz4.o blz.o \
|
||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
|
||||
GFX_INC := '"../$(SOURCEDIR)/gfx/gfx.h"'
|
||||
FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"'
|
||||
|
||||
################################################################################
|
||||
|
||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BL_RESERVED)
|
||||
#CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
# UART Logging: Max baudrate 12.5M.
|
||||
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
NYXDIR := $(wildcard nyx)
|
||||
LDRDIR := $(wildcard loader)
|
||||
TOOLSLZ := $(wildcard tools/lz)
|
||||
TOOLSB2C := $(wildcard tools/bin2c)
|
||||
TOOLS := $(TOOLSLZ) $(TOOLSB2C)
|
||||
|
||||
################################################################################
|
||||
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR)
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR) $(LDRDIR) $(TOOLS)
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Payload size is "
|
||||
@wc -c < $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "Max size is 126296 Bytes."
|
||||
all: $(TARGET).bin $(LDRDIR)
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo -n "Uncompr size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET)_unc.bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Uncompr Max: 140288 Bytes + 3 KiB BSS"
|
||||
@if [ ${BIN_SIZE} -gt 140288 ]; then echo "\e[1;33mUncompr size exceeds limit!\e[0m"; fi
|
||||
@echo -n "Payload size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Payload Max: 126296 Bytes"
|
||||
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean:
|
||||
clean: $(TOOLS)
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
|
||||
$(MODULEDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(NYXDIR):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR)
|
||||
$(LDRDIR): $(TARGET).bin
|
||||
@$(TOOLSLZ)/lz77 $(OUTPUTDIR)/$(TARGET).bin
|
||||
mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.00.lz payload_00
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.01.lz payload_01
|
||||
@$(TOOLSB2C)/bin2c payload_00 > $(LDRDIR)/payload_00.h
|
||||
@$(TOOLSB2C)/bin2c payload_01 > $(LDRDIR)/payload_01.h
|
||||
@rm payload_00
|
||||
@rm payload_01
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS) PAYLOAD_NAME=$(TARGET)
|
||||
|
||||
$(TOOLS):
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@echo "hekate was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) $(BDKINC) -c $< -o $@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.S
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJS): $(BUILDDIR)/$(TARGET)
|
||||
|
||||
$(BUILDDIR)/$(TARGET):
|
||||
@mkdir -p "$(BUILDDIR)"
|
||||
@mkdir -p "$(BUILDDIR)/$(TARGET)"
|
||||
@mkdir -p "$(OUTPUTDIR)"
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
181
README.md
181
README.md
@@ -1,9 +1,38 @@
|
||||
# hekate - CTCaer mod
|
||||
# hekate - Nyx
|
||||
|
||||

|
||||
|
||||
|
||||
Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many more.
|
||||
|
||||
|
||||
|
||||
- [Features](#features)
|
||||
- [Bootloader folders and files](#bootloader-folders-and-files)
|
||||
- [Bootloader configuration](#bootloader-configuration)
|
||||
* [hekate global Configuration keys/values](#hekate-global-configuration-keysvalues-when-entry-is-config)
|
||||
* [Boot entry key/value combinations](#boot-entry-keyvalue-combinations)
|
||||
* [Boot entry key/value combinations for Exosphère](#boot-entry-keyvalue-combinations-for-exosphère)
|
||||
* [Payload storage](#payload-storage)
|
||||
* [Nyx Configuration keys/values](#nyx-configuration-keysvalues-nyxini)
|
||||
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **Fully Configurable and Graphical** with Touchscreen and Joycon input support
|
||||
- **Launcher Style, Background and Color Themes**
|
||||
- **HOS (Switch OS) Bootloader** -- For CFW Sys/Emu, OFW Sys and Stock Sys
|
||||
- **Android & Linux Bootloader**
|
||||
- **Payload Launcher**
|
||||
- **eMMC/emuMMC Backup/Restore Tools**
|
||||
- **SD Card Partition Manager** -- Prepares and formats SD Card for any combo of HOS (Sys/emuMMC), Android and Linux
|
||||
- **emuMMC Creation & Manager** -- Can also migrate and fix existing emuMMC
|
||||
- **Switch Android & Linux flasher**
|
||||
- **USB Mass Storage (UMS) for SD/eMMC/emuMMC** -- Converts Switch into a SD Card Reader
|
||||
- **USB Gamepad** -- Converts Switch with Joycon into a USB HID Gamepad
|
||||
- **Hardware and Peripherals info** (SoC, Fuses, RAM, Display, Touch, eMMC, SD, Battery, PSU, Charger)
|
||||
- **Many other tools** like Archive Bit Fixer, Touch Calibration, SD/eMMC Benchmark, AutoRCM enabler and more
|
||||
|
||||
|
||||
## Bootloader folders and files
|
||||
@@ -11,27 +40,27 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
| Folder/File | Description |
|
||||
| ------------------------ | --------------------------------------------------------------------- |
|
||||
| bootloader | Main folder. |
|
||||
| \|__ bootlogo.bmp | It is used when custom is on and no logopath found. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries. |
|
||||
| \|__ bootlogo.bmp | It is used if no `logopath` key is found. User provided. Can be skipped. |
|
||||
| \|__ hekate_ipl.ini | Main bootloader configuration and boot entries in `Launch` menu. |
|
||||
| \|__ nyx.ini | Nyx GUI configuration |
|
||||
| \|__ patches.ini | Add external patches. Can be skipped. A template can be found [here](./res/patches_template.ini) |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. For modchips. Can be skipped. |
|
||||
| bootloader/ini/ | For individual inis. 'More configs...' menu. Autoboot is supported. |
|
||||
| \|__ update.bin | If newer, it is loaded at boot. Normally for modchips. Auto updated and created at first boot. |
|
||||
| bootloader/ini/ | For individual inis. `More configs` menu. Autoboot is supported. |
|
||||
| bootloader/res/ | Nyx user resources. Icons and more. |
|
||||
| \|__ background.bmp | Nyx - custom background. |
|
||||
| \|__ background.bmp | Nyx - Custom background. User provided. |
|
||||
| \|__ icon_switch.bmp | Nyx - Default icon for CFWs. |
|
||||
| \|__ icon_payload.bmp | Nyx - Default icon for Payloads. |
|
||||
| \|__ icon_lakka.bmp | Nyx - Default icon for Lakka. |
|
||||
| bootloader/sys/ | For system modules. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. Important! |
|
||||
| bootloader/sys/ | hekate and Nyx system modules folder. |
|
||||
| \|__ emummc.kipm | emuMMC KIP1 module. !Important! |
|
||||
| \|__ libsys_lp0.bso | LP0 (sleep mode) module. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. Important! |
|
||||
| \|__ nyx.bin | Nyx - Our GUI. Important! |
|
||||
| \|__ res.pak | Nyx resources package. Important! |
|
||||
| \|__ libsys_minerva.bso | Minerva Training Cell. Used for DRAM Frequency training. !Important! |
|
||||
| \|__ nyx.bin | Nyx - hekate's GUI. !Important! |
|
||||
| \|__ res.pak | Nyx resources package. !Important! |
|
||||
| \|__ thk.bin | Atmosphère Tsec Hovi Keygen. !Important! |
|
||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||
| bootloader/libtools/ | Future reserved |
|
||||
| bootloader/payloads/ | For the `Payloads` menu. All CFW bootloaders, tools, Linux payloads are supported. Autoboot only supported by including them into an ini. |
|
||||
| bootloader/libtools/ | Reserved |
|
||||
|
||||
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
||||
|
||||
|
||||
## Bootloader configuration
|
||||
@@ -42,84 +71,126 @@ The bootloader can be configured via 'bootloader/hekate_ipl.ini' (if it is prese
|
||||
There are four possible type of entries. "**[ ]**": Boot entry, "**{ }**": Caption, "**#**": Comment, "*newline*": .ini cosmetic newline.
|
||||
|
||||
|
||||
You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
**You can find a template [Here](./res/hekate_ipl_template.ini)**
|
||||
|
||||
|
||||
### Global Configuration keys/values when boot entry is **config**:
|
||||
### hekate Global Configuration keys/values (when entry is *[config]*):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| autoboot=0 | 0: Disable, #: Boot entry number to auto boot. |
|
||||
| autoboot_list=0 | 0: Read `autoboot` boot entry from hekate_ipl.ini, 1: Read from ini folder (ini files are ASCII ordered). |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| verification=2 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and not 100% reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. Max: 20s. |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
|
||||
### Possible boot entry key/value combinations:
|
||||
### Boot entry key/value combinations:
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| warmboot={SD path} | Replaces the warmboot binary |
|
||||
| secmon={SD path} | Replaces the security monitor binary |
|
||||
| kernel={SD path} | Replaces the kernel binary |
|
||||
| kip1={SD path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||
| warmboot={FILE path} | Replaces the warmboot binary |
|
||||
| secmon={FILE path} | Replaces the security monitor binary |
|
||||
| kernel={FILE path} | Replaces the kernel binary |
|
||||
| kip1={FILE path} | Replaces/Adds kernel initial process. Multiple can be set. |
|
||||
| kip1={FOLDER path}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={FILE path} | Takes an Atmosphere `package3` binary (formerly fusee-secondary.bin) and `extracts` all needed parts from it. kips, exosphere, warmboot and mesophere if enabled. |
|
||||
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
|
||||
| exofatal={FILE path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or in one line with `,` as separator. If actual patch is not found, a warning will show up |
|
||||
| emupath={FOLDER path} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
|
||||
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
|
||||
| stock=1 | Disables unneeded kernel patching and CFW kips when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disable=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission). Doesn't work with Mesosphere as kernel. |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. |
|
||||
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
||||
| userpmu=1 | Allows user access to PMU when paired with Exosphère. |
|
||||
| emummc_force_disable=1 | Disabled emuMMC if it's enabled. |
|
||||
| stock=1 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required to run completely stock. |
|
||||
| id=idname | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
| logopath={SD path} | If no logopath, `bootloader/bootlogo.bmp` will be used if exists. If logopath exists, it will load the specified bitmap. |
|
||||
| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| payload={FILE path} | Payload launching. Tools, Android/Linux, CFW bootloaders, etc. Any key above when used with that, doesn't get into account. |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| id=IDNAME | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||
| logopath={FILE path} | If it exists, it will load the specified bitmap. Otherwise `bootloader/bootlogo.bmp` will be used if exists |
|
||||
| icon={FILE path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise defaults will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes). In such cases, the `kip1` line must be under `fss0` line.
|
||||
|
||||
|
||||
### Boot entry key/value combinations for Exosphère:
|
||||
|
||||
| Config option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------- |
|
||||
| nouserexceptions=1 | Disables usermode exception handlers when paired with Exosphère. |
|
||||
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
|
||||
|
||||
|
||||
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
|
||||
|
||||
|
||||
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
|
||||
hekate has a boot storage in the binary that helps it configure it outside of BPMP enviroment:
|
||||
|
||||
| Offset / Name | Description |
|
||||
| -------------------- | ----------------------------------------------------------------- |
|
||||
| '0x94' boot_cfg | bit0: Force AutoBoot, bit1: Show launch log, bit2: Boot from ID, bit7: sept run. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2`. |
|
||||
| '0x98' id[8] | When Boot from ID is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`, 0: Force go to menu, else boot that entry. |
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |
|
||||
|
||||
|
||||
If the main .ini is not found, it is created on the first hekate boot.
|
||||
If the main .ini is not found, it is created on the first hekate boot and only has the `[config]` entry.
|
||||
|
||||
|
||||
### Nyx Configuration keys/values (nyx.ini):
|
||||
|
||||
| Config option | Description |
|
||||
| ------------------ | ---------------------------------------------------------- |
|
||||
| themecolor=167 | Sets Nyx color of text highlights. |
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
| bpmpclock=1 | 0: Auto, 1: Faster, 2: Fast. Use 2 if Nyx hangs or some functions like UMS/Backup Verification fail. |
|
||||
|
||||
|
||||
```
|
||||
hekate (C) 2018 naehrwert, st4rk
|
||||
CTCaer mod (C) 2018 CTCaer.
|
||||
hekate (c) 2018, naehrwert, st4rk.
|
||||
(c) 2018-2021, CTCaer.
|
||||
|
||||
Nyx GUI (c) 2019-2021, CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
||||
Open source and free packages used:
|
||||
- FatFs R0.13a, Copyright (C) 2017, ChaN
|
||||
- bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard
|
||||
- FatFs R0.13a, Copyright (c) 2017, ChaN
|
||||
- bcl-1.2.0, Copyright (c) 2003-2006, Marcus Geelnard
|
||||
- Atmosphère (Exosphere types/panic, prc id kernel patches),
|
||||
Copyright (C) 2018-2019, Atmosphère-NX
|
||||
- elfload, Copyright (C) 2014 Owen Shepherd, Copyright (C) 2018 M4xw
|
||||
Copyright (c) 2018-2019, Atmosphère-NX
|
||||
- elfload, Copyright (c) 2014 Owen Shepherd, Copyright (c) 2018 M4xw
|
||||
- Littlev Graphics Library, Copyright (c) 2016 Gabor Kiss-Vamosi
|
||||
|
||||
___
|
||||
.-' `'.
|
||||
|
||||
@@ -11,6 +11,7 @@ Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are
|
||||
|
||||
## How to configure
|
||||
|
||||
If the custom logo option is enabled, it will try to load /bootlogo.bmp. If this is not found, the default hekate's logo will be used.
|
||||
If a boot entry specifies a custom logo path (`logopath=`), this is one will be loaded.
|
||||
|
||||
If a boot entry specifies a custom logo path, this is one will be loaded. Again if this is not found, bootlogo.bmp will be loaded and if that fails, hekate's built-in will be used.
|
||||
If the above is not found or the format is not correct, it will try to load `bootloader/bootlogo.bmp`.
|
||||
If this is not found, the default hekate logo will be used.
|
||||
|
||||
11
Versions.inc
Normal file
11
Versions.inc
Normal file
@@ -0,0 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 6
|
||||
BLVERSION_HOTFX := 5
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 1
|
||||
NYXVERSION_HOTFX := 1
|
||||
NYXVERSION_RSVD := 0
|
||||
867
bdk/display/di.c
Normal file
867
bdk/display/di.c
Normal file
@@ -0,0 +1,867 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "di.h"
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include "di.inl"
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
static u32 _display_id = 0;
|
||||
static bool nx_aula = false;
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit);
|
||||
|
||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
{
|
||||
u32 end = get_tmr_us() + timeout;
|
||||
while (get_tmr_us() < end && DSI(off) & mask)
|
||||
;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
|
||||
{
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (param << 8) | cmd;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
if (wait)
|
||||
usleep(wait);
|
||||
}
|
||||
|
||||
static void _display_dsi_read_rx_fifo(u32 *data)
|
||||
{
|
||||
u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
|
||||
for (u32 i = 0; i < fifo_count; i++)
|
||||
{
|
||||
// Read or Drain RX FIFO.
|
||||
if (data)
|
||||
data[i] = DSI(_DSIREG(DSI_RD_DATA));
|
||||
else
|
||||
(void)DSI(_DSIREG(DSI_RD_DATA));
|
||||
}
|
||||
}
|
||||
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
int res = 0;
|
||||
u32 host_control = 0;
|
||||
u32 cmd_timeout = video_enabled ? 0 : 250000;
|
||||
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||
|
||||
// Drain RX FIFO.
|
||||
_display_dsi_read_rx_fifo(NULL);
|
||||
|
||||
// Save host control and enable host cmd packets during video.
|
||||
if (video_enabled)
|
||||
{
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
|
||||
|
||||
// Use the 4th line to transmit the host cmd packet.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
||||
|
||||
// Wait for vblank before starting the transfer.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
||||
;
|
||||
}
|
||||
|
||||
// Set reply size.
|
||||
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Request register read.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Transfer bus control to device for transmitting the reply.
|
||||
u32 high_speed = video_enabled ? DSI_HOST_CONTROL_HS : 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC | high_speed;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
// Wait a bit for the reply.
|
||||
usleep(5000);
|
||||
|
||||
// Read RX FIFO.
|
||||
_display_dsi_read_rx_fifo(fifo);
|
||||
|
||||
// Parse packet and copy over the data.
|
||||
if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
|
||||
{
|
||||
// Act based on reply type.
|
||||
switch (fifo[1] & 0xFF)
|
||||
{
|
||||
case GEN_LONG_RD_RES:
|
||||
case DCS_LONG_RD_RES:
|
||||
memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
|
||||
break;
|
||||
|
||||
case GEN_1_BYTE_SHORT_RD_RES:
|
||||
case DCS_1_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 1);
|
||||
break;
|
||||
|
||||
case GEN_2_BYTE_SHORT_RD_RES:
|
||||
case DCS_2_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 2);
|
||||
break;
|
||||
|
||||
case ACK_ERROR_RES:
|
||||
default:
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
res = 1;
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
{
|
||||
// Wait for vblank before reseting sync points.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
||||
;
|
||||
|
||||
// Reset all states of syncpt block.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Clear syncpt block reset.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Restore video mode and host control.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
|
||||
// Disable and clear vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
u8 *fifo8;
|
||||
u32 *fifo32;
|
||||
u32 host_control;
|
||||
|
||||
// Enable host cmd packets during video and save host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable host transfer trigger.
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control | DSI_HOST_CONTROL_TX_TRIG_HOST;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4);
|
||||
fifo8 = (u8 *)fifo32;
|
||||
fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
|
||||
fifo8[4] = cmd;
|
||||
memcpy(&fifo8[5], data, len);
|
||||
len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
|
||||
for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
free(fifo32);
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for the write to happen.
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST);
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
}
|
||||
|
||||
void display_dsi_vblank_write(u8 cmd, u32 len, void *data)
|
||||
{
|
||||
u8 *fifo8;
|
||||
u32 *fifo32;
|
||||
|
||||
// Enable vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
|
||||
|
||||
// Use the 4th line to transmit the host cmd packet.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
||||
|
||||
// Wait for vblank before starting the transfer.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
||||
;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (cmd << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = ((cmd | (*(u8 *)data << 8)) << 8) | MIPI_DSI_DCS_SHORT_WRITE_PARAM;
|
||||
break;
|
||||
|
||||
default:
|
||||
fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4);
|
||||
fifo8 = (u8 *)fifo32;
|
||||
fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
|
||||
fifo8[4] = cmd;
|
||||
memcpy(&fifo8[5], data, len);
|
||||
len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
|
||||
for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
|
||||
free(fifo32);
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for vblank before reseting sync points.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (!(DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT))
|
||||
;
|
||||
|
||||
// Reset all states of syncpt block.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Clear syncpt block reset.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Restore video mode and host control.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
|
||||
// Disable and clear vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
|
||||
}
|
||||
|
||||
void display_init()
|
||||
{
|
||||
// Get Hardware type, as it's used in various DI functions.
|
||||
nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA;
|
||||
|
||||
// Check if display is already initialized.
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_DISP1))
|
||||
_display_panel_and_hw_end(true);
|
||||
|
||||
// Get Chip ID.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// T210B01: Power on SD2 regulator for supplying LDO0.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
// Set SD2 regulator voltage.
|
||||
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
||||
|
||||
// Set slew rate and enable SD2 regulator.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
||||
max7762x_regulator_enable(REGULATOR_SD2, true);
|
||||
|
||||
}
|
||||
|
||||
// Enable power to display panel controller.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO0, true);
|
||||
|
||||
if (tegra_t210)
|
||||
max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> Display panel.
|
||||
|
||||
// Enable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
|
||||
|
||||
// Bring every IO rail out of deep power down.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
|
||||
// Configure LCD pins.
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Configure Backlight pins.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
if (nx_aula)
|
||||
{
|
||||
// Configure LCD RST pin.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_2, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set LCD +-5V pins mode and direction
|
||||
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable LCD power.
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable.
|
||||
usleep(10000);
|
||||
|
||||
// Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST).
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable Backlight power.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
|
||||
}
|
||||
|
||||
// Power up supply regulator for display interface.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
|
||||
|
||||
if (!tegra_t210)
|
||||
{
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
|
||||
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
||||
}
|
||||
|
||||
// Set DISP1 clock source and parent clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT.
|
||||
u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 97.5 MHz (offset).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
|
||||
// Setup Display Interface initial window configuration.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
|
||||
|
||||
// Setup display communication interfaces.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8);
|
||||
if (tegra_t210)
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
|
||||
else
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part2, 14);
|
||||
if (!tegra_t210)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part3_t210b01, 7);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part4, 10);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part5, 12);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part6, 14);
|
||||
usleep(10000);
|
||||
|
||||
// Enable LCD Reset.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
|
||||
usleep(60000);
|
||||
|
||||
// Setup DSI device takeover timeout.
|
||||
DSI(_DSIREG(DSI_BTA_TIMING)) = nx_aula ? 0x40103 : 0x50204;
|
||||
|
||||
// Get Display ID.
|
||||
_display_id = 0xCCCCCC;
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (!display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED))
|
||||
break;
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
// Save raw Display ID to Nyx storage.
|
||||
nyx_str->info.disp_id = _display_id;
|
||||
|
||||
// Decode Display ID.
|
||||
_display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
|
||||
// For Aula ensure that we have a compatible panel id.
|
||||
if (nx_aula && _display_id == 0xCCCC)
|
||||
_display_id = PANEL_SAM_AMS699VC01;
|
||||
|
||||
// Initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_SAM_AMS699VC01:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xA0, 0); // Write 0 to 0xA0.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, MIPI_DCS_SET_CONTROL_DISPLAY | (DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL << 8), 0); // Enable brightness control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x339; // MIPI_DSI_DCS_LONG_WRITE: 3 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x000051; // MIPI_DCS_SET_BRIGHTNESS 0000: 0%. FF07: 100%.
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
case PANEL_AUO_A062TAN01:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
|
||||
if (_display_id == PANEL_INL_P062CCA_AZ1)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else // PANEL_AUO_A062TAN01.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
default: // Allow spare part displays to work.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
|
||||
break;
|
||||
}
|
||||
|
||||
// Unblank display.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||
|
||||
// Configure PLLD for DISP1.
|
||||
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 234 MHz (offset, it's ddr btw, so normally div2).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
|
||||
else
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
|
||||
|
||||
// Finalize DSI configuration.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19);
|
||||
// Set pixel clock dividers: 234 / 3 / 1 = 78 MHz (offset) for 60 Hz.
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
|
||||
usleep(10000);
|
||||
|
||||
// Calibrate display communication pads.
|
||||
u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4);
|
||||
for (u32 i = 0; i < loops; i++)
|
||||
{
|
||||
// Set MIPI bias pad config.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
|
||||
|
||||
// Set pad trimmers and set MIPI DSI cal offsets.
|
||||
if (tegra_t210)
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210, 4);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210b01, 7);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210b01, 4);
|
||||
}
|
||||
|
||||
// Set the rest of MIPI cal offsets and apply calibration.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
|
||||
}
|
||||
usleep(10000);
|
||||
|
||||
// Enable video display controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113);
|
||||
}
|
||||
|
||||
void display_backlight_pwm_init()
|
||||
{
|
||||
if (_display_id == PANEL_SAM_AMS699VC01)
|
||||
return;
|
||||
|
||||
clock_enable_pwm();
|
||||
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
||||
}
|
||||
|
||||
void display_backlight(bool enable)
|
||||
{
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
|
||||
}
|
||||
|
||||
void display_dsi_backlight_brightness(u32 brightness)
|
||||
{
|
||||
// Normalize brightness value by 82% and a base of 45 duty.
|
||||
if (brightness)
|
||||
brightness = (brightness * PANEL_OLED_BL_COEFF / 100) + PANEL_OLED_BL_OFFSET;
|
||||
|
||||
u16 bl_ctrl = byte_swap_16((u16)(brightness * 8));
|
||||
display_dsi_vblank_write(MIPI_DCS_SET_BRIGHTNESS, 2, &bl_ctrl);
|
||||
}
|
||||
|
||||
void display_pwm_backlight_brightness(u32 brightness, u32 step_delay)
|
||||
{
|
||||
u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
|
||||
if (brightness == old_value)
|
||||
return;
|
||||
|
||||
if (old_value < brightness)
|
||||
{
|
||||
for (u32 i = old_value; i < brightness + 1; i++)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = old_value; i > brightness; i--)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16);
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
if (!brightness)
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
|
||||
}
|
||||
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay)
|
||||
{
|
||||
if (brightness > 255)
|
||||
brightness = 255;
|
||||
|
||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||
display_pwm_backlight_brightness(brightness, step_delay);
|
||||
else
|
||||
display_dsi_backlight_brightness(brightness);
|
||||
}
|
||||
|
||||
u32 display_get_backlight_brightness()
|
||||
{
|
||||
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||
{
|
||||
if (no_panel_deinit)
|
||||
goto skip_panel_deinit;
|
||||
|
||||
display_backlight_brightness(0, 1000);
|
||||
|
||||
// Enable host cmd packets during video.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
|
||||
// Blank display.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
||||
|
||||
// Propagate changes to all register buffers and disable host cmd packets during video.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
|
||||
// De-initialize video controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_timing_deinit_config, 16);
|
||||
|
||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||
usleep(10000);
|
||||
|
||||
// De-initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
|
||||
break;
|
||||
|
||||
case PANEL_AUO_A062TAN01:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
if (_display_id == PANEL_INL_2J055IA_27A)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else if (_display_id == PANEL_AUO_A055TAN01)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
else // PANEL_V40_55_UNK.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40).
|
||||
if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01)
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
|
||||
}
|
||||
else // PANEL_V40_55_UNK.
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
|
||||
}
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Blank - powerdown.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE,
|
||||
(_display_id == PANEL_SAM_AMS699VC01) ? 120000 : 50000);
|
||||
|
||||
skip_panel_deinit:
|
||||
// Disable LCD power pins.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
|
||||
|
||||
if (!nx_aula) // HOS uses panel id.
|
||||
{
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable.
|
||||
usleep(10000);
|
||||
}
|
||||
else
|
||||
usleep(30000); // Aula Panel.
|
||||
|
||||
// Disable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
// Power down pads.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
||||
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
|
||||
|
||||
// Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
|
||||
if (!nx_aula)
|
||||
{
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
}
|
||||
}
|
||||
|
||||
void display_end() { _display_panel_and_hw_end(false); };
|
||||
|
||||
u16 display_get_decoded_panel_id()
|
||||
{
|
||||
return _display_id;
|
||||
}
|
||||
|
||||
void display_set_decoded_panel_id(u32 id)
|
||||
{
|
||||
// Get Hardware type, as it's used in various DI functions.
|
||||
nx_aula = fuse_read_hw_type() == FUSE_NX_HW_TYPE_AULA;
|
||||
|
||||
// Decode Display ID.
|
||||
_display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
|
||||
// For Aula ensure that we have a compatible panel id.
|
||||
if (nx_aula && _display_id == 0xCCCC)
|
||||
_display_id = PANEL_SAM_AMS699VC01;
|
||||
}
|
||||
|
||||
void display_color_screen(u32 color)
|
||||
{
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
|
||||
|
||||
// Configure display to show single color.
|
||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
||||
usleep(35000); // No need to wait on Aula.
|
||||
|
||||
if (_display_id != PANEL_SAM_AMS699VC01)
|
||||
display_backlight(true);
|
||||
else
|
||||
display_backlight_brightness(255, 0);
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch()
|
||||
{
|
||||
// Sanitize framebuffer area.
|
||||
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
|
||||
|
||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
|
||||
usleep(35000); // No need to wait on Aula.
|
||||
|
||||
return (u32 *)IPL_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch_inv()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
|
||||
usleep(35000); // No need to wait on Aula.
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_block()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34);
|
||||
usleep(35000); // No need to wait on Aula.
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_log()
|
||||
{
|
||||
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
|
||||
|
||||
return (u32 *)LOG_FB_ADDRESS;
|
||||
}
|
||||
|
||||
void display_activate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
|
||||
for (u32 i = 0xFF80; i < 0x10000; i++)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deactivate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
|
||||
for (u32 i = 0xFFFF; i > 0xFF7F; i--)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(500);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_init_cursor(void *crs_fb, u32 size)
|
||||
{
|
||||
// Setup cursor.
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) =
|
||||
CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
|
||||
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
|
||||
|
||||
// Arm and activate changes.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_set_pos_cursor(u32 x, u32 y)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
|
||||
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deinit_cursor()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
742
bdk/display/di.h
Normal file
742
bdk/display/di.h
Normal file
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DI_H_
|
||||
#define _DI_H_
|
||||
|
||||
#include <memory_map.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define DSI_VIDEO_DISABLED 0
|
||||
#define DSI_VIDEO_ENABLED 1
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
|
||||
// Display controller scratch registers.
|
||||
#define DC_D_WINBUF_DD_SCRATCH_REGISTER_0 0xED
|
||||
#define DC_D_WINBUF_DD_SCRATCH_REGISTER_1 0xEE
|
||||
#define DC_T_WINBUF_TD_SCRATCH_REGISTER_0 0x16D
|
||||
#define DC_T_WINBUF_TD_SCRATCH_REGISTER_1 0x16E
|
||||
#define DC_COM_SCRATCH_REGISTER_A 0x325
|
||||
#define DC_COM_SCRATCH_REGISTER_B 0x326
|
||||
#define DC_A_WINBUF_AD_SCRATCH_REGISTER_0 0xBED
|
||||
#define DC_A_WINBUF_AD_SCRATCH_REGISTER_1 0xBEE
|
||||
#define DC_B_WINBUF_BD_SCRATCH_REGISTER_0 0xDED
|
||||
#define DC_B_WINBUF_BD_SCRATCH_REGISTER_1 0xDEE
|
||||
#define DC_C_WINBUF_CD_SCRATCH_REGISTER_0 0xFED
|
||||
#define DC_C_WINBUF_CD_SCRATCH_REGISTER_1 0xFEE
|
||||
|
||||
// DC_CMD non-shadowed command/sync registers.
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_SOFT_RESET BIT(0)
|
||||
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND 0x32
|
||||
#define DISP_CTRL_MODE_STOP (0 << 5)
|
||||
#define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
|
||||
#define DISP_CTRL_MODE_NC_DISPLAY (2 << 5)
|
||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
||||
|
||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
||||
#define PW0_ENABLE BIT(0)
|
||||
#define PW1_ENABLE BIT(2)
|
||||
#define PW2_ENABLE BIT(4)
|
||||
#define PW3_ENABLE BIT(6)
|
||||
#define PW4_ENABLE BIT(8)
|
||||
#define PM0_ENABLE BIT(16)
|
||||
#define PM1_ENABLE BIT(18)
|
||||
|
||||
#define DC_CMD_INT_STATUS 0x37
|
||||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX BIT(0)
|
||||
#define WRITE_MUX BIT(2)
|
||||
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define GENERAL_ACT_REQ BIT(0)
|
||||
#define WIN_A_ACT_REQ BIT(1)
|
||||
#define WIN_B_ACT_REQ BIT(2)
|
||||
#define WIN_C_ACT_REQ BIT(3)
|
||||
#define WIN_D_ACT_REQ BIT(4)
|
||||
#define CURSOR_ACT_REQ BIT(7)
|
||||
#define GENERAL_UPDATE BIT(8)
|
||||
#define WIN_A_UPDATE BIT(9)
|
||||
#define WIN_B_UPDATE BIT(10)
|
||||
#define WIN_C_UPDATE BIT(11)
|
||||
#define WIN_D_UPDATE BIT(12)
|
||||
#define CURSOR_UPDATE BIT(15)
|
||||
#define NC_HOST_TRIG BIT(24)
|
||||
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define WINDOW_A_SELECT BIT(4)
|
||||
#define WINDOW_B_SELECT BIT(5)
|
||||
#define WINDOW_C_SELECT BIT(6)
|
||||
#define WINDOW_D_SELECT BIT(7)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
|
||||
// DC_D_WIN_DD window D instance of DC_WIN
|
||||
#define DC_D_WIN_DD_WIN_OPTIONS 0x80
|
||||
#define DC_D_WIN_DD_COLOR_DEPTH 0x83
|
||||
#define DC_D_WIN_DD_POSITION 0x84
|
||||
#define DC_D_WIN_DD_SIZE 0x85
|
||||
#define DC_D_WIN_DD_LINE_STRIDE 0x8A
|
||||
#define DC_D_WIN_DD_BLEND_LAYER_CONTROL 0x96
|
||||
#define DC_D_WIN_DD_BLEND_MATCH_SELECT 0x97
|
||||
#define DC_D_WIN_DD_BLEND_ALPHA_1BIT 0x99
|
||||
|
||||
// DC_D_WINBUF_DD window D instance of DC_WINBUF
|
||||
#define DC_D_WINBUF_DD_START_ADDR 0xC0
|
||||
#define DC_D_WINBUF_DD_ADDR_H_OFFSET 0xC6
|
||||
#define DC_D_WINBUF_DD_ADDR_V_OFFSET 0xC8
|
||||
#define DC_D_WINBUF_DD_START_ADDR_HI 0xCD
|
||||
#define DC_D_WINBUF_DD_MEMFETCH_CONTROL 0xEB
|
||||
|
||||
// DC_T_WIN_TD macro for using DD defines.
|
||||
#define _DC_T(reg) ((reg) + 0x80)
|
||||
|
||||
// DC_COM non-shadowed registers.
|
||||
#define DC_COM_CRC_CONTROL 0x300
|
||||
#define DC_COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
|
||||
#define DC_COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
|
||||
|
||||
#define DC_COM_DSC_TOP_CTL 0x33E
|
||||
|
||||
// DC_DISP shadowed registers.
|
||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
||||
#define CURSOR_ENABLE BIT(16)
|
||||
#define SOR_ENABLE BIT(25)
|
||||
#define SOR1_ENABLE BIT(26)
|
||||
#define SOR1_TIMING_CYA BIT(27)
|
||||
#define DSI_ENABLE BIT(29)
|
||||
#define HDMI_ENABLE BIT(30)
|
||||
|
||||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
#define DC_DISP_DISP_TIMING_OPTIONS 0x405
|
||||
#define DC_DISP_REF_TO_SYNC 0x406
|
||||
#define DC_DISP_SYNC_WIDTH 0x407
|
||||
#define DC_DISP_BACK_PORCH 0x408
|
||||
#define DC_DISP_ACTIVE 0x409
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD3 (3 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD4 (4 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD6 (5 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD8 (6 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD9 (7 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD12 (8 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD16 (9 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
||||
|
||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C24B (1 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C18B (2 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P2C16B (3 << 0)
|
||||
#define DISP_DATA_FORMAT_DF2S (4 << 0)
|
||||
#define DISP_DATA_FORMAT_DF3S (5 << 0)
|
||||
#define DISP_DATA_FORMAT_DFSPI (6 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C24B (7 << 0)
|
||||
#define DISP_DATA_FORMAT_DF1P3C18B (8 << 0)
|
||||
#define DISP_ALIGNMENT_MSB (0 << 8)
|
||||
#define DISP_ALIGNMENT_LSB (1 << 8)
|
||||
#define DISP_ORDER_RED_BLUE (0 << 9)
|
||||
#define DISP_ORDER_BLUE_RED (1 << 9)
|
||||
|
||||
#define DC_DISP_DISP_COLOR_CONTROL 0x430
|
||||
#define DITHER_CONTROL_MASK (3 << 8)
|
||||
#define DITHER_CONTROL_DISABLE (0 << 8)
|
||||
#define DITHER_CONTROL_ORDERED (2 << 8)
|
||||
#define DITHER_CONTROL_ERRDIFF (3 << 8)
|
||||
#define BASE_COLOR_SIZE_MASK (0xf << 0)
|
||||
#define BASE_COLOR_SIZE_666 (0 << 0)
|
||||
#define BASE_COLOR_SIZE_111 (1 << 0)
|
||||
#define BASE_COLOR_SIZE_222 (2 << 0)
|
||||
#define BASE_COLOR_SIZE_333 (3 << 0)
|
||||
#define BASE_COLOR_SIZE_444 (4 << 0)
|
||||
#define BASE_COLOR_SIZE_555 (5 << 0)
|
||||
#define BASE_COLOR_SIZE_565 (6 << 0)
|
||||
#define BASE_COLOR_SIZE_332 (7 << 0)
|
||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||
|
||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||
#define SC0_H_QUALIFIER_NONE BIT(0)
|
||||
#define SC1_H_QUALIFIER_NONE BIT(16)
|
||||
|
||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
||||
#define DE_SELECT_ACTIVE (1 << 0)
|
||||
#define DE_SELECT_ACTIVE_IS (2 << 0)
|
||||
#define DE_CONTROL_ONECLK (0 << 2)
|
||||
#define DE_CONTROL_NORMAL (1 << 2)
|
||||
#define DE_CONTROL_EARLY_EXT (2 << 2)
|
||||
#define DE_CONTROL_EARLY (3 << 2)
|
||||
#define DE_CONTROL_ACTIVE_BLANK (4 << 2)
|
||||
|
||||
// Cursor configuration registers.
|
||||
#define DC_DISP_CURSOR_FOREGROUND 0x43C
|
||||
#define DC_DISP_CURSOR_BACKGROUND 0x43D
|
||||
#define CURSOR_COLOR(r,g,b) (((r) & 0xFF) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16))
|
||||
|
||||
#define DC_DISP_CURSOR_START_ADDR 0x43E
|
||||
#define CURSOR_CLIPPING(w) ((w) << 28)
|
||||
#define CURSOR_CLIP_WIN_A 1
|
||||
#define CURSOR_CLIP_WIN_B 2
|
||||
#define CURSOR_CLIP_WIN_C 3
|
||||
#define CURSOR_SIZE_32 (0 << 24)
|
||||
#define CURSOR_SIZE_64 (1 << 24)
|
||||
#define CURSOR_SIZE_128 (2 << 24)
|
||||
#define CURSOR_SIZE_256 (3 << 24)
|
||||
#define DC_DISP_CURSOR_POSITION 0x440
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||
#define CURSOR_BLEND_2BIT (0 << 24)
|
||||
#define CURSOR_BLEND_R8G8B8A8 (1 << 24)
|
||||
#define CURSOR_BLEND_SRC_FACTOR(n) ((n) << 8)
|
||||
#define CURSOR_BLEND_DST_FACTOR(n) ((n) << 16)
|
||||
#define CURSOR_BLEND_ZRO 0
|
||||
#define CURSOR_BLEND_K1 1
|
||||
#define CURSOR_BLEND_NK1 2
|
||||
// End of cursor cfg regs.
|
||||
|
||||
#define DC_DISP_DC_MCCIF_FIFOCTRL 0x480
|
||||
#define DC_DISP_SD_BL_PARAMETERS 0x4D7
|
||||
#define DC_DISP_SD_BL_CONTROL 0x4DC
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
|
||||
#define DC_WIN_CSC_YOF 0x611
|
||||
#define DC_WIN_CSC_KYRGB 0x612
|
||||
#define DC_WIN_CSC_KUR 0x613
|
||||
#define DC_WIN_CSC_KVR 0x614
|
||||
#define DC_WIN_CSC_KUG 0x615
|
||||
#define DC_WIN_CSC_KVG 0x616
|
||||
#define DC_WIN_CSC_KUB 0x617
|
||||
#define DC_WIN_CSC_KVB 0x618
|
||||
#define DC_WIN_AD_WIN_OPTIONS 0xB80
|
||||
#define DC_WIN_BD_WIN_OPTIONS 0xD80
|
||||
#define DC_WIN_CD_WIN_OPTIONS 0xF80
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define BUFFER_CONTROL_HOST 0
|
||||
#define BUFFER_CONTROL_VI 1
|
||||
#define BUFFER_CONTROL_EPP 2
|
||||
#define BUFFER_CONTROL_MPEGE 3
|
||||
#define BUFFER_CONTROL_SB2D 4
|
||||
|
||||
#define DC_WIN_COLOR_DEPTH 0x703
|
||||
#define WIN_COLOR_DEPTH_P1 0x0
|
||||
#define WIN_COLOR_DEPTH_P2 0x1
|
||||
#define WIN_COLOR_DEPTH_P4 0x2
|
||||
#define WIN_COLOR_DEPTH_P8 0x3
|
||||
#define WIN_COLOR_DEPTH_B4G4R4A4 0x4
|
||||
#define WIN_COLOR_DEPTH_B5G5R5A 0x5
|
||||
#define WIN_COLOR_DEPTH_B5G6R5 0x6
|
||||
#define WIN_COLOR_DEPTH_AB5G5R5 0x7
|
||||
#define WIN_COLOR_DEPTH_B8G8R8A8 0xC
|
||||
#define WIN_COLOR_DEPTH_R8G8B8A8 0xD
|
||||
#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 0xE
|
||||
#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 0xF
|
||||
#define WIN_COLOR_DEPTH_YCbCr422 0x10
|
||||
#define WIN_COLOR_DEPTH_YUV422 0x11
|
||||
#define WIN_COLOR_DEPTH_YCbCr420P 0x12
|
||||
#define WIN_COLOR_DEPTH_YUV420P 0x13
|
||||
#define WIN_COLOR_DEPTH_YCbCr422P 0x14
|
||||
#define WIN_COLOR_DEPTH_YUV422P 0x15
|
||||
#define WIN_COLOR_DEPTH_YCbCr422R 0x16
|
||||
#define WIN_COLOR_DEPTH_YUV422R 0x17
|
||||
#define WIN_COLOR_DEPTH_YCbCr422RA 0x18
|
||||
#define WIN_COLOR_DEPTH_YUV422RA 0x19
|
||||
|
||||
#define DC_WIN_POSITION 0x704
|
||||
#define H_POSITION(x) (((x) & 0xFfff) << 0)
|
||||
#define V_POSITION(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_SIZE 0x705
|
||||
#define H_SIZE(x) (((x) & 0x1fff) << 0)
|
||||
#define V_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_PRESCALED_SIZE 0x706
|
||||
#define H_PRESCALED_SIZE(x) (((x) & 0x7fff) << 0)
|
||||
#define V_PRESCALED_SIZE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define DC_WIN_H_INITIAL_DDA 0x707
|
||||
#define DC_WIN_V_INITIAL_DDA 0x708
|
||||
|
||||
#define DC_WIN_DDA_INC 0x709
|
||||
#define H_DDA_INC(x) (((x) & 0xffff) << 0)
|
||||
#define V_DDA_INC(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DC_WIN_LINE_STRIDE 0x70A
|
||||
#define LINE_STRIDE(x) (x)
|
||||
#define UV_LINE_STRIDE(x) (((x) & 0xffff) << 16)
|
||||
#define DC_WIN_DV_CONTROL 0x70E
|
||||
|
||||
#define DC_WINBUF_BLEND_LAYER_CONTROL 0x716
|
||||
#define WIN_K1(x) (((x) & 0xff) << 8)
|
||||
#define WIN_K2(x) (((x) & 0xff) << 16)
|
||||
#define WIN_BLEND_ENABLE (0 << 24)
|
||||
#define WIN_BLEND_BYPASS (1 << 24)
|
||||
|
||||
#define DC_WINBUF_BLEND_MATCH_SELECT 0x717
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_ZERO (0 << 0)
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_ONE (1 << 0)
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 (2 << 0)
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1_TIMES_DST (3 << 0)
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_NEG_K1_TIMES_DST (4 << 0)
|
||||
#define WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1_TIMES_SRC (5 << 0)
|
||||
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_ZERO (0 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_ONE (1 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_K1 (2 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_K2 (3 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_K1_TIMES_DST (4 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1_TIMES_DST (5 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1_TIMES_SRC (6 << 4)
|
||||
#define WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1 (7 << 4)
|
||||
|
||||
#define WIN_BLEND_FACT_SRC_ALPHA_MATCH_SEL_ZERO (0 << 8)
|
||||
#define WIN_BLEND_FACT_SRC_ALPHA_MATCH_SEL_K1 (1 << 8)
|
||||
#define WIN_BLEND_FACT_SRC_ALPHA_MATCH_SEL_K2 (2 << 8)
|
||||
|
||||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_ZERO (0 << 12)
|
||||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_ONE (1 << 12)
|
||||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_NEG_K1_TIMES_SRC (2 << 12)
|
||||
#define WIN_BLEND_FACT_DST_ALPHA_MATCH_SEL_K2 (3 << 12)
|
||||
|
||||
#define DC_WINBUF_BLEND_ALPHA_1BIT 0x719
|
||||
#define WIN_ALPHA_1BIT_WEIGHT0(x) (((x) & 0xff) << 0)
|
||||
#define WIN_ALPHA_1BIT_WEIGHT1(x) (((x) & 0xff) << 8)
|
||||
|
||||
/*! The following registers are A/B/C shadows of the 0xBC0/0xDC0/0xFC0 registers (see DISPLAY_WINDOW_HEADER). */
|
||||
#define DC_WINBUF_START_ADDR 0x800
|
||||
#define DC_WINBUF_ADDR_H_OFFSET 0x806
|
||||
#define DC_WINBUF_ADDR_V_OFFSET 0x808
|
||||
#define DC_WINBUF_SURFACE_KIND 0x80B
|
||||
#define PITCH (0 << 0)
|
||||
#define TILED (1 << 0)
|
||||
#define BLOCK (2 << 0)
|
||||
#define BLOCK_HEIGHT(x) (((x) & 0x7) << 4)
|
||||
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
|
||||
#define DSI_INCR_SYNCPT_CNTRL 0x1
|
||||
#define DSI_INCR_SYNCPT_SOFT_RESET BIT(0)
|
||||
#define DSI_INCR_SYNCPT_NO_STALL BIT(8)
|
||||
|
||||
#define DSI_RD_DATA 0x9
|
||||
#define DSI_WR_DATA 0xA
|
||||
|
||||
#define DSI_POWER_CONTROL 0xB
|
||||
#define DSI_POWER_CONTROL_ENABLE 1
|
||||
|
||||
#define DSI_INT_ENABLE 0xC
|
||||
#define DSI_INT_STATUS 0xD
|
||||
#define DSI_INT_MASK 0xE
|
||||
|
||||
#define DSI_HOST_CONTROL 0xF
|
||||
#define DSI_HOST_CONTROL_ECC BIT(0)
|
||||
#define DSI_HOST_CONTROL_CS BIT(1)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA BIT(2)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA BIT(3)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL BIT(4)
|
||||
#define DSI_HOST_CONTROL_HS BIT(5)
|
||||
#define DSI_HOST_CONTROL_RAW BIT(6)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET BIT(20)
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET BIT(21)
|
||||
|
||||
#define DSI_CONTROL 0x10
|
||||
#define DSI_CONTROL_HOST_ENABLE BIT(0)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE BIT(1)
|
||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
||||
#define DSI_CONTROL_DCS_ENABLE BIT(3)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_HS_CLK_CTRL BIT(20)
|
||||
|
||||
#define DSI_SOL_DELAY 0x11
|
||||
#define DSI_MAX_THRESHOLD 0x12
|
||||
|
||||
#define DSI_TRIGGER 0x13
|
||||
#define DSI_TRIGGER_VIDEO BIT(0)
|
||||
#define DSI_TRIGGER_HOST BIT(1)
|
||||
|
||||
#define DSI_TX_CRC 0x14
|
||||
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
||||
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
||||
#define DSI_INIT_SEQ_DATA_2 0x1D
|
||||
#define DSI_INIT_SEQ_DATA_3 0x1E
|
||||
#define DSI_PKT_SEQ_0_LO 0x23
|
||||
#define DSI_PKT_SEQ_0_HI 0x24
|
||||
#define DSI_PKT_SEQ_1_LO 0x25
|
||||
#define DSI_PKT_SEQ_1_HI 0x26
|
||||
#define DSI_PKT_SEQ_2_LO 0x27
|
||||
#define DSI_PKT_SEQ_2_HI 0x28
|
||||
#define DSI_PKT_SEQ_3_LO 0x29
|
||||
#define DSI_PKT_SEQ_3_HI 0x2A
|
||||
#define DSI_PKT_SEQ_4_LO 0x2B
|
||||
#define DSI_PKT_SEQ_4_HI 0x2C
|
||||
#define DSI_PKT_SEQ_5_LO 0x2D
|
||||
#define DSI_PKT_SEQ_5_HI 0x2E
|
||||
#define DSI_DCS_CMDS 0x33
|
||||
#define DSI_PKT_LEN_0_1 0x34
|
||||
#define DSI_PKT_LEN_2_3 0x35
|
||||
#define DSI_PKT_LEN_4_5 0x36
|
||||
#define DSI_PKT_LEN_6_7 0x37
|
||||
#define DSI_PHY_TIMING_0 0x3C
|
||||
#define DSI_PHY_TIMING_1 0x3D
|
||||
#define DSI_PHY_TIMING_2 0x3E
|
||||
#define DSI_BTA_TIMING 0x3F
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DSI_TO_TALLY 0x46
|
||||
|
||||
#define DSI_PAD_CONTROL_0 0x4B
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
|
||||
#define DSI_PAD_CONTROL_CD 0x4C
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||
#define DSI_CMD_PKT_VID_ENABLE 1
|
||||
#define DSI_DSI_LINE_TYPE(x) ((x) << 1)
|
||||
|
||||
#define DSI_PAD_CONTROL_1 0x4F
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
|
||||
#define DSI_PAD_CONTROL_3 0x51
|
||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
#define DSI_PAD_CONTROL_5_B01 0x53
|
||||
#define DSI_PAD_CONTROL_6_B01 0x54
|
||||
#define DSI_PAD_CONTROL_7_B01 0x55
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
||||
#define DSI_INIT_SEQ_DATA_15_B01 0x62
|
||||
|
||||
/*! DSI packet defines */
|
||||
#define DSI_ESCAPE_CMD 0x87
|
||||
#define DSI_ACK_NO_ERR 0x84
|
||||
|
||||
#define ACK_ERROR_RES 0x02
|
||||
#define GEN_LONG_RD_RES 0x1A
|
||||
#define DCS_LONG_RD_RES 0x1C
|
||||
#define GEN_1_BYTE_SHORT_RD_RES 0x11
|
||||
#define DCS_1_BYTE_SHORT_RD_RES 0x21
|
||||
#define GEN_2_BYTE_SHORT_RD_RES 0x12
|
||||
#define DCS_2_BYTE_SHORT_RD_RES 0x22
|
||||
|
||||
/*! MIPI registers. */
|
||||
#define MIPI_CAL_MIPI_CAL_CTRL (0x00 / 0x4)
|
||||
#define MIPI_CAL_CIL_MIPI_CAL_STATUS (0x08 / 0x4)
|
||||
#define MIPI_CAL_CILA_MIPI_CAL_CONFIG (0x14 / 0x4)
|
||||
#define MIPI_CAL_CILB_MIPI_CAL_CONFIG (0x18 / 0x4)
|
||||
#define MIPI_CAL_CILC_MIPI_CAL_CONFIG (0x1C / 0x4)
|
||||
#define MIPI_CAL_CILD_MIPI_CAL_CONFIG (0x20 / 0x4)
|
||||
#define MIPI_CAL_CILE_MIPI_CAL_CONFIG (0x24 / 0x4)
|
||||
#define MIPI_CAL_CILF_MIPI_CAL_CONFIG (0x28 / 0x4)
|
||||
#define MIPI_CAL_DSIA_MIPI_CAL_CONFIG (0x38 / 0x4)
|
||||
#define MIPI_CAL_DSIB_MIPI_CAL_CONFIG (0x3C / 0x4)
|
||||
#define MIPI_CAL_DSIC_MIPI_CAL_CONFIG (0x40 / 0x4)
|
||||
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG (0x44 / 0x4)
|
||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG0 (0x58 / 0x4)
|
||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG1 (0x5C / 0x4)
|
||||
#define MIPI_CAL_MIPI_BIAS_PAD_CFG2 (0x60 / 0x4)
|
||||
#define MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2 (0x64 / 0x4)
|
||||
#define MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2 (0x68 / 0x4)
|
||||
#define MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2 (0x70 / 0x4)
|
||||
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG_2 (0x74 / 0x4)
|
||||
|
||||
/*! MIPI CMDs. */
|
||||
#define MIPI_DSI_V_SYNC_START 0x01
|
||||
#define MIPI_DSI_COLOR_MODE_OFF 0x02
|
||||
#define MIPI_DSI_END_OF_TRANSMISSION 0x08
|
||||
#define MIPI_DSI_NULL_PACKET 0x09
|
||||
#define MIPI_DSI_V_SYNC_END 0x11
|
||||
#define MIPI_DSI_COLOR_MODE_ON 0x12
|
||||
#define MIPI_DSI_BLANKING_PACKET 0x19
|
||||
#define MIPI_DSI_H_SYNC_START 0x21
|
||||
#define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22
|
||||
#define MIPI_DSI_H_SYNC_END 0x31
|
||||
#define MIPI_DSI_TURN_ON_PERIPHERAL 0x32
|
||||
#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
|
||||
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE 0x05
|
||||
#define MIPI_DSI_DCS_READ 0x06
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
|
||||
#define MIPI_DSI_DCS_LONG_WRITE 0x39
|
||||
|
||||
#define MIPI_DSI_GENERIC_LONG_WRITE 0x29
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM 0x04
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM 0x14
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM 0x24
|
||||
|
||||
/*! MIPI DCS CMDs. */
|
||||
#define MIPI_DCS_NOP 0x00
|
||||
#define MIPI_DCS_SOFT_RESET 0x01
|
||||
#define MIPI_DCS_GET_COMPRESSION_MODE 0x03
|
||||
#define MIPI_DCS_GET_DISPLAY_ID 0x04
|
||||
#define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID.
|
||||
#define MIPI_DCS_GET_NUM_ERRORS 0x05 // 1 byte.
|
||||
#define MIPI_DCS_GET_RED_CHANNEL 0x06
|
||||
#define MIPI_DCS_GET_GREEN_CHANNEL 0x07
|
||||
#define MIPI_DCS_GET_BLUE_CHANNEL 0x08
|
||||
#define MIPI_DCS_GET_DISPLAY_STATUS 0x09 // 4 bytes.
|
||||
#define MIPI_DCS_GET_POWER_MODE 0x0A // 1 byte. 2: DISON, 3: NORON, 4: SLPOUT, 7: BSTON.
|
||||
#define MIPI_DCS_GET_ADDRESS_MODE 0x0B // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
|
||||
#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C // 1 byte. 4-6: DPI.
|
||||
#define MIPI_DCS_GET_DISPLAY_MODE 0x0D // 1 byte. 0-2: GCS, 3: ALLPOFF, 4: ALLPON, 5: INVON.
|
||||
#define MIPI_DCS_GET_SIGNAL_MODE 0x0E // 1 byte. 0: EODSI, 2: DEON, 3: PCLKON, 4: VSON, 5: HSON, 7: TEON.
|
||||
#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F // 1 byte. 6: FUNDT, 7: REGLD.
|
||||
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
|
||||
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
|
||||
#define MIPI_DCS_ENTER_PARTIAL_MODE 0x12
|
||||
#define MIPI_DCS_ENTER_NORMAL_MODE 0x13
|
||||
#define MIPI_DCS_EXIT_INVERT_MODE 0x20
|
||||
#define MIPI_DCS_ENTER_INVERT_MODE 0x21
|
||||
#define MIPI_DCS_ALL_PIXELS_OFF 0x22
|
||||
#define MIPI_DCS_ALL_PIXELS_ON 0x23
|
||||
#define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer.
|
||||
#define MIPI_DCS_SET_GAMMA_CURVE 0x26 // 1 byte. 0-7: GC.
|
||||
#define MIPI_DCS_SET_DISPLAY_OFF 0x28
|
||||
#define MIPI_DCS_SET_DISPLAY_ON 0x29
|
||||
#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A
|
||||
#define MIPI_DCS_SET_PAGE_ADDRESS 0x2B
|
||||
#define MIPI_DCS_WRITE_MEMORY_START 0x2C
|
||||
#define MIPI_DCS_WRITE_LUT 0x2D // 24-bit: 192 bytes.
|
||||
#define MIPI_DCS_READ_MEMORY_START 0x2E
|
||||
#define MIPI_DCS_SET_PARTIAL_ROWS 0x30
|
||||
#define MIPI_DCS_SET_PARTIAL_COLUMNS 0x31
|
||||
#define MIPI_DCS_SET_SCROLL_AREA 0x33
|
||||
#define MIPI_DCS_SET_TEAR_OFF 0x34
|
||||
#define MIPI_DCS_SET_TEAR_ON 0x35
|
||||
#define MIPI_DCS_SET_ADDRESS_MODE 0x36 // Display Access Control. 1 byte. 0: GS, 1: SS, 3: BGR.
|
||||
#define MIPI_DCS_SET_SCROLL_START 0x37
|
||||
#define MIPI_DCS_EXIT_IDLE_MODE 0x38
|
||||
#define MIPI_DCS_ENTER_IDLE_MODE 0x39
|
||||
#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A // 1 byte. 4-6: DPI.
|
||||
#define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C
|
||||
#define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E
|
||||
#define MIPI_DCS_GET_3D_CONTROL 0x3F
|
||||
#define MIPI_DCS_SET_VSYNC_TIMING 0x40
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE 0x44
|
||||
#define MIPI_DCS_GET_SCANLINE 0x45
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
|
||||
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
|
||||
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL. 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_GET_BRIGHTNESS 0x52 // 1 byte. 0-7: DBV.
|
||||
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
|
||||
#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54 // 1 byte. 2: BL, 3: DD, 5: BCTRL.
|
||||
#define MIPI_DCS_SET_CABC_VALUE 0x55 // 1 byte. 0-32: C, 4-7: C.
|
||||
#define MIPI_DCS_GET_CABC_VALUE 0x56 // 1 byte. 0-32: C, 4-7: C.
|
||||
#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E // 1 byte. 0-7: CMB.
|
||||
#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F // 1 byte. 0-7: CMB.
|
||||
#define MIPI_DCS_GET_AUTO_BRI_DIAG_RES 0x68 // 1 byte. 6-7: D.
|
||||
#define MIPI_DCS_READ_DDB_START 0xA1
|
||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8 // 0x100 size.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_UNK_A0 0xA0
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
#define MIPI_DCS_PRIV_SET_EXTC 0xB9 // Enable extended commands.
|
||||
#define MIPI_DCS_PRIV_UNK_BD 0xBD
|
||||
#define MIPI_DCS_PRIV_UNK_D5 0xD5
|
||||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
#define MIPI_DCS_PRIV_READ_EXTC_CMD_SPI 0xFE // Read EXTC Command In SPI. 1 byte. 0-6: EXT_SPI_CNT, 7:EXT_SP.
|
||||
#define MIPI_DCS_PRIV_SET_EXTC_CMD_REG 0xFF // EXTC Command Set enable register. 5 bytes. Pass: FF 98 06 04, PAGE.
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs PAGE 1. */
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID4 0x00
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID5 0x01
|
||||
#define MIPI_DCS_PRIV_GET_DISPLAY_ID6 0x02
|
||||
|
||||
/*! MIPI DCS CMD Defines. */
|
||||
#define DCS_POWER_MODE_DISPLAY_ON BIT(2)
|
||||
#define DCS_POWER_MODE_NORMAL_MODE BIT(3)
|
||||
#define DCS_POWER_MODE_SLEEP_MODE BIT(4)
|
||||
#define DCS_POWER_MODE_PARTIAL_MODE BIT(5)
|
||||
#define DCS_POWER_MODE_IDLE_MODE BIT(6)
|
||||
|
||||
#define DCS_ADDRESS_MODE_V_FLIP BIT(0)
|
||||
#define DCS_ADDRESS_MODE_H_FLIP BIT(1)
|
||||
#define DCS_ADDRESS_MODE_LATCH_RL BIT(2) // Latch Data Order.
|
||||
#define DCS_ADDRESS_MODE_BGR_COLOR BIT(3)
|
||||
#define DCS_ADDRESS_MODE_LINE_ORDER BIT(4) // Line Refresh Order.
|
||||
#define DCS_ADDRESS_MODE_SWAP_XY BIT(5) // Page/Column Addressing Reverse Order.
|
||||
#define DCS_ADDRESS_MODE_MIRROR_X BIT(6) // Column Address Order.
|
||||
#define DCS_ADDRESS_MODE_MIRROR_Y BIT(7) // Page Address Order.
|
||||
#define DCS_ADDRESS_MODE_ROTATION_MASK (0xF << 4)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_90 (DCS_ADDRESS_MODE_SWAP_XY | DCS_ADDRESS_MODE_LINE_ORDER)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_180 (DCS_ADDRESS_MODE_MIRROR_X | DCS_ADDRESS_MODE_LINE_ORDER)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_270 (DCS_ADDRESS_MODE_SWAP_XY)
|
||||
|
||||
#define DCS_GAMMA_CURVE_NONE 0
|
||||
#define DCS_GAMMA_CURVE_GC0_1_8 BIT(0)
|
||||
#define DCS_GAMMA_CURVE_GC1_2_5 BIT(1)
|
||||
#define DCS_GAMMA_CURVE_GC2_1_0 BIT(2)
|
||||
#define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more?
|
||||
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
|
||||
#define PANEL_OLED_BL_COEFF 82 // 82%.
|
||||
#define PANEL_OLED_BL_OFFSET 45 // Least legible backlight duty.
|
||||
|
||||
/* Switch Panels:
|
||||
*
|
||||
* 6.2" panels for Icosa and Iowa skus:
|
||||
* [10] 81 [26]: JDI LPM062M326A
|
||||
* [10] 96 [09]: JDI LAM062M109A
|
||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV]
|
||||
* [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
|
||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||
* [30] XX [0F]: AUO A062TAN03 (59.06A33.003) [UNCONFIRMED ID]
|
||||
*
|
||||
* 5.5" panels for Hoag skus:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||
* [30] 93 [10]: AUO A055TAN01 (59.05A30.001)
|
||||
* [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
|
||||
*
|
||||
* 7.0" OLED panels for Aula skus:
|
||||
* [50] 9B [20]: Samsung AMS699VC01-0 (Rev 2.5)
|
||||
*/
|
||||
|
||||
/* Display ID Decoding:
|
||||
*
|
||||
* byte0: Vendor
|
||||
* byte1: Model
|
||||
* byte2: Board
|
||||
*
|
||||
* Vendors:
|
||||
* 10h: Japan Display Inc.
|
||||
* 20h: InnoLux Corporation
|
||||
* 30h: AU Optronics
|
||||
* 40h: Unknown0
|
||||
* 50h: Samsung
|
||||
*
|
||||
* Boards, Panel Size:
|
||||
* 0Fh: Icosa/Iowa, 6.2"
|
||||
* 10h: Hoag, 5.5"
|
||||
* 20h: Aula, 7.0"
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
PANEL_JDI_XXX062M = 0x10,
|
||||
PANEL_JDI_LAM062M109A = 0x0910,
|
||||
PANEL_JDI_LPM062M326A = 0x2610,
|
||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030,
|
||||
PANEL_V40_55_UNK = 0x1040,
|
||||
PANEL_SAM_AMS699VC01 = 0x2050
|
||||
};
|
||||
|
||||
void display_init();
|
||||
void display_backlight_pwm_init();
|
||||
void display_end();
|
||||
|
||||
/*! Get/Set Display panel ID. */
|
||||
u16 display_get_decoded_panel_id();
|
||||
void display_set_decoded_panel_id(u32 id);
|
||||
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Switches screen backlight ON/OFF. */
|
||||
void display_backlight(bool enable);
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
u32 display_get_backlight_brightness();
|
||||
|
||||
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
u32 *display_init_framebuffer_pitch();
|
||||
u32 *display_init_framebuffer_pitch_inv();
|
||||
u32 *display_init_framebuffer_block();
|
||||
u32 *display_init_framebuffer_log();
|
||||
void display_activate_console();
|
||||
void display_deactivate_console();
|
||||
void display_init_cursor(void *crs_fb, u32 size);
|
||||
void display_set_pos_cursor(u32 x, u32 y);
|
||||
void display_deinit_cursor();
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -15,20 +15,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_1[4] = {
|
||||
{0x4E, 0x40000000}, //CLK_RST_CONTROLLER_CLK_SOURCE_DISP1
|
||||
{0x34, 0x4830A001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2D0AAA} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_2[94] = {
|
||||
static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
@@ -104,16 +96,16 @@ static const cfg_op_t _display_config_2[94] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -128,7 +120,7 @@ static const cfg_op_t _display_config_2[94] = {
|
||||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_config_3[61] = {
|
||||
static const cfg_op_t _display_dsi_init_config_part1[8] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
@@ -136,8 +128,9 @@ static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_INIT_SEQ_DATA_0, 0},
|
||||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0},
|
||||
{DSI_INIT_SEQ_DATA_15, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
@@ -151,7 +144,18 @@ static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_PKT_SEQ_3_HI, 0},
|
||||
{DSI_PKT_SEQ_4_HI, 0},
|
||||
{DSI_PKT_SEQ_5_HI, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_CONTROL, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0},
|
||||
{DSI_PAD_CONTROL_5_B01, 0},
|
||||
{DSI_PAD_CONTROL_6_B01, 0},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part4[10] = {
|
||||
{DSI_PAD_CONTROL_CD, 0},
|
||||
{DSI_SOL_DELAY, 0x18},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
@@ -161,8 +165,9 @@ static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_PKT_LEN_2_3, 0},
|
||||
{DSI_PKT_LEN_4_5, 0},
|
||||
{DSI_PKT_LEN_6_7, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part5[12] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -174,8 +179,9 @@ static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part6[14] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -192,15 +198,15 @@ static const cfg_op_t _display_config_3[61] = {
|
||||
{DSI_INIT_SEQ_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_4[43] = {
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0x9483FFB9},
|
||||
//DSI panel config.
|
||||
static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
{DSI_WR_DATA, 0x0439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xBD15},
|
||||
{DSI_WR_DATA, 0xBD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1939},
|
||||
{DSI_WR_DATA, 0xAAAAAAD8},
|
||||
{DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes.
|
||||
{DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAAAAAAAA},
|
||||
@@ -208,10 +214,10 @@ static const cfg_op_t _display_config_4[43] = {
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAA},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1BD15},
|
||||
{DSI_WR_DATA, 0x01BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 1 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2739},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0x2739}, // MIPI_DSI_DCS_LONG_WRITE: 39 bytes.
|
||||
{DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
@@ -222,27 +228,25 @@ static const cfg_op_t _display_config_4[43] = {
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2BD15},
|
||||
{DSI_WR_DATA, 0x02BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 2 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xF39},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0xF39}, // MIPI_DSI_DCS_LONG_WRITE: 15 bytes.
|
||||
{DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xBD15},
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x6D915},
|
||||
{DSI_WR_DATA, 0x06D915}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 6 to 0xD9.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0xB9},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_5[21] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
//DSI packet config.
|
||||
static const cfg_op_t _display_dsi_packet_config[19] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -261,18 +265,11 @@ static const cfg_op_t _display_config_5[21] = {
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_HOST_CONTROL, 0},
|
||||
{DSI_HOST_CONTROL, 0}
|
||||
};
|
||||
|
||||
//Clock config.
|
||||
static const cfg_op_t _display_config_6[3] = {
|
||||
{0x34, 0x4810C001}, //CLK_RST_CONTROLLER_PLLD_BASE
|
||||
{0x36, 0x20}, //CLK_RST_CONTROLLER_PLLD_MISC1
|
||||
{0x37, 0x2DFC00} //CLK_RST_CONTROLLER_PLLD_MISC
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_7[10] = {
|
||||
//DSI mode config.
|
||||
static const cfg_op_t _display_dsi_mode_config[10] = {
|
||||
{DSI_TRIGGER, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_SOL_DELAY, 6},
|
||||
@@ -286,45 +283,60 @@ static const cfg_op_t _display_config_7[10] = {
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_8[6] = {
|
||||
{0x18, 0}, // MIPI_CAL_MIPI_BIAS_PAD_CFG2
|
||||
{0x02, 0xF3F10000}, // MIPI_CAL_CIL_MIPI_CAL_STATUS
|
||||
{0x16, 0}, // MIPI_CAL_MIPI_BIAS_PAD_CFG0
|
||||
{0x18, 0}, // MIPI_CAL_MIPI_BIAS_PAD_CFG2
|
||||
{0x18, 0x10010}, // MIPI_CAL_MIPI_BIAS_PAD_CFG2
|
||||
{0x17, 0x300} // MIPI_CAL_MIPI_BIAS_PAD_CFG1
|
||||
static const cfg_op_t _display_mipi_pad_cal_config[4] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_9[4] = {
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
{DSI_PAD_CONTROL_5_B01, 0x77777},
|
||||
{DSI_PAD_CONTROL_6_B01, 0x1111},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_config_10[16] = {
|
||||
{0x0E, 0x200200}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG
|
||||
{0x0F, 0x200200}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG
|
||||
{0x19, 0x200002}, // MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2
|
||||
{0x1A, 0x200002}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2
|
||||
{0x05, 0}, // MIPI_CAL_CILA_MIPI_CAL_CONFIG
|
||||
{0x06, 0}, // MIPI_CAL_CILB_MIPI_CAL_CONFIG
|
||||
{0x07, 0}, // MIPI_CAL_CILC_MIPI_CAL_CONFIG
|
||||
{0x08, 0}, // MIPI_CAL_CILD_MIPI_CAL_CONFIG
|
||||
{0x09, 0}, // MIPI_CAL_CILE_MIPI_CAL_CONFIG
|
||||
{0x0A, 0}, // MIPI_CAL_CILF_MIPI_CAL_CONFIG
|
||||
{0x10, 0}, // MIPI_CAL_DSIC_MIPI_CAL_CONFIG
|
||||
{0x11, 0}, // MIPI_CAL_DSID_MIPI_CAL_CONFIG
|
||||
{0x1A, 0}, // MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2
|
||||
{0x1C, 0}, // MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2
|
||||
{0x1D, 0}, // MIPI_CAL_DSID_MIPI_CAL_CONFIG_2
|
||||
{0, 0x2A000001} // MIPI_CAL_DSIA_MIPI_CAL_CONFIG
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILD_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILE_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILF_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_DSID_MIPI_CAL_CONFIG_2, 0},
|
||||
{MIPI_CAL_MIPI_CAL_CTRL, 0x2A000001}
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t _display_config_11[113] = {
|
||||
static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -387,16 +399,16 @@ static const cfg_op_t _display_config_11[113] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -409,14 +421,37 @@ static const cfg_op_t _display_config_11[113] = {
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
/* Set Display timings */
|
||||
|
||||
/* Set Display timings
|
||||
*
|
||||
* DC_DISP_REF_TO_SYNC:
|
||||
* V_REF_TO_SYNC - 1
|
||||
* H_REF_TO_SYNC - 0
|
||||
*
|
||||
* DC_DISP_SYNC_WIDTH:
|
||||
* V_SYNC_WIDTH - 1
|
||||
* H_SYNC_WIDTH - 72
|
||||
*
|
||||
* DC_DISP_BACK_PORCH:
|
||||
* V_BACK_PORCH - 9
|
||||
* H_BACK_PORCH - 72
|
||||
*
|
||||
* DC_DISP_ACTIVE:
|
||||
* V_DISP_ACTIVE - 1280
|
||||
* H_DISP_ACTIVE - 720
|
||||
*
|
||||
* DC_DISP_FRONT_PORCH:
|
||||
* V_FRONT_PORCH - 10
|
||||
* H_FRONT_PORCH - 136
|
||||
*/
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
|
||||
{DC_DISP_REF_TO_SYNC, 0x10000},
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
@@ -449,7 +484,7 @@ static const cfg_op_t _display_config_11[113] = {
|
||||
};
|
||||
|
||||
////Display A config.
|
||||
static const cfg_op_t _display_config_12[17] = {
|
||||
static const cfg_op_t _display_video_disp_controller_disable_config[17] = {
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088},
|
||||
{DC_CMD_INT_MASK, 0},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
@@ -470,7 +505,7 @@ static const cfg_op_t _display_config_12[17] = {
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_config_13[16] = {
|
||||
static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
@@ -490,12 +525,12 @@ static const cfg_op_t _display_config_13[16] = {
|
||||
};
|
||||
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_config_14[22] = {
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0x9483FFB9},
|
||||
static const cfg_op_t _display_deinit_config_jdi[22] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2139},
|
||||
{DSI_WR_DATA, 0x191919D5},
|
||||
{DSI_WR_DATA, 0x2139}, // MIPI_DSI_DCS_LONG_WRITE: 33 bytes.
|
||||
{DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
@@ -505,95 +540,207 @@ static const cfg_op_t _display_config_14[22] = {
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xB39},
|
||||
{DSI_WR_DATA, 0x4F0F41B1},
|
||||
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
{DSI_WR_DATA, 0x4F0F41B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL.
|
||||
{DSI_WR_DATA, 0xF179A433},
|
||||
{DSI_WR_DATA, 0x2D81},
|
||||
{DSI_WR_DATA, 0x002D81},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439},
|
||||
{DSI_WR_DATA, 0xB9},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
|
||||
{DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
|
||||
{DSI_WR_DATA, 0x191919D6}, // Register: 0xD6.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
{DSI_WR_DATA, 0x711148B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
{DSI_WR_DATA, 0x71143209},
|
||||
{DSI_WR_DATA, 0x114D31}, // (Unknown).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_init_config_invert[3] = {
|
||||
{DSI_WR_DATA, 0x239},
|
||||
{DSI_WR_DATA, 0x02C1}, // INV_EN.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} //DISPLAY_CTRL_MODE: continuous display.
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
||||
};
|
||||
|
||||
//Display A config.
|
||||
static const cfg_op_t cfg_display_framebuffer[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
//Display A config linear pitch.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, 0},
|
||||
{DC_WINBUF_SURFACE_KIND, 0}, //Regular surface.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config linear pitch inverse + Win D support.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0}, //Linear: 0x383FFC, Block: 0x3813FC
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, //Linear: 1279, Block: 0
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 1279}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | V_DIRECTION}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
static const cfg_op_t cfg_display_framebuffer2[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT}, //Enable window C.
|
||||
//Display A config block linear.
|
||||
static const cfg_op_t cfg_display_framebuffer_block[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT}, //Enable window B.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT}, //Enable window A.
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, //T_A8R8G8B8 //NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)}, //Pre-scaled size: 1280x2880 bytes.
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)},
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)}, //Window size: 1280 vertical lines x 720 horizontal pixels.
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //768*2x768*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, 0},
|
||||
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK}, //Regular surface.
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, BLOCK_HEIGHT(4) | BLOCK},
|
||||
{DC_WINBUF_START_ADDR, NYX_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, //Linear: 0x383FFC, Block: 0x3813FC
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, //Linear: 1279, Block: 0
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0x3813FC}, // Linear: 0x383FFC, Block: 0x3813FC.
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0}, // Linear: 1279, Block: 0.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE}, //DSI_ENABLE
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, //Enable window AD. | SCAN_COLUMN | H_DIRECTION
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, //DISPLAY_CTRL_MODE: continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE}, //General update; window A update.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ} //General activation request; window A activation request.
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE | SCAN_COLUMN | H_DIRECTION}, // Enable window AD. | SCAN_COLUMN | H_DIRECTION.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display D config.
|
||||
static const cfg_op_t cfg_display_framebuffer_log[20] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(656 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(656)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(656 * 2) | LINE_STRIDE(656 * 4)}, //656*2x656*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, LOG_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, WIN_BLEND_ENABLE | WIN_K1(200)},
|
||||
{DC_WINBUF_BLEND_MATCH_SELECT, WIN_BLEND_FACT_SRC_COLOR_MATCH_SEL_K1 | WIN_BLEND_FACT_DST_COLOR_MATCH_SEL_NEG_K1},
|
||||
{DC_WIN_WIN_OPTIONS, 0}, // Enable window DD.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_D_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_D_ACT_REQ}
|
||||
};
|
||||
233
bdk/exception_handlers.S
Normal file
233
bdk/exception_handlers.S
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Armv7tdmi Status register.
|
||||
*
|
||||
* bit0: Mode 0.
|
||||
* bit1: Mode 1.
|
||||
* bit2: Mode 2.
|
||||
* bit3: Mode 3.
|
||||
* bit4: Mode 4.
|
||||
* bit5: Thumb state.
|
||||
* bit6: FIQ disable.
|
||||
* bit7: IRQ disable.
|
||||
* bit8-27: Reserved.
|
||||
* bit28: Overflow condition.
|
||||
* bit29: Carry/Borrow/Extend condition.
|
||||
* bit30: Zero condition.
|
||||
* bit31: Negative/Less than condition.
|
||||
*
|
||||
* M[4:0] | Mode | Visible Thumb-state registers | Visible ARM-state registers
|
||||
* 10000 | USER | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
|
||||
* 10001 | FIQ | r0–r7, SP_fiq, LR_fiq, PC, CPSR, SPSR_fiq | r0–r7, r8_fiq–r14_fiq, PC, CPSR, SPSR_fiq
|
||||
* 10010 | IRQ | r0–r7, SP_irq, LR_irq, PC, CPSR, SPSR_irq | r0–r12, r13_irq, r14_irq, PC, CPSR, SPSR_irq
|
||||
* 10011 | SVC | r0–r7, SP_svc, LR_svc, PC, CPSR, SPSR_svc | r0–r12, r13_svc, r14_svc, PC, CPSR, SPSR_svc
|
||||
* 10111 | ABRT | r0–r7, SP_abt, LR_abt, PC, CPSR, SPSR_abt | r0–r12, r13_abt, r14_abt, PC, CPSR, SPSR_abt
|
||||
* 11011 | UNDF | r0–r7, SP_und, LR_und, PC, CPSR, SPSR_und | r0–r12, r13_und, r14_und, PC, CPSR, SPSR_und
|
||||
* 11111 | SYS | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
|
||||
*/
|
||||
|
||||
#define EXCP_EN_ADDR 0x4003FFFC
|
||||
#define EXCP_TYPE_ADDR 0x4003FFF8
|
||||
#define EXCP_LR_ADDR 0x4003FFF4
|
||||
|
||||
#define EXCP_VEC_BASE 0x6000F000
|
||||
#define EVP_COP_RESET_VECTOR 0x200
|
||||
#define EVP_COP_UNDEF_VECTOR 0x204
|
||||
#define EVP_COP_SWI_VECTOR 0x208
|
||||
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
|
||||
#define EVP_COP_DATA_ABORT_VECTOR 0x210
|
||||
#define EVP_COP_RSVD_VECTOR 0x214
|
||||
#define EVP_COP_IRQ_VECTOR 0x218
|
||||
#define EVP_COP_FIQ_VECTOR 0x21C
|
||||
|
||||
#define MODE_USR 0x10
|
||||
#define MODE_FIQ 0x11
|
||||
#define MODE_IRQ 0x12
|
||||
#define MODE_SVC 0x13
|
||||
#define MODE_ABT 0x17
|
||||
#define MODE_UDF 0x1B
|
||||
#define MODE_SYS 0x1F
|
||||
#define MODE_MASK 0x1F
|
||||
|
||||
#define FIQ 0x40
|
||||
#define IRQ 0x80
|
||||
|
||||
.section .text._irq_setup
|
||||
.arm
|
||||
|
||||
.extern ipl_main
|
||||
.type ipl_main, %function
|
||||
|
||||
.extern svc_handler
|
||||
.type svc_handler, %function
|
||||
|
||||
.extern irq_handler
|
||||
.type irq_handler, %function
|
||||
|
||||
.extern fiq_setup
|
||||
.type fiq_setup, %function
|
||||
|
||||
.extern fiq_handler
|
||||
.type fiq_handler, %function
|
||||
|
||||
.globl _irq_setup
|
||||
.type _irq_setup, %function
|
||||
_irq_setup:
|
||||
MRS R0, CPSR
|
||||
BIC R0, R0, #MODE_MASK /* Clear mode bits */
|
||||
ORR R0, R0, #(MODE_SVC | IRQ | FIQ) /* SUPERVISOR mode, IRQ/FIQ disabled */
|
||||
MSR CPSR, R0
|
||||
|
||||
/* Setup IRQ stack pointer */
|
||||
MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x40040000
|
||||
|
||||
/* Setup SYS stack pointer */
|
||||
MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
|
||||
LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
|
||||
|
||||
MOV LR, PC
|
||||
BL setup_vectors
|
||||
/*BL fiq_setup*/
|
||||
|
||||
/* Enable interrupts */
|
||||
BL irq_enable_cpu_irq_exceptions
|
||||
|
||||
B ipl_main
|
||||
B .
|
||||
|
||||
_reset:
|
||||
LDR R0, =EXCP_EN_ADDR
|
||||
LDR R1, =0x30505645 /* EVP0 */
|
||||
STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
|
||||
LDR R0, =EXCP_LR_ADDR
|
||||
MOV R1, LR
|
||||
STR R1, [R0] /* Save LR in EXCP_LR_ADDR */
|
||||
LDR R0, =__bss_start
|
||||
EOR R1, R1, R1
|
||||
LDR R2, =__bss_end
|
||||
SUB R2, R2, R0
|
||||
BL memset
|
||||
B _irq_setup
|
||||
|
||||
_reset_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x545352 /* RST */
|
||||
STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
|
||||
_undefined_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x464455 /* UDF */
|
||||
STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
|
||||
_prefetch_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424150 /* PABT */
|
||||
STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
|
||||
_data_abort_handler:
|
||||
LDR R0, =EXCP_TYPE_ADDR
|
||||
LDR R1, =0x54424144 /* DABT */
|
||||
STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
|
||||
B _reset
|
||||
|
||||
.globl irq_enable_cpu_irq_exceptions
|
||||
.type irq_enable_cpu_irq_exceptions, %function
|
||||
irq_enable_cpu_irq_exceptions:
|
||||
MRS R12, CPSR
|
||||
BIC R12, R12, #(IRQ | FIQ) /* IRQ/FIQ enabled */
|
||||
MSR CPSR, R12
|
||||
BX LR
|
||||
|
||||
.globl irq_disable_cpu_irq_exceptions
|
||||
.type irq_disable_cpu_irq_exceptions, %function
|
||||
irq_disable_cpu_irq_exceptions:
|
||||
MRS R12, CPSR
|
||||
ORR R12, R12, #(IRQ | FIQ) /* IRQ/FIQ disabled */
|
||||
MSR CPSR, R12
|
||||
BX LR
|
||||
|
||||
_irq_handler:
|
||||
MOV R13, R0 /* Save R0 in R13_IRQ */
|
||||
SUB R0, LR, #4 /* Put return address in R0_SYS */
|
||||
MOV LR, R1 /* Save R1 in R14_IRQ (LR) */
|
||||
MRS R1, SPSR /* Put the SPSR in R1_SYS */
|
||||
|
||||
MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
|
||||
STMFD SP!, {R0, R1} /* SPSR and PC */
|
||||
STMFD SP!, {R2-R3, R12, LR} /* AAPCS-clobbered registers */
|
||||
MOV R0, SP /* Make SP_SYS visible to IRQ mode */
|
||||
SUB SP, SP, #8 /* Make room for stacking R0 and R1 */
|
||||
|
||||
MSR CPSR_c, #(MODE_IRQ | IRQ) /* IRQ mode, IRQ disabled */
|
||||
STMFD R0!, {R13, R14} /* Finish saving the context (R0, R1) */
|
||||
|
||||
MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
|
||||
LDR R12, =irq_handler
|
||||
MOV LR, PC /* Copy the return address to link register */
|
||||
BX R12 /* Call the C IRQ handler (ARM/THUMB) */
|
||||
|
||||
MSR CPSR_c, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
|
||||
MOV R0, SP /* Make SP_SYS visible to IRQ mode */
|
||||
ADD SP, SP, #32 /* Fake unstacking 8 registers from SP_SYS */
|
||||
|
||||
MSR CPSR_c, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
|
||||
MOV SP, R0 /* Copy SP_SYS to SP_IRQ */
|
||||
LDR R0, [SP, #28] /* Load the saved SPSR from the stack */
|
||||
MSR SPSR_cxsf, R0 /* Copy it into SPSR_IRQ */
|
||||
|
||||
LDMFD SP, {R0-R3, R12, LR}^ /* Unstack all saved USER/SYSTEM registers */
|
||||
NOP /* Cant access barked registers immediately */
|
||||
LDR LR, [SP, #24] /* Load return address from the SYS stack */
|
||||
MOVS PC, LR /* Return restoring CPSR from SPSR */
|
||||
|
||||
_fiq_handler:
|
||||
BL fiq_handler
|
||||
|
||||
setup_vectors:
|
||||
/* Setup vectors */
|
||||
LDR R0, =EXCP_VEC_BASE
|
||||
|
||||
LDR R1, =_reset_handler
|
||||
STR R1, [R0, #EVP_COP_RESET_VECTOR]
|
||||
|
||||
LDR R1, =_undefined_handler
|
||||
STR R1, [R0, #EVP_COP_UNDEF_VECTOR]
|
||||
|
||||
LDR R1, =_reset_handler
|
||||
STR R1, [R0, #EVP_COP_SWI_VECTOR]
|
||||
|
||||
LDR R1, =_prefetch_abort_handler
|
||||
STR R1, [R0, #EVP_COP_PREFETCH_ABORT_VECTOR]
|
||||
|
||||
LDR R1, =_data_abort_handler
|
||||
STR R1, [R0, #EVP_COP_DATA_ABORT_VECTOR]
|
||||
|
||||
LDR R1, =_reset_handler
|
||||
STR R1, [R0, #EVP_COP_RSVD_VECTOR]
|
||||
|
||||
LDR R1, =_irq_handler
|
||||
STR R1, [R0, #EVP_COP_IRQ_VECTOR]
|
||||
|
||||
LDR R1, =_fiq_handler
|
||||
STR R1, [R0, #EVP_COP_FIQ_VECTOR]
|
||||
|
||||
BX LR
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -14,11 +14,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CLUSTER_H_
|
||||
#define _CLUSTER_H_
|
||||
#ifndef _FATFS_CFG_H_
|
||||
#define _FATFS_CFG_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void cluster_boot_cpu0(u32 entry);
|
||||
#ifdef FFCFG_INC
|
||||
#include FFCFG_INC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -14,6 +14,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../utils/types.h"
|
||||
#ifndef _GFX_UTILS_H_
|
||||
#define _GFX_UTILS_H_
|
||||
|
||||
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles);
|
||||
#ifdef GFX_INC
|
||||
#include GFX_INC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -22,10 +22,10 @@
|
||||
#include "elfarch.h"
|
||||
#include "elf.h"
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "../../gfx/gfx.h"
|
||||
#include <gfx_utils.h>
|
||||
#define EL_DEBUG(format, ...) \
|
||||
gfx_printf(format __VA_OPT__(, ) __VA_ARGS__)
|
||||
#else
|
||||
@@ -18,33 +18,36 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "ianos.h"
|
||||
#include "../utils/types.h"
|
||||
#include "../libs/elfload/elfload.h"
|
||||
#include "../../common/common_module.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "elfload/elfload.h"
|
||||
#include <module.h>
|
||||
#include <mem/heap.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define DRAM_LIB_ADDR 0xE0000000
|
||||
|
||||
extern heap_t _heap;
|
||||
|
||||
extern void *sd_file_read(const char *path, u32 *fsize);
|
||||
extern bool sd_mount();
|
||||
extern void sd_unmount();
|
||||
|
||||
void *elfBuf = NULL;
|
||||
void *fileBuf = NULL;
|
||||
|
||||
static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
||||
{
|
||||
bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));
|
||||
bdkParameters->gfxCon = &gfx_con;
|
||||
bdkParameters->gfxCtx = &gfx_ctxt;
|
||||
bdkParameters->gfxCon = (void *)&gfx_con;
|
||||
bdkParameters->gfxCtx = (void *)&gfx_ctxt;
|
||||
bdkParameters->memcpy = (memcpy_t)&memcpy;
|
||||
bdkParameters->memset = (memset_t)&memset;
|
||||
bdkParameters->sharedHeap = &_heap;
|
||||
|
||||
// Extra functions.
|
||||
bdkParameters->extension_magic = IANOS_EXT0;
|
||||
bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage;
|
||||
|
||||
entrypoint(moduleConfig, bdkParameters);
|
||||
}
|
||||
|
||||
@@ -66,26 +69,20 @@ static bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t o
|
||||
}
|
||||
|
||||
//TODO: Support shared libraries.
|
||||
uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig)
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
||||
{
|
||||
el_ctx ctx;
|
||||
uintptr_t epaddr = 0;
|
||||
|
||||
if (sdmount)
|
||||
{
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
// Read library.
|
||||
fileBuf = sd_file_read(path, NULL);
|
||||
|
||||
if (sdmount)
|
||||
sd_unmount();
|
||||
|
||||
if (!fileBuf)
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
|
||||
el_ctx ctx;
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
@@ -97,7 +94,6 @@ uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleCon
|
||||
case EXEC_ELF:
|
||||
case AR64_ELF:
|
||||
elfBuf = (void *)DRAM_LIB_ADDR;
|
||||
sd_unmount();
|
||||
break;
|
||||
default:
|
||||
elfBuf = malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
@@ -126,6 +122,5 @@ elfFreeOut:
|
||||
fileBuf = NULL;
|
||||
|
||||
elfLoadFinalOut:
|
||||
|
||||
return epaddr;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef IANOS_H
|
||||
#define IANOS_H
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -29,6 +29,6 @@ typedef enum
|
||||
KEEP_IN_RAM = (1 << 31) // Shared library mask.
|
||||
} elfType_t;
|
||||
|
||||
uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void* config);
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void* config);
|
||||
|
||||
#endif
|
||||
156
bdk/input/als.c
Normal file
156
bdk/input/als.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Ambient light sensor driver for Nintendo Switch's Rohm BH1730
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "als.h"
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
|
||||
#define BH1730_DEFAULT_ICYCLE 38
|
||||
|
||||
#define BH1730_INTERNAL_CLOCK_NS 2800
|
||||
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
|
||||
#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
|
||||
|
||||
#define BH1730_DEFAULT_ITIME_MS 100
|
||||
|
||||
#define BH1730_LUX_MULTIPLIER 3600
|
||||
#define BH1730_LUX_MULTIPLIER_AULA 1410
|
||||
|
||||
#define BH1730_LUX_MAX 100000
|
||||
|
||||
typedef struct _opt_win_cal_t
|
||||
{
|
||||
u32 rc;
|
||||
u32 cv;
|
||||
u32 ci;
|
||||
} opt_win_cal_t;
|
||||
|
||||
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_default[] = {
|
||||
{ 500, 5002, 7502 },
|
||||
{ 754, 2250, 2000 },
|
||||
{ 1029, 1999, 1667 },
|
||||
{ 1373, 884, 583 },
|
||||
{ 1879, 309, 165 }
|
||||
};
|
||||
|
||||
// Nintendo Switch Aula Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_aula[] = {
|
||||
{ 231, 9697, 30300 },
|
||||
{ 993, 3333, 2778 },
|
||||
{ 1478, 1621, 1053 },
|
||||
{ 7500, 81, 10 }
|
||||
};
|
||||
|
||||
const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
||||
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||
{
|
||||
if (gain > BH1730_GAIN_128X)
|
||||
gain = BH1730_GAIN_128X;
|
||||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
als_ctxt->gain = gain;
|
||||
als_ctxt->cycle = cycle;
|
||||
}
|
||||
|
||||
void get_als_lux(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
u32 data[2];
|
||||
u32 visible_light;
|
||||
u32 ir_light;
|
||||
u64 lux = 0;
|
||||
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
|
||||
|
||||
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
|
||||
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
|
||||
visible_light = data[0];
|
||||
ir_light = data[1];
|
||||
|
||||
als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
|
||||
als_ctxt->vi_light = visible_light;
|
||||
als_ctxt->ir_light = ir_light;
|
||||
|
||||
if (!visible_light)
|
||||
{
|
||||
als_ctxt->lux = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set calibration parameters.
|
||||
u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
|
||||
u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
|
||||
const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
|
||||
|
||||
// Apply optical window calibration coefficients.
|
||||
for (u32 i = 0; i < opt_win_cal_count; i++)
|
||||
{
|
||||
if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
|
||||
{
|
||||
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
|
||||
lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
|
||||
lux /= 1000;
|
||||
|
||||
if (lux > BH1730_LUX_MAX)
|
||||
lux = BH1730_LUX_MAX;
|
||||
|
||||
als_ctxt->lux = lux;
|
||||
}
|
||||
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
// Enable power to ALS IC.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Init I2C2.
|
||||
pinmux_config_i2c(I2C_2);
|
||||
clock_enable_i2c(I2C_2);
|
||||
i2c_init(I2C_2);
|
||||
|
||||
// Initialize ALS.
|
||||
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
|
||||
|
||||
set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef __ALS_H_
|
||||
#define __ALS_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BH1730_I2C_ADDR 0x29
|
||||
|
||||
@@ -45,21 +45,21 @@
|
||||
#define BH1730_DATA1LOW_REG 0x16
|
||||
#define BH1730_DATA1HIGH_REG 0x17
|
||||
|
||||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | reg)
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | cmd)
|
||||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
|
||||
|
||||
typedef struct _als_table_t
|
||||
typedef struct _als_ctxt_t
|
||||
{
|
||||
float lux;
|
||||
u32 lux;
|
||||
bool over_limit;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 itime;
|
||||
} als_table_t;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 cycle;
|
||||
} als_ctxt_t;
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
|
||||
void get_als_lux(als_table_t *als_val);
|
||||
u8 als_init(als_table_t *als_val);
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
|
||||
void get_als_lux(als_ctxt_t *als_ctxt);
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt);
|
||||
|
||||
#endif /* __ALS_H_ */
|
||||
928
bdk/input/joycon.c
Normal file
928
bdk/input/joycon.c
Normal file
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* Joy-Con UART driver for Nintendo Switch
|
||||
*
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "joycon.h"
|
||||
#include <gfx_utils.h>
|
||||
#include <power/max17050.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/uart.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
// For disabling driver when logging is enabled.
|
||||
#include <libs/lv_conf.h>
|
||||
|
||||
#define JC_WIRED_CMD 0x91
|
||||
#define JC_WIRED_HID 0x92
|
||||
#define JC_WIRED_INIT_REPLY 0x94
|
||||
#define JC_INIT_HANDSHAKE 0xA5
|
||||
|
||||
#define JC_HORI_INPUT_RPT_CMD 0x9A
|
||||
#define JC_HORI_INPUT_RPT 0x00
|
||||
|
||||
#define JC_WIRED_CMD_MAC 0x01
|
||||
#define JC_WIRED_CMD_10 0x10
|
||||
|
||||
#define JC_HID_OUTPUT_RPT 0x01
|
||||
#define JC_HID_RUMBLE_RPT 0x10
|
||||
|
||||
#define JC_HID_INPUT_RPT 0x30
|
||||
#define JC_HID_SUBMCD_RPT 0x21
|
||||
|
||||
#define JC_HID_SUBCMD_HCI_STATE 0x06
|
||||
#define HCI_STATE_SLEEP 0x00
|
||||
#define HCI_STATE_RECONNECT 0x01
|
||||
#define HCI_STATE_PAIR 0x02
|
||||
#define HCI_STATE_HOME 0x04
|
||||
#define JC_HID_SUBCMD_SPI_READ 0x10
|
||||
#define SPI_READ_OFFSET 0x20
|
||||
#define JC_HID_SUBCMD_RUMBLE_CTL 0x48
|
||||
#define JC_HID_SUBCMD_SND_RUMBLE 0xFF
|
||||
|
||||
#define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status.
|
||||
#define JC_BTN_MASK_R 0x0056FF
|
||||
|
||||
#define JC_ID_L 0x01
|
||||
#define JC_ID_R 0x02
|
||||
#define JC_ID_HORI 0x20
|
||||
|
||||
#define JC_CRC8_INIT 0x00
|
||||
#define JC_CRC8_POLY 0x8D
|
||||
|
||||
enum
|
||||
{
|
||||
JC_BATT_EMTPY = 0,
|
||||
JC_BATT_CRIT = 2,
|
||||
JC_BATT_LOW = 4,
|
||||
JC_BATT_MID = 6,
|
||||
JC_BATT_FULL = 8
|
||||
};
|
||||
|
||||
static const u8 init_jc[] = {
|
||||
0xA1, 0xA2, 0xA3, 0xA4
|
||||
};
|
||||
|
||||
static const u8 init_handshake[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_INIT_HANDSHAKE, 0x02, // Wired cmd and wired subcmd.
|
||||
0x01, 0x7E, 0x00, 0x00, 0x00 // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 init_get_info[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_WIRED_CMD, JC_WIRED_CMD_MAC, // Wired cmd and subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 init_finalize[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_WIRED_CMD, JC_WIRED_CMD_10, // Wired cmd and subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 nx_pad_status[] = {
|
||||
0x19, 0x01, 0x03, 0x08, 0x00, // Uart header.
|
||||
JC_WIRED_HID, 0x00, // Wired cmd and hid cmd.
|
||||
0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data and crc.
|
||||
};
|
||||
|
||||
static const u8 hori_pad_status[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_HORI_INPUT_RPT_CMD, 0x01, // Hori cmd and hori subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x48 // Hori cmd data and crc.
|
||||
};
|
||||
|
||||
typedef struct _jc_uart_hdr_t
|
||||
{
|
||||
u8 magic[3];
|
||||
u8 total_size_lsb;
|
||||
u8 total_size_msb;
|
||||
} jc_uart_hdr_t;
|
||||
|
||||
typedef struct _jc_wired_hdr_t
|
||||
{
|
||||
jc_uart_hdr_t uart_hdr;
|
||||
u8 cmd;
|
||||
u8 data[5];
|
||||
u8 crc;
|
||||
u8 payload[];
|
||||
} jc_wired_hdr_t;
|
||||
|
||||
typedef struct _jc_hid_out_rpt_t
|
||||
{
|
||||
u8 cmd;
|
||||
u8 pkt_id;
|
||||
u8 rumble[8];
|
||||
u8 subcmd;
|
||||
u8 subcmd_data[];
|
||||
} jc_hid_out_rpt_t;
|
||||
|
||||
typedef struct _jc_hid_out_spi_read_t
|
||||
{
|
||||
u32 addr;
|
||||
u8 size;
|
||||
} jc_hid_out_spi_read_t;
|
||||
|
||||
typedef struct _jc_hid_in_rpt_t
|
||||
{
|
||||
u8 cmd;
|
||||
u8 pkt_id;
|
||||
u8 conn_info:4;
|
||||
u8 batt_info:4;
|
||||
u8 btn_right;
|
||||
u8 btn_shared;
|
||||
u8 btn_left;
|
||||
u8 stick_h_left;
|
||||
u8 stick_m_left;
|
||||
u8 stick_v_left;
|
||||
u8 stick_h_right;
|
||||
u8 stick_m_right;
|
||||
u8 stick_v_right;
|
||||
u8 vib_decider;
|
||||
u8 submcd_ack;
|
||||
u8 subcmd;
|
||||
u8 subcmd_data[];
|
||||
} jc_hid_in_rpt_t;
|
||||
|
||||
typedef struct _jc_hid_in_spi_read_t
|
||||
{
|
||||
u32 addr;
|
||||
u8 size;
|
||||
u8 data[];
|
||||
} jc_hid_in_spi_read_t;
|
||||
|
||||
typedef struct _jc_hid_in_pair_data_t
|
||||
{
|
||||
u8 magic;
|
||||
u8 size;
|
||||
u16 checksum;
|
||||
u8 mac[6];
|
||||
u8 ltk[16];
|
||||
u8 pad0[10];
|
||||
u8 bt_caps; // bit3: Secure conn supported host, bit5: Paired to TBFC supported host, bit6: iTBFC page supported
|
||||
u8 pad1;
|
||||
} jc_hid_in_pair_data_t;
|
||||
|
||||
typedef struct _joycon_ctxt_t
|
||||
{
|
||||
u8 buf[0x100]; //FIXME: If heap is used, dumping breaks.
|
||||
u8 uart;
|
||||
u8 type;
|
||||
u8 mac[6];
|
||||
u32 hw_init_done;
|
||||
u32 last_received_time;
|
||||
u32 last_status_req_time;
|
||||
u8 rumble_sent;
|
||||
u8 connected;
|
||||
} joycon_ctxt_t;
|
||||
|
||||
static joycon_ctxt_t jc_l = {0};
|
||||
static joycon_ctxt_t jc_r = {0};
|
||||
|
||||
static bool jc_init_done = false;
|
||||
static u32 hid_pkt_inc = 0;
|
||||
|
||||
static jc_gamepad_rpt_t jc_gamepad;
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable);
|
||||
|
||||
static u8 jc_crc(u8 *data, u16 len)
|
||||
{
|
||||
u8 crc = JC_CRC8_INIT;
|
||||
u16 i, j;
|
||||
for (i = 0; i < len; i++) {
|
||||
crc ^= data[i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((crc & 0x80) != 0)
|
||||
crc = (u8)((crc << 1) ^ JC_CRC8_POLY);
|
||||
else
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
void joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
|
||||
{
|
||||
uart_send(uart_port, buf, size);
|
||||
uart_wait_idle(uart_port, UART_TX_IDLE);
|
||||
}
|
||||
|
||||
static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc)
|
||||
{
|
||||
out->uart_hdr.magic[0] = 0x19;
|
||||
out->uart_hdr.magic[1] = 0x01;
|
||||
out->uart_hdr.magic[2] = 0x3;
|
||||
|
||||
out->uart_hdr.total_size_lsb = sizeof(jc_wired_hdr_t) - sizeof(jc_uart_hdr_t);
|
||||
out->uart_hdr.total_size_msb = 0;
|
||||
out->cmd = wired_cmd;
|
||||
|
||||
if (data)
|
||||
memcpy(out->data, data, size);
|
||||
|
||||
out->crc = crc ? jc_crc(&out->uart_hdr.total_size_msb, sizeof(out->uart_hdr.total_size_msb) + sizeof(out->cmd) + sizeof(out->data)) : 0;
|
||||
|
||||
return sizeof(jc_wired_hdr_t);
|
||||
}
|
||||
|
||||
static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u16 pkt_size = jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
|
||||
pkt_size += size;
|
||||
|
||||
rpt->uart_hdr.total_size_lsb += size;
|
||||
rpt->data[0] = size >> 8;
|
||||
rpt->data[1] = size & 0xFF;
|
||||
|
||||
if (payload)
|
||||
memcpy(rpt->payload, payload, size);
|
||||
|
||||
return pkt_size;
|
||||
}
|
||||
|
||||
void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u8 rpt[0x50];
|
||||
memset(rpt, 0, sizeof(rpt));
|
||||
|
||||
u32 rpt_size = jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc);
|
||||
|
||||
joycon_send_raw(uart, rpt, rpt_size);
|
||||
}
|
||||
|
||||
static u8 jc_hid_pkt_id_incr()
|
||||
{
|
||||
u8 curr_id = hid_pkt_inc;
|
||||
hid_pkt_inc++;
|
||||
|
||||
return (curr_id & 0xF);
|
||||
}
|
||||
|
||||
void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
||||
{
|
||||
u8 temp[0x30];
|
||||
u8 rumble_neutral[8] = {0x00, 0x01, 0x40, 0x40, 0x00, 0x01, 0x40, 0x40};
|
||||
u8 rumble_init[8] = {0xc2, 0xc8, 0x03, 0x72, 0xc2, 0xc8, 0x03, 0x72};
|
||||
|
||||
memset(temp, 0, sizeof(temp));
|
||||
|
||||
jc_hid_out_rpt_t *hid_pkt = (jc_hid_out_rpt_t *)temp;
|
||||
|
||||
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
||||
|
||||
if (subcmd == JC_HID_SUBCMD_SND_RUMBLE)
|
||||
{
|
||||
bool send_r_rumble = jc_r.connected && !jc_r.rumble_sent;
|
||||
bool send_l_rumble = jc_l.connected && !jc_l.rumble_sent;
|
||||
|
||||
// Enable rumble.
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||
hid_pkt->subcmd_data[0] = 1;
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
|
||||
// Send rumble.
|
||||
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false);
|
||||
|
||||
msleep(15);
|
||||
|
||||
// Disable rumble.
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||
hid_pkt->subcmd_data[0] = 0;
|
||||
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI);
|
||||
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = subcmd;
|
||||
if (data)
|
||||
memcpy(hid_pkt->subcmd_data, data, size);
|
||||
|
||||
jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
||||
}
|
||||
}
|
||||
|
||||
static void jc_charging_decider(u8 batt, u8 uart)
|
||||
{
|
||||
u32 system_batt_enough = max17050_get_cached_batt_volt() > 4000;
|
||||
|
||||
// Power supply control based on battery levels and charging.
|
||||
if ((batt >> 1 << 1) < JC_BATT_LOW) // Level without checking charging.
|
||||
jc_power_supply(uart, true);
|
||||
else if (batt > (system_batt_enough ? JC_BATT_FULL : JC_BATT_MID)) // Addresses the charging bit.
|
||||
jc_power_supply(uart, false);
|
||||
}
|
||||
|
||||
static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
||||
{
|
||||
u32 btn_tmp;
|
||||
jc_hid_in_rpt_t *hid_pkt = (jc_hid_in_rpt_t *)packet;
|
||||
|
||||
switch (hid_pkt->cmd)
|
||||
{
|
||||
case JC_HORI_INPUT_RPT:
|
||||
case JC_HID_INPUT_RPT:
|
||||
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||
|
||||
if (jc->type & JC_ID_L)
|
||||
{
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_L;
|
||||
jc_gamepad.buttons |= (btn_tmp & JC_BTN_MASK_L);
|
||||
|
||||
jc_gamepad.lstick_x = hid_pkt->stick_h_left | ((hid_pkt->stick_m_left & 0xF) << 8);
|
||||
jc_gamepad.lstick_y = (hid_pkt->stick_m_left >> 4) | (hid_pkt->stick_v_left << 4);
|
||||
|
||||
jc_gamepad.batt_info_l = hid_pkt->batt_info;
|
||||
}
|
||||
else if (jc->type & JC_ID_R)
|
||||
{
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_R;
|
||||
jc_gamepad.buttons |= (btn_tmp & JC_BTN_MASK_R);
|
||||
|
||||
jc_gamepad.rstick_x = hid_pkt->stick_h_right | ((hid_pkt->stick_m_right & 0xF) << 8);
|
||||
jc_gamepad.rstick_y = (hid_pkt->stick_m_right >> 4) | (hid_pkt->stick_v_right << 4);
|
||||
|
||||
jc_gamepad.batt_info_r = hid_pkt->batt_info;
|
||||
}
|
||||
|
||||
jc_gamepad.conn_l = jc_l.connected;
|
||||
jc_gamepad.conn_r = jc_r.connected;
|
||||
|
||||
jc_charging_decider(hid_pkt->batt_info, jc->uart);
|
||||
break;
|
||||
case JC_HID_SUBMCD_RPT:
|
||||
if (hid_pkt->subcmd == JC_HID_SUBCMD_SPI_READ)
|
||||
{
|
||||
jc_bt_conn_t *bt_conn;
|
||||
|
||||
if (jc->type & JC_ID_L)
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
else
|
||||
bt_conn = &jc_gamepad.bt_conn_r;
|
||||
|
||||
jc_hid_in_spi_read_t *spi_info = (jc_hid_in_spi_read_t *)hid_pkt->subcmd_data;
|
||||
jc_hid_in_pair_data_t *pair_data = (jc_hid_in_pair_data_t *)spi_info->data;
|
||||
|
||||
// Check if we reply is pairing info.
|
||||
if (spi_info->size == 0x1A && pair_data->magic == 0x95 && pair_data->size == 0x22)
|
||||
{
|
||||
bt_conn->type = jc->type;
|
||||
|
||||
memcpy(bt_conn->mac, jc->mac, 6);
|
||||
memcpy(bt_conn->host_mac, pair_data->mac, 6);
|
||||
for (u32 i = 16; i > 0; i--)
|
||||
bt_conn->ltk[16 - i] = pair_data->ltk[i - 1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
jc->last_received_time = get_tmr_ms();
|
||||
}
|
||||
|
||||
static void jc_parse_wired_init(joycon_ctxt_t *jc, const u8* data, u32 size)
|
||||
{
|
||||
switch (data[0])
|
||||
{
|
||||
case JC_WIRED_CMD_MAC:
|
||||
for (int i = 12; i > 6; i--)
|
||||
jc->mac[12 - i] = data[i];
|
||||
jc->type = data[6];
|
||||
jc->connected = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void jc_uart_pkt_parse(joycon_ctxt_t *jc, const u8* packet, size_t size)
|
||||
{
|
||||
jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)packet;
|
||||
switch (pkt->cmd)
|
||||
{
|
||||
case JC_HORI_INPUT_RPT_CMD:
|
||||
case JC_WIRED_HID:
|
||||
jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
|
||||
break;
|
||||
case JC_WIRED_INIT_REPLY:
|
||||
jc_parse_wired_init(jc, pkt->data, size - sizeof(jc_uart_hdr_t) - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void jc_rcv_pkt(joycon_ctxt_t *jc)
|
||||
{
|
||||
if (gpio_read(GPIO_PORT_E, GPIO_PIN_6) && jc->uart == UART_C)
|
||||
return;
|
||||
else if (gpio_read(GPIO_PORT_H, GPIO_PIN_6) && jc->uart == UART_B)
|
||||
return;
|
||||
|
||||
// Check if device stopped sending data.
|
||||
u32 uart_irq = uart_get_IIR(jc->uart);
|
||||
if (uart_irq != UART_IIR_REDI)
|
||||
return;
|
||||
|
||||
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
|
||||
|
||||
// Check valid size and uart reply magic.
|
||||
if (len > 7 && !memcmp(jc->buf, "\x19\x81\x03", 3))
|
||||
{
|
||||
jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)(jc->buf);
|
||||
|
||||
jc_uart_pkt_parse(jc, jc->buf, pkt->uart_hdr.total_size_lsb + sizeof(jc_uart_hdr_t));
|
||||
}
|
||||
}
|
||||
|
||||
static bool jc_send_init_rumble(joycon_ctxt_t *jc)
|
||||
{
|
||||
// Send init rumble or request nx pad status report.
|
||||
if ((jc_r.connected && !jc_r.rumble_sent) || (jc_l.connected && !jc_l.rumble_sent))
|
||||
{
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
jc_send_hid_cmd(jc->uart, JC_HID_SUBCMD_SND_RUMBLE, NULL, 0);
|
||||
|
||||
if (jc_l.connected)
|
||||
jc_l.rumble_sent = true;
|
||||
if (jc_r.connected)
|
||||
jc_r.rumble_sent = true;
|
||||
|
||||
if (jc->uart != UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
else
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
||||
{
|
||||
bool is_nxpad = !(jc->type & JC_ID_HORI);
|
||||
|
||||
if (is_nxpad)
|
||||
{
|
||||
bool sent_rumble = jc_send_init_rumble(jc);
|
||||
|
||||
if (sent_rumble)
|
||||
return;
|
||||
}
|
||||
|
||||
if (jc->last_status_req_time > get_tmr_ms() || !jc->connected)
|
||||
return;
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
if (jc->uart == UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
else
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
if (is_nxpad)
|
||||
joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
|
||||
else
|
||||
joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
if (jc->uart == UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
else
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
|
||||
jc->last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
|
||||
{
|
||||
u8 crc = 0;
|
||||
for (u32 i = 0; i < 0x22; i++)
|
||||
crc += buf[4 + i];
|
||||
|
||||
crc += 0x68; // Host is Switch.
|
||||
|
||||
if ((crc ^ 0x55) == buf[2])
|
||||
*is_hos = true;
|
||||
|
||||
crc -= 0x68;
|
||||
crc += 0x08; // Host is PC.
|
||||
|
||||
if (*is_hos || (crc ^ 0x55) == buf[2])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
|
||||
{
|
||||
u8 retries;
|
||||
jc_bt_conn_t *bt_conn;
|
||||
|
||||
if (!jc_init_done)
|
||||
return NULL;
|
||||
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
|
||||
bt_conn = &jc_gamepad.bt_conn_r;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
|
||||
while (jc_l.last_status_req_time > get_tmr_ms())
|
||||
{
|
||||
jc_rcv_pkt(&jc_r);
|
||||
jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
|
||||
jc_hid_in_spi_read_t subcmd_data_l;
|
||||
subcmd_data_l.addr = 0x2000;
|
||||
subcmd_data_l.size = 0x1A;
|
||||
|
||||
jc_hid_in_spi_read_t subcmd_data_r;
|
||||
subcmd_data_r.addr = 0x2000;
|
||||
subcmd_data_r.size = 0x1A;
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
bool jc_r_found = jc_r.connected ? false : true;
|
||||
bool jc_l_found = jc_l.connected ? false : true;
|
||||
|
||||
u32 total_retries = 10;
|
||||
retry:
|
||||
retries = 10;
|
||||
while (retries)
|
||||
{
|
||||
u32 time_now = get_tmr_ms();
|
||||
if ((!jc_l_found && jc_l.last_status_req_time < time_now) || (!jc_r_found && jc_r.last_status_req_time < time_now))
|
||||
{
|
||||
if (!jc_l_found)
|
||||
{
|
||||
jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
||||
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
||||
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
retries--;
|
||||
}
|
||||
|
||||
if (!jc_l_found)
|
||||
{
|
||||
memset(jc_l.buf, 0, 0x100);
|
||||
jc_rcv_pkt(&jc_l);
|
||||
|
||||
bool is_hos = false;
|
||||
if (_jc_validate_pairing_info(&jc_l.buf[SPI_READ_OFFSET], &is_hos))
|
||||
{
|
||||
bool is_active = jc_l.buf[SPI_READ_OFFSET] == 0x95;
|
||||
|
||||
if (!is_active)
|
||||
subcmd_data_l.addr += 0x26; // Get next slot.
|
||||
else
|
||||
jc_l_found = true; // Entry is active.
|
||||
|
||||
if (jc_l_found && is_hos)
|
||||
*is_l_hos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
memset(jc_r.buf, 0, 0x100);
|
||||
jc_rcv_pkt(&jc_r);
|
||||
|
||||
bool is_hos = false;
|
||||
if (_jc_validate_pairing_info(&jc_r.buf[SPI_READ_OFFSET], &is_hos))
|
||||
{
|
||||
bool is_active = jc_r.buf[SPI_READ_OFFSET] == 0x95;
|
||||
|
||||
if (!is_active)
|
||||
subcmd_data_r.addr += 0x26; // Get next slot.
|
||||
else
|
||||
jc_r_found = true; // Entry is active.
|
||||
|
||||
if (jc_r_found && is_hos)
|
||||
*is_r_hos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (jc_l_found && jc_r_found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!jc_l_found || !jc_r_found)
|
||||
{
|
||||
if (total_retries)
|
||||
{
|
||||
total_retries--;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!jc_l_found)
|
||||
{
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
bt_conn = &jc_gamepad.bt_conn_r;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
|
||||
return &jc_gamepad;
|
||||
}
|
||||
|
||||
void jc_deinit()
|
||||
{
|
||||
// Disable power.
|
||||
jc_power_supply(UART_B, false);
|
||||
jc_power_supply(UART_C, false);
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
// Send sleep command.
|
||||
u8 data = HCI_STATE_SLEEP;
|
||||
|
||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||
{
|
||||
jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
jc_rcv_pkt(&jc_r);
|
||||
}
|
||||
if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
|
||||
{
|
||||
jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
|
||||
// Disable UART B and C clocks.
|
||||
clock_disable_uart(UART_B);
|
||||
clock_disable_uart(UART_C);
|
||||
}
|
||||
|
||||
static void jc_init_conn(joycon_ctxt_t *jc)
|
||||
{
|
||||
if (((u32)get_tmr_ms() - jc->last_received_time) > 1000)
|
||||
{
|
||||
jc_power_supply(jc->uart, true);
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
if (jc->uart == UART_B)
|
||||
{
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_R;
|
||||
jc_gamepad.conn_r = false;
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_L;
|
||||
jc_gamepad.conn_l = false;
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
}
|
||||
|
||||
uart_init(jc->uart, 1000000);
|
||||
uart_invert(jc->uart, true, UART_INVERT_TXD);
|
||||
uart_set_IIR(jc->uart);
|
||||
|
||||
joycon_send_raw(jc->uart, init_jc, 4);
|
||||
joycon_send_raw(jc->uart, init_handshake, sizeof(init_handshake));
|
||||
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
|
||||
joycon_send_raw(jc->uart, init_get_info, sizeof(init_get_info));
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
|
||||
if (!(jc->type & JC_ID_HORI))
|
||||
{
|
||||
joycon_send_raw(jc->uart, init_finalize, sizeof(init_finalize));
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
}
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
if (jc->uart == UART_B)
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
else
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
|
||||
jc->last_received_time = get_tmr_ms();
|
||||
|
||||
if (jc->connected)
|
||||
jc_power_supply(jc->uart, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void jc_conn_check()
|
||||
{
|
||||
// Check if a Joy-Con was disconnected.
|
||||
if (gpio_read(GPIO_PORT_E, GPIO_PIN_6))
|
||||
{
|
||||
jc_power_supply(UART_C, false);
|
||||
|
||||
hid_pkt_inc = 0;
|
||||
|
||||
jc_l.connected = false;
|
||||
jc_l.rumble_sent = false;
|
||||
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_L;
|
||||
jc_gamepad.conn_l = false;
|
||||
|
||||
jc_gamepad.batt_info_l = 0;
|
||||
jc_gamepad.bt_conn_l.type = 0;
|
||||
}
|
||||
|
||||
if (gpio_read(GPIO_PORT_H, GPIO_PIN_6))
|
||||
{
|
||||
jc_power_supply(UART_B, false);
|
||||
|
||||
hid_pkt_inc = 0;
|
||||
|
||||
jc_r.connected = false;
|
||||
jc_r.rumble_sent = false;
|
||||
|
||||
jc_gamepad.buttons &= ~JC_BTN_MASK_R;
|
||||
jc_gamepad.conn_r = false;
|
||||
|
||||
jc_gamepad.batt_info_r = 0;
|
||||
jc_gamepad.bt_conn_r.type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if (regulator_5v_get_dev_enabled(1 << uart))
|
||||
return;
|
||||
|
||||
regulator_5v_enable(1 << uart);
|
||||
|
||||
if (jc_init_done)
|
||||
{
|
||||
if (uart == UART_C)
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
|
||||
else
|
||||
gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
|
||||
return;
|
||||
}
|
||||
|
||||
if (uart == UART_C)
|
||||
{
|
||||
// Joy-Con(L) Charge Detect.
|
||||
PINMUX_AUX(PINMUX_AUX_SPDIF_IN) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_config(GPIO_PORT_CC, GPIO_PIN_3, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_3, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Joy-Con(R) Charge Detect.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PK3) = PINMUX_DRIVE_4X | PINMUX_PULL_DOWN | 2;
|
||||
gpio_config(GPIO_PORT_K, GPIO_PIN_3, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_K, GPIO_PIN_3, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_HIGH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!regulator_5v_get_dev_enabled(1 << uart))
|
||||
return;
|
||||
|
||||
regulator_5v_disable(1 << uart);
|
||||
|
||||
if (uart == UART_C)
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW);
|
||||
else
|
||||
gpio_write(GPIO_PORT_K, GPIO_PIN_3, GPIO_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void jc_init_hw()
|
||||
{
|
||||
jc_l.uart = UART_C;
|
||||
jc_r.uart = UART_B;
|
||||
|
||||
#if !defined(DEBUG_UART_PORT) || !(DEBUG_UART_PORT)
|
||||
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG)
|
||||
return;
|
||||
|
||||
jc_power_supply(UART_C, true);
|
||||
jc_power_supply(UART_B, true);
|
||||
|
||||
// Joy-Con (R) IsAttached.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PH6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
gpio_config(GPIO_PORT_H, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
|
||||
// Joy-Con (L) IsAttached.
|
||||
PINMUX_AUX(PINMUX_AUX_GPIO_PE6) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE;
|
||||
gpio_config(GPIO_PORT_E, GPIO_PIN_6, GPIO_MODE_GPIO);
|
||||
|
||||
// Configure pinmuxing for UART B and C.
|
||||
pinmux_config_uart(UART_B);
|
||||
pinmux_config_uart(UART_C);
|
||||
|
||||
// Ease the stress to APB.
|
||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
// Enable UART B and C clocks.
|
||||
clock_enable_uart(UART_B);
|
||||
clock_enable_uart(UART_C);
|
||||
|
||||
// Restore OC.
|
||||
bpmp_clk_rate_set(prev_fid);
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
|
||||
jc_init_done = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
jc_gamepad_rpt_t *joycon_poll()
|
||||
{
|
||||
if (!jc_init_done)
|
||||
return NULL;
|
||||
|
||||
if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
|
||||
jc_init_conn(&jc_r);
|
||||
if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
|
||||
jc_init_conn(&jc_l);
|
||||
|
||||
if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
|
||||
jc_req_nx_pad_status(&jc_r);
|
||||
if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
|
||||
jc_req_nx_pad_status(&jc_l);
|
||||
|
||||
if (!gpio_read(GPIO_PORT_H, GPIO_PIN_6))
|
||||
jc_rcv_pkt(&jc_r);
|
||||
if (!gpio_read(GPIO_PORT_E, GPIO_PIN_6))
|
||||
jc_rcv_pkt(&jc_l);
|
||||
|
||||
jc_conn_check();
|
||||
|
||||
return &jc_gamepad;
|
||||
}
|
||||
98
bdk/input/joycon.h
Normal file
98
bdk/input/joycon.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Ambient light sensor driver for Nintendo Switch's Rohm BH1730
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __JOYCON_H_
|
||||
#define __JOYCON_H_
|
||||
|
||||
#include <utils/types.h>
|
||||
|
||||
#define JC_BTNS_DIRECTION_PAD 0xF0000
|
||||
#define JC_BTNS_PREV_NEXT 0x800080
|
||||
#define JC_BTNS_ENTER 0x400008
|
||||
#define JC_BTNS_ESC 0x4
|
||||
|
||||
#define JC_BTNS_ALL (JC_BTNS_PREV_NEXT | JC_BTNS_ENTER | JC_BTNS_DIRECTION_PAD | JC_BTNS_ESC)
|
||||
|
||||
typedef struct _jc_bt_conn_t
|
||||
{
|
||||
u8 type;
|
||||
u8 mac[6];
|
||||
u8 host_mac[6];
|
||||
u8 ltk[16];
|
||||
} jc_bt_conn_t;
|
||||
|
||||
typedef struct _jc_gamepad_rpt_t
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
// Joy-Con (R).
|
||||
u32 y:1;
|
||||
u32 x:1;
|
||||
u32 b:1;
|
||||
u32 a:1;
|
||||
u32 sr_r:1;
|
||||
u32 sl_r:1;
|
||||
u32 r:1;
|
||||
u32 zr:1;
|
||||
|
||||
// Shared
|
||||
u32 minus:1;
|
||||
u32 plus:1;
|
||||
u32 r3:1;
|
||||
u32 l3:1;
|
||||
u32 home:1;
|
||||
u32 cap:1;
|
||||
u32 pad:1;
|
||||
u32 wired:1;
|
||||
|
||||
// Joy-Con (L).
|
||||
u32 down:1;
|
||||
u32 up:1;
|
||||
u32 right:1;
|
||||
u32 left:1;
|
||||
u32 sr_l:1;
|
||||
u32 sl_l:1;
|
||||
u32 l:1;
|
||||
u32 zl:1;
|
||||
};
|
||||
u32 buttons;
|
||||
};
|
||||
|
||||
u16 lstick_x;
|
||||
u16 lstick_y;
|
||||
u16 rstick_x;
|
||||
u16 rstick_y;
|
||||
bool center_stick_l;
|
||||
bool center_stick_r;
|
||||
bool conn_l;
|
||||
bool conn_r;
|
||||
u8 batt_info_l;
|
||||
u8 batt_info_r;
|
||||
jc_bt_conn_t bt_conn_l;
|
||||
jc_bt_conn_t bt_conn_r;
|
||||
} jc_gamepad_rpt_t;
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable);
|
||||
void jc_init_hw();
|
||||
void jc_deinit();
|
||||
jc_gamepad_rpt_t *joycon_poll();
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos);
|
||||
|
||||
#endif
|
||||
461
bdk/input/touch.c
Normal file
461
bdk/input/touch.c
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <soc/clock.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/util.h>
|
||||
#include "touch.h"
|
||||
|
||||
|
||||
#include <gfx_utils.h>
|
||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
|
||||
static touch_panel_info_t _panels[] =
|
||||
{
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },
|
||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },
|
||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },
|
||||
{ 3, 1, 0, 0, "GiS 5.5\"" },
|
||||
{ 4, 0, 0, 1, "Samsung BH2109" },
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" }
|
||||
};
|
||||
|
||||
static int touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
|
||||
if (!res)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd[0], &cmd[1], csize - 1);
|
||||
if (res)
|
||||
res = i2c_recv_buf(buf, size, I2C_3, STMFTS_I2C_ADDR);
|
||||
if (!res)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
{
|
||||
u32 timer = get_tmr_ms() + timeout;
|
||||
while (true)
|
||||
{
|
||||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == event && tmp[2] == status)
|
||||
{
|
||||
if (buf)
|
||||
memcpy(buf, &tmp[3], 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define X_REAL_MAX 1264
|
||||
#define Y_REAL_MAX 704
|
||||
#define EDGE_OFFSET 15
|
||||
|
||||
static void _touch_compensate_limits(touch_event *event, bool touching)
|
||||
{
|
||||
event->x = MAX(event->x, EDGE_OFFSET);
|
||||
event->x = MIN(event->x, X_REAL_MAX);
|
||||
event->x -= EDGE_OFFSET;
|
||||
u32 x_adj = (1280 * 1000) / (X_REAL_MAX - EDGE_OFFSET);
|
||||
event->x = ((u32)event->x * x_adj) / 1000;
|
||||
|
||||
if (touching)
|
||||
{
|
||||
event->y = MAX(event->y, EDGE_OFFSET);
|
||||
event->y = MIN(event->y, Y_REAL_MAX);
|
||||
event->y -= EDGE_OFFSET;
|
||||
u32 y_adj = (720 * 1000) / (Y_REAL_MAX - EDGE_OFFSET);
|
||||
event->y = ((u32)event->y * y_adj) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
static void _touch_process_contact_event(touch_event *event, bool touching)
|
||||
{
|
||||
event->x = (event->raw[2] << 4) | ((event->raw[4] & STMFTS_MASK_Y_LSB) >> 4);
|
||||
|
||||
// Normally, GUI elements have bigger horizontal estate.
|
||||
// Avoid parsing y axis when finger is removed to minimize touch noise.
|
||||
if (touching)
|
||||
{
|
||||
event->y = (event->raw[3] << 4) | (event->raw[4] & STMFTS_MASK_X_MSB);
|
||||
|
||||
event->z = event->raw[5] | (event->raw[6] << 8);
|
||||
event->z = event->z << 6;
|
||||
u16 tmp = 0x40;
|
||||
if ((event->raw[7] & 0x3F) != 1 && (event->raw[7] & 0x3F) != 0x3F)
|
||||
tmp = event->raw[7] & 0x3F;
|
||||
event->z /= tmp + 0x40;
|
||||
|
||||
event->fingers = ((event->raw[1] & STMFTS_MASK_TOUCH_ID) >> 4) + 1;
|
||||
}
|
||||
else
|
||||
event->fingers = 0;
|
||||
|
||||
_touch_compensate_limits(event, touching);
|
||||
}
|
||||
|
||||
static void _touch_parse_event(touch_event *event)
|
||||
{
|
||||
event->type = event->raw[1] & STMFTS_MASK_EVENT_ID;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case STMFTS_EV_MULTI_TOUCH_ENTER:
|
||||
case STMFTS_EV_MULTI_TOUCH_MOTION:
|
||||
_touch_process_contact_event(event, true);
|
||||
if (event->z < 255) // Reject palm rest.
|
||||
event->touch = true;
|
||||
else
|
||||
{
|
||||
event->touch = false;
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
break;
|
||||
case STMFTS_EV_MULTI_TOUCH_LEAVE:
|
||||
event->touch = false;
|
||||
_touch_process_contact_event(event, false);
|
||||
break;
|
||||
case STMFTS_EV_NO_EVENT:
|
||||
if (event->touch)
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_MOTION;
|
||||
break;
|
||||
default:
|
||||
if (event->touch && event->raw[0] == STMFTS_EV_MULTI_TOUCH_MOTION)
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_MOTION;
|
||||
else
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
|
||||
// gfx_con_setpos(0, 300);
|
||||
// DPRINTF("x = %d \ny = %d \nz = %d \n", event->x, event->y, event->z);
|
||||
// DPRINTF("0 = %02X\n1 = %02X\n2 = %02X\n3 = %02X\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02X\n6 = %02X\n7 = %02X\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
}
|
||||
|
||||
void touch_poll(touch_event *event)
|
||||
{
|
||||
i2c_recv_buf_small(event->raw, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_LATEST_EVENT);
|
||||
|
||||
_touch_parse_event(event);
|
||||
}
|
||||
|
||||
touch_event touch_poll_wait()
|
||||
{
|
||||
touch_event event;
|
||||
do
|
||||
{
|
||||
touch_poll(&event);
|
||||
} while (event.type != STMFTS_EV_MULTI_TOUCH_LEAVE);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
touch_info touch_get_info()
|
||||
{
|
||||
touch_info info;
|
||||
u8 buf[8];
|
||||
memset(&buf, 0, 8);
|
||||
i2c_recv_buf_small(buf, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_INFO);
|
||||
|
||||
info.chip_id = buf[0] << 8 | buf[1];
|
||||
info.fw_ver = buf[2] << 8 | buf[3];
|
||||
info.config_id = buf[4];
|
||||
info.config_ver = buf[5];
|
||||
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02X, Cfg Ver: %d\n",
|
||||
// info.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
touch_panel_info_t *touch_get_panel_vendor()
|
||||
{
|
||||
u8 buf[5] = {0};
|
||||
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
||||
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
|
||||
|
||||
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
||||
return NULL;
|
||||
|
||||
if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
|
||||
return NULL;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_panels); i++)
|
||||
{
|
||||
touch_panel_info_t *panel = &_panels[i];
|
||||
if (buf[0] == panel->gpio0 && buf[1] == panel->gpio1 && buf[2] == panel->gpio2)
|
||||
return panel;
|
||||
}
|
||||
|
||||
// Touch panel not found, return current gpios.
|
||||
panel_info.gpio0 = buf[0];
|
||||
panel_info.gpio1 = buf[1];
|
||||
panel_info.gpio2 = buf[2];
|
||||
|
||||
return &panel_info;
|
||||
}
|
||||
|
||||
int touch_get_fw_info(touch_fw_info_t *fw)
|
||||
{
|
||||
u8 buf[8] = {0};
|
||||
|
||||
memset(fw, 0, sizeof(touch_fw_info_t));
|
||||
|
||||
// Get fw address info.
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
||||
int res = touch_read_reg(cmd, 3, buf, 3);
|
||||
if (!res)
|
||||
{
|
||||
// Get fw info.
|
||||
cmd[1] = buf[2]; cmd[2] = buf[1];
|
||||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
if (!res)
|
||||
{
|
||||
fw->fw_id = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
|
||||
fw->ftb_ver = (buf[6] << 8) | buf[5];
|
||||
}
|
||||
|
||||
cmd[2]++;
|
||||
res = touch_read_reg(cmd, 3, buf, 8);
|
||||
if (!res)
|
||||
fw->fw_rev = (buf[7] << 8) | buf[6];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int touch_sys_reset()
|
||||
{
|
||||
u8 cmd[3] = { 0, 0x28, 0x80 }; // System reset cmd.
|
||||
for (u8 retries = 0; retries < 3; retries++)
|
||||
{
|
||||
if (touch_command(STMFTS_WRITE_REG, cmd, 3))
|
||||
{
|
||||
msleep(10);
|
||||
continue;
|
||||
}
|
||||
msleep(10);
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL))
|
||||
continue;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int touch_panel_ito_test(u8 *err)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
// Reset touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return res;
|
||||
|
||||
// Do ITO Production test.
|
||||
u8 cmd[2] = { 1, 0 };
|
||||
if (touch_command(STMFTS_ITO_CHECK, cmd, 2))
|
||||
return res;
|
||||
|
||||
u32 timer = get_tmr_ms() + 2000;
|
||||
while (true)
|
||||
{
|
||||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == 0xF && tmp[2] == 0x5)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
err[0] = tmp[3];
|
||||
err[1] = tmp[4];
|
||||
}
|
||||
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset touchscreen module.
|
||||
touch_sys_reset();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int touch_get_fb_info(u8 *buf)
|
||||
{
|
||||
u8 tmp[5];
|
||||
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0 };
|
||||
int res = 0;
|
||||
|
||||
|
||||
for (u32 i = 0; i < 0x10000; i += 4)
|
||||
{
|
||||
if (!res)
|
||||
{
|
||||
cmd[1] = (i >> 8) & 0xFF;
|
||||
cmd[2] = i & 0xFF;
|
||||
memset(tmp, 0xCC, 5);
|
||||
res = touch_read_reg(cmd, 3, tmp, 5);
|
||||
memcpy(&buf[i], tmp + 1, 4);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int touch_sense_enable()
|
||||
{
|
||||
// Switch sense mode and enable multi-touch sensing.
|
||||
u8 cmd = STMFTS_FINGER_MODE;
|
||||
if (touch_command(STMFTS_SWITCH_SENSE_MODE, &cmd, 1))
|
||||
return 0;
|
||||
|
||||
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
|
||||
return 0;
|
||||
|
||||
if (touch_command(STMFTS_CLEAR_EVENT_STACK, NULL, 0))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int touch_execute_autotune()
|
||||
{
|
||||
// Reset touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return 0;
|
||||
|
||||
// Trim low power oscillator.
|
||||
if (touch_command(STMFTS_LP_TIMER_CALIB, NULL, 0))
|
||||
return 0;
|
||||
msleep(200);
|
||||
|
||||
// Apply Mutual Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Apply Self Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Save Compensation data to EEPROM.
|
||||
if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
return touch_sense_enable();
|
||||
}
|
||||
|
||||
static int touch_init()
|
||||
{
|
||||
// Initialize touchscreen module.
|
||||
if (touch_sys_reset())
|
||||
return 0;
|
||||
|
||||
return touch_sense_enable();
|
||||
}
|
||||
|
||||
int touch_power_on()
|
||||
{
|
||||
// Enable LDO6 for touchscreen AVDD supply.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Configure touchscreen VDD GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_HIGH);
|
||||
|
||||
// IRQ and more.
|
||||
// PINMUX_AUX(PINMUX_AUX_TOUCH_INT) = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 3;
|
||||
// gpio_config(GPIO_PORT_X, GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
// gpio_write(GPIO_PORT_X, GPIO_PIN_1, GPIO_LOW);
|
||||
|
||||
// Configure Touscreen and GCAsic shared GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||
|
||||
// Initialize I2C3.
|
||||
pinmux_config_i2c(I2C_3);
|
||||
clock_enable_i2c(I2C_3);
|
||||
i2c_init(I2C_3);
|
||||
|
||||
// Wait for the touchscreen module to get ready.
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
|
||||
// Check for forced boot time calibration.
|
||||
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
{
|
||||
u8 err[2];
|
||||
if (touch_panel_ito_test(err))
|
||||
if (!err[0] && !err[1])
|
||||
return touch_execute_autotune();
|
||||
}
|
||||
|
||||
// Initialize touchscreen.
|
||||
u32 retries = 3;
|
||||
while (retries)
|
||||
{
|
||||
if (touch_init())
|
||||
return 1;
|
||||
retries--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void touch_power_off()
|
||||
{
|
||||
// Disable touchscreen power.
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
|
||||
// Disables LDO6 for touchscreen VDD, AVDD supply
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, false);
|
||||
|
||||
clock_disable_i2c(I2C_3);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Touch driver for Nintendo Switch's STMicroelectronics FingerTip S touch controller
|
||||
* Touch driver for Nintendo Switch's STM FingerTip S (4CD60D) touch controller
|
||||
*
|
||||
* Copyright (c) 2018 langerhans
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef __TOUCH_H_
|
||||
#define __TOUCH_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#define STMFTS_I2C_ADDR 0x49
|
||||
|
||||
@@ -44,20 +44,30 @@
|
||||
#define STMFTS_FULL_FORCE_CALIBRATION 0xA2
|
||||
#define STMFTS_MS_CX_TUNING 0xA3
|
||||
#define STMFTS_SS_CX_TUNING 0xA4
|
||||
#define STMFTS_ITO_CHECK 0xA7
|
||||
#define STMFTS_RELEASEINFO 0xAA
|
||||
#define STMFTS_WRITE_REG 0xB6
|
||||
#define STMFTS_SWITCH_SENSE_MODE 0xC3
|
||||
#define STMFTS_NOISE_WRITE 0xC7
|
||||
#define STMFTS_NOISE_READ 0xC8
|
||||
#define STMFTS_RW_FB_REG 0xD0 // read data
|
||||
#define STMFTS_RW_FRAMEBUFFER_REG 0xD0
|
||||
#define STMFTS_SAVE_CX_TUNING 0xFC
|
||||
|
||||
#define STMFTS_UNK0 0xB8 //Request compensation
|
||||
#define STMFTS_UNK1 0xCF
|
||||
#define STMFTS_UNK2 0xF7
|
||||
#define STMFTS_UNK3 0xFA
|
||||
#define STMFTS_UNK4 0xF9
|
||||
#define STMFTS_DETECTION_CONFIG 0xB0
|
||||
#define STMFTS_REQU_COMP_DATA 0xB8
|
||||
#define STMFTS_VENDOR 0xCF
|
||||
#define STMFTS_FLASH_UNLOCK 0xF7
|
||||
#define STMFTS_FLASH_WRITE_64K 0xF8
|
||||
#define STMFTS_FLASH_STATUS 0xF9
|
||||
#define STMFTS_FLASH_OP 0xFA
|
||||
#define STMFTS_UNK5 0x62
|
||||
|
||||
/* cmd parameters */
|
||||
#define STMFTS_VENDOR_GPIO_STATE 0x01
|
||||
#define STMFTS_VENDOR_SENSE_MODE 0x02
|
||||
#define STMFTS_STYLUS_MODE 0x00
|
||||
#define STMFTS_FINGER_MODE 0x01
|
||||
#define STMFTS_HOVER_MODE 0x02
|
||||
|
||||
/* events */
|
||||
#define STMFTS_EV_NO_EVENT 0x00
|
||||
@@ -72,12 +82,16 @@
|
||||
#define STMFTS_EV_ERROR 0x0f
|
||||
#define STMFTS_EV_NOISE_READ 0x17
|
||||
#define STMFTS_EV_NOISE_WRITE 0x18
|
||||
#define STMFTS_EV_VENDOR 0x20
|
||||
|
||||
#define STMFTS_EV_CONTROLLER_READY 0x10
|
||||
#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY 0x11
|
||||
#define STMFTS_EV_STATUS 0x16
|
||||
#define STMFTS_EV_DEBUG 0xDB
|
||||
|
||||
#define STMFTS_EV_STATUS_MS_CX_TUNING_DONE 1
|
||||
#define STMFTS_EV_STATUS_SS_CX_TUNING_DONE 2
|
||||
#define STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE 4
|
||||
|
||||
/* multi touch related event masks */
|
||||
#define STMFTS_MASK_EVENT_ID 0x0F
|
||||
#define STMFTS_MASK_TOUCH_ID 0xF0
|
||||
@@ -95,16 +109,46 @@
|
||||
#define STMFTS_DATA_MAX_SIZE (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
|
||||
#define STMFTS_MAX_FINGERS 10
|
||||
|
||||
typedef enum _touch_ito_error {
|
||||
ITO_NO_ERROR = 0,
|
||||
ITO_FORCE_OPEN,
|
||||
ITO_SENSE_OPEN,
|
||||
ITO_FORCE_SHRT_GND,
|
||||
ITO_SENSE_SHRT_GND,
|
||||
ITO_FORCE_SHRT_VCM,
|
||||
ITO_SENSE_SHRT_VCM,
|
||||
ITO_FORCE_SHRT_FORCE,
|
||||
ITO_SENSE_SHRT_SENSE,
|
||||
ITO_F2E_SENSE,
|
||||
ITO_FPC_FORCE_OPEN,
|
||||
ITO_FPC_SENSE_OPEN,
|
||||
ITO_KEY_FORCE_OPEN,
|
||||
ITO_KEY_SENSE_OPEN,
|
||||
ITO_RESERVED0,
|
||||
ITO_RESERVED1,
|
||||
ITO_RESERVED2,
|
||||
ITO_MAX_ERR_REACHED = 0xFF
|
||||
} touch_ito_error;
|
||||
|
||||
typedef struct _touch_event {
|
||||
u8 raw[8];
|
||||
u16 type; // Event type.
|
||||
u16 x; // Horizontal coordinates.
|
||||
u16 y; // Vertical coordinates.
|
||||
u8 z;
|
||||
u32 z;
|
||||
u8 fingers;
|
||||
bool touch;
|
||||
} touch_event;
|
||||
|
||||
typedef struct _touch_panel_info_t
|
||||
{
|
||||
u8 idx;
|
||||
u8 gpio0;
|
||||
u8 gpio1;
|
||||
u8 gpio2;
|
||||
char *vendor;
|
||||
} touch_panel_info_t;
|
||||
|
||||
typedef struct _touch_info {
|
||||
u16 chip_id;
|
||||
u16 fw_ver;
|
||||
@@ -112,10 +156,21 @@ typedef struct _touch_info {
|
||||
u16 config_ver;
|
||||
} touch_info;
|
||||
|
||||
int touch_power_on();
|
||||
void touch_power_off();
|
||||
typedef struct _touch_fw_info_t {
|
||||
u32 fw_id;
|
||||
u16 ftb_ver;
|
||||
u16 fw_rev;
|
||||
} touch_fw_info_t;
|
||||
|
||||
void touch_poll(touch_event *event);
|
||||
touch_event touch_poll_wait();
|
||||
touch_panel_info_t *touch_get_panel_vendor();
|
||||
int touch_get_fw_info(touch_fw_info_t *fw);
|
||||
touch_info touch_get_info();
|
||||
int touch_panel_ito_test(u8 *err);
|
||||
int touch_execute_autotune();
|
||||
int touch_sense_enable();
|
||||
int touch_power_on();
|
||||
void touch_power_off();
|
||||
|
||||
#endif /* __TOUCH_H_ */
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef _BLZ_H_
|
||||
#define _BLZ_H_
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef struct _blz_footer
|
||||
{
|
||||
@@ -125,7 +125,7 @@ static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
|
||||
* insize - Number of input bytes.
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize )
|
||||
{
|
||||
unsigned char marker, symbol;
|
||||
@@ -134,7 +134,7 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
/* Do we have anything to uncompress? */
|
||||
if( insize < 1 )
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get marker symbol from input stream */
|
||||
@@ -176,4 +176,6 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
}
|
||||
while( inpos < insize );
|
||||
|
||||
return outpos;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ extern "C" {
|
||||
* Function prototypes
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize );
|
||||
|
||||
|
||||
1681
bdk/libs/compr/lz4.c
Normal file
1681
bdk/libs/compr/lz4.c
Normal file
File diff suppressed because it is too large
Load Diff
569
bdk/libs/compr/lz4.h
Normal file
569
bdk/libs/compr/lz4.h
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-2017, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://www.lz4.org
|
||||
- LZ4 source repository : https://github.com/lz4/lz4
|
||||
*/
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef LZ4_H_2983827168210
|
||||
#define LZ4_H_2983827168210
|
||||
|
||||
/* --- Dependency --- */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
|
||||
/**
|
||||
Introduction
|
||||
|
||||
LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core,
|
||||
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
|
||||
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
|
||||
|
||||
The LZ4 compression library provides in-memory compression and decompression functions.
|
||||
Compression can be done in:
|
||||
- a single step (described as Simple Functions)
|
||||
- a single step, reusing a context (described in Advanced Functions)
|
||||
- unbounded multiple steps (described as Streaming compression)
|
||||
|
||||
lz4.h provides block compression functions. It gives full buffer control to user.
|
||||
Decompressing an lz4-compressed block also requires metadata (such as compressed size).
|
||||
Each application is free to encode such metadata in whichever way it wants.
|
||||
|
||||
An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md),
|
||||
take care of encoding standard metadata alongside LZ4-compressed blocks.
|
||||
If your application requires interoperability, it's recommended to use it.
|
||||
A library is provided to take care of it, see lz4frame.h.
|
||||
*/
|
||||
|
||||
/*^***************************************************************
|
||||
* Export parameters
|
||||
*****************************************************************/
|
||||
/*
|
||||
* LZ4_DLL_EXPORT :
|
||||
* Enable exporting of functions when building a Windows DLL
|
||||
* LZ4LIB_VISIBILITY :
|
||||
* Control library symbols visibility.
|
||||
*/
|
||||
#ifndef LZ4LIB_VISIBILITY
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define LZ4LIB_VISIBILITY
|
||||
# endif
|
||||
#endif
|
||||
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
|
||||
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
|
||||
#else
|
||||
# define LZ4LIB_API LZ4LIB_VISIBILITY
|
||||
#endif
|
||||
|
||||
/*------ Version ------*/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
|
||||
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
|
||||
#define LZ4_QUOTE(str) #str
|
||||
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
|
||||
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
|
||||
|
||||
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
|
||||
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; unseful to check dll version */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
/*!
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio
|
||||
* Reduced memory usage may improve speed, thanks to cache effect
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#ifndef LZ4_MEMORY_USAGE
|
||||
# define LZ4_MEMORY_USAGE 14
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
/*! LZ4_compress_default() :
|
||||
Compresses 'srcSize' bytes from buffer 'src'
|
||||
into already allocated 'dst' buffer of size 'dstCapacity'.
|
||||
Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
|
||||
It also runs faster, so it's a recommended setting.
|
||||
If the function cannot compress 'src' into a more limited 'dst' budget,
|
||||
compression stops *immediately*, and the function result is zero.
|
||||
Note : as a consequence, 'dst' content is not valid.
|
||||
Note 2 : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
|
||||
srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
|
||||
dstCapacity : size of buffer 'dst' (which must be already allocated)
|
||||
return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
|
||||
or 0 if compression fails */
|
||||
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
|
||||
/*! LZ4_decompress_safe() :
|
||||
compressedSize : is the exact complete size of the compressed block.
|
||||
dstCapacity : is the size of destination buffer, which must be already allocated.
|
||||
return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function is protected against malicious data packets.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*!
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is incorrect (too large or negative)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*!
|
||||
LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_compress_fast_extState() :
|
||||
Same compression function, just using an externally allocated memory space to store compression state.
|
||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
and allocate it on 8-bytes boundaries (using malloc() typically).
|
||||
Then, provide it as 'void* state' to compression function.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_sizeofState(void);
|
||||
LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_compress_destSize() :
|
||||
Reverse the logic : compresses as much data as possible from 'src' buffer
|
||||
into already allocated buffer 'dst' of size 'targetDestSize'.
|
||||
This function either compresses the entire 'src' content into 'dst' if it's large enough,
|
||||
or fill 'dst' buffer completely with as much data as possible from 'src'.
|
||||
*srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
|
||||
New value is necessarily <= old value.
|
||||
return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
|
||||
or 0 if compression fails
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_decompress_fast() : **unsafe!**
|
||||
This function is a bit faster than LZ4_decompress_safe(),
|
||||
but doesn't provide any security guarantee.
|
||||
originalSize : is the uncompressed size to regenerate
|
||||
Destination buffer must be already allocated, and its size must be >= 'originalSize' bytes.
|
||||
return : number of bytes read from source buffer (== compressed size).
|
||||
If the source stream is detected malformed, the function stops decoding and return a negative result.
|
||||
note : This function respects memory boundaries for *properly formed* compressed data.
|
||||
However, it does not provide any protection against malicious input.
|
||||
It also doesn't know 'src' size, and implies it's >= compressed size.
|
||||
Use this function in trusted environment **only**.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
|
||||
|
||||
/*!
|
||||
LZ4_decompress_safe_partial() :
|
||||
This function decompress a compressed block of size 'srcSize' at position 'src'
|
||||
into destination buffer 'dst' of size 'dstCapacity'.
|
||||
The function will decompress a minimum of 'targetOutputSize' bytes, and stop after that.
|
||||
However, it's not accurate, and may write more than 'targetOutputSize' (but always <= dstCapacity).
|
||||
@return : the number of bytes decoded in the destination buffer (necessarily <= dstCapacity)
|
||||
Note : this number can also be < targetOutputSize, if compressed block contains less data.
|
||||
Therefore, always control how many bytes were decoded.
|
||||
If source stream is detected malformed, function returns a negative result.
|
||||
This function is protected against malicious data packets.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-*********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
|
||||
|
||||
/*! LZ4_createStream() and LZ4_freeStream() :
|
||||
* LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure.
|
||||
* LZ4_freeStream() releases its memory.
|
||||
*/
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
|
||||
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_resetStream() :
|
||||
* An LZ4_stream_t structure can be allocated once and re-used multiple times.
|
||||
* Use this function to start compressing a new stream.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_loadDict() :
|
||||
* Use this function to load a static dictionary into LZ4_stream_t.
|
||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
||||
* Loading a size of 0 is allowed, and is the same as reset.
|
||||
* @return : dictionary size, in bytes (necessarily <= 64 KB)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_compress_fast_continue() :
|
||||
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
*
|
||||
* Important : The previous 64KB of compressed data is assumed to remain present and unmodified in memory!
|
||||
*
|
||||
* Special 1 : When input is a double-buffer, they can have any size, including < 64 KB.
|
||||
* Make sure that buffers are separated by at least one byte.
|
||||
* This way, each block only depends on previous block.
|
||||
* Special 2 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
|
||||
*
|
||||
* @return : size of compressed block
|
||||
* or 0 if there is an error (typically, cannot fit into 'dst').
|
||||
* After an error, the stream status is invalid, it can only be reset or freed.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_saveDict() :
|
||||
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
|
||||
* save it into a safer place (char* safeBuffer).
|
||||
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
|
||||
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
|
||||
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
|
||||
|
||||
|
||||
/*-**********************************************
|
||||
* Streaming Decompression Functions
|
||||
* Bufferless synchronous API
|
||||
************************************************/
|
||||
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */
|
||||
|
||||
/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
|
||||
* creation / destruction of streaming decompression tracking structure.
|
||||
* A tracking structure can be re-used multiple times sequentially. */
|
||||
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
|
||||
/*! LZ4_setStreamDecode() :
|
||||
* An LZ4_streamDecode_t structure can be allocated once and re-used multiple times.
|
||||
* Use this function to start decompression of a new stream of blocks.
|
||||
* A dictionary can optionnally be set. Use NULL or size 0 for a reset order.
|
||||
* @return : 1 if OK, 0 if error
|
||||
*/
|
||||
LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_decompress_*_continue() :
|
||||
* These decoding functions allow decompression of consecutive blocks in "streaming" mode.
|
||||
* A block is an unsplittable entity, it must be presented entirely to a decompression function.
|
||||
* Decompression functions only accept one block at a time.
|
||||
* The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
|
||||
* If less than 64KB of data has been decoded all the data must be present.
|
||||
*
|
||||
* Special : if application sets a ring buffer for decompression, it must respect one of the following conditions :
|
||||
* - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
|
||||
* In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
|
||||
* - Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
* maxBlockSize is implementation dependent. It's the maximum size of any single block.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
* - _At least_ 64 KB + 8 bytes + maxBlockSize.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including larger than decoding buffer.
|
||||
* Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
|
||||
* and indicate where it is saved using LZ4_setStreamDecode() before decompressing next block.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
|
||||
|
||||
|
||||
/*! LZ4_decompress_*_usingDict() :
|
||||
* These decoding functions work the same as
|
||||
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
|
||||
* They are stand-alone, and don't need an LZ4_streamDecode_t structure.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
|
||||
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
|
||||
/*^**********************************************
|
||||
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||
***********************************************/
|
||||
|
||||
/*-************************************
|
||||
* Unstable declarations
|
||||
**************************************
|
||||
* Declarations in this section should be considered unstable.
|
||||
* Use at your own peril, etc., etc.
|
||||
* They may be removed in the future.
|
||||
* Their signatures may change.
|
||||
**************************************/
|
||||
|
||||
#ifdef LZ4_STATIC_LINKING_ONLY
|
||||
|
||||
/*! LZ4_resetStream_fast() :
|
||||
* When an LZ4_stream_t is known to be in a internally coherent state,
|
||||
* it can often be prepared for a new compression with almost no work, only
|
||||
* sometimes falling back to the full, expensive reset that is always required
|
||||
* when the stream is in an indeterminate state (i.e., the reset performed by
|
||||
* LZ4_resetStream()).
|
||||
*
|
||||
* LZ4_streams are guaranteed to be in a valid state when:
|
||||
* - returned from LZ4_createStream()
|
||||
* - reset by LZ4_resetStream()
|
||||
* - memset(stream, 0, sizeof(LZ4_stream_t))
|
||||
* - the stream was in a valid state and was reset by LZ4_resetStream_fast()
|
||||
* - the stream was in a valid state and was then used in any compression call
|
||||
* that returned success
|
||||
* - the stream was in an indeterminate state and was used in a compression
|
||||
* call that fully reset the state (LZ4_compress_fast_extState()) and that
|
||||
* returned success
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_compress_fast_extState_fastReset() :
|
||||
* A variant of LZ4_compress_fast_extState().
|
||||
*
|
||||
* Using this variant avoids an expensive initialization step. It is only safe
|
||||
* to call if the state buffer is known to be correctly initialized already
|
||||
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly
|
||||
* initialized"). From a high level, the difference is that this function
|
||||
* initializes the provided state with a call to LZ4_resetStream_fast() while
|
||||
* LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_attach_dictionary() :
|
||||
* This is an experimental API that allows for the efficient use of a
|
||||
* static dictionary many times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
|
||||
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references the dictionary stream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of the dictionary stream.
|
||||
* Currently, only streams which have been prepared by LZ4_loadDict() should
|
||||
* be expected to work.
|
||||
*
|
||||
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
||||
* case any existing dictionary stream is unset.
|
||||
*
|
||||
* If a dictionary is provided, it replaces any pre-existing stream history.
|
||||
* The dictionary contents are the only history that can be referenced and
|
||||
* logically immediately precede the data compressed in the first subsequent
|
||||
* compression call.
|
||||
*
|
||||
* The dictionary will only remain attached to the working stream through the
|
||||
* first compression call, at the end of which it is cleared. The dictionary
|
||||
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the completion of the first compression call on the stream.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream);
|
||||
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Private definitions
|
||||
**************************************
|
||||
* Do not use these definitions.
|
||||
* They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
|
||||
* Using these definitions will expose code to API and/or ABI break in future versions of the library.
|
||||
**************************************/
|
||||
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
|
||||
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
|
||||
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
|
||||
|
||||
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
uint32_t hashTable[LZ4_HASH_SIZE_U32];
|
||||
uint32_t currentOffset;
|
||||
uint16_t initCheck;
|
||||
uint16_t tableType;
|
||||
const uint8_t* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
uint32_t dictSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* externalDict;
|
||||
size_t extDictSize;
|
||||
const uint8_t* prefixEnd;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
unsigned int hashTable[LZ4_HASH_SIZE_U32];
|
||||
unsigned int currentOffset;
|
||||
unsigned short initCheck;
|
||||
unsigned short tableType;
|
||||
const unsigned char* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
unsigned int dictSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const unsigned char* externalDict;
|
||||
size_t extDictSize;
|
||||
const unsigned char* prefixEnd;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* LZ4_stream_t :
|
||||
* information structure to track an LZ4 stream.
|
||||
* init this structure before first use.
|
||||
* note : only use in association with static linking !
|
||||
* this definition is not API/ABI safe,
|
||||
* it may change in a future version !
|
||||
*/
|
||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long))
|
||||
union LZ4_stream_u {
|
||||
unsigned long long table[LZ4_STREAMSIZE_U64];
|
||||
LZ4_stream_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_stream_t */
|
||||
|
||||
|
||||
/*!
|
||||
* LZ4_streamDecode_t :
|
||||
* information structure to track an LZ4 stream during decompression.
|
||||
* init this structure using LZ4_setStreamDecode (or memset()) before first use
|
||||
* note : only use in association with static linking !
|
||||
* this definition is not API/ABI safe,
|
||||
* and may change in a future version !
|
||||
*/
|
||||
#define LZ4_STREAMDECODESIZE_U64 4
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
union LZ4_streamDecode_u {
|
||||
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
|
||||
LZ4_streamDecode_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_streamDecode_t */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
|
||||
/*! Deprecation warnings
|
||||
Should deprecation warnings be a problem,
|
||||
it is generally possible to disable them,
|
||||
typically with -Wno-deprecated-declarations for gcc
|
||||
or _CRT_SECURE_NO_WARNINGS in Visual.
|
||||
Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||
#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
|
||||
#else
|
||||
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
|
||||
# define LZ4_DEPRECATED(message) [[deprecated(message)]]
|
||||
# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif (LZ4_GCC_VERSION >= 301)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# else
|
||||
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
|
||||
# define LZ4_DEPRECATED(message)
|
||||
# endif
|
||||
#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||
|
||||
/* Obsolete compression functions */
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* source, char* dest, int sourceSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete decompression functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||
|
||||
/* Obsolete streaming functions; degraded functionality; do not use!
|
||||
*
|
||||
* In order to perform streaming compression, these functions depended on data
|
||||
* that is no longer tracked in the state. They have been preserved as well as
|
||||
* possible: using them will still produce a correct output. However, they don't
|
||||
* actually retain any history between compression calls. The compression ratio
|
||||
* achieved will therefore be no better than compressing each chunk
|
||||
* independently.
|
||||
*/
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
#endif /* LZ4_H_2983827168210 */
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
@@ -23,6 +23,14 @@ typedef enum {
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
typedef enum {
|
||||
DRIVE_SD = 0,
|
||||
DRIVE_RAM = 1,
|
||||
DRIVE_EMMC = 2,
|
||||
DRIVE_BIS = 3,
|
||||
DRIVE_EMU = 4
|
||||
} DDRIVE;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
@@ -33,6 +41,7 @@ DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
@@ -47,9 +56,11 @@ DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define SET_SECTOR_COUNT 1 /* Set media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -38,7 +38,8 @@
|
||||
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
#include "../../gfx/gfx.h"
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
//#define EFSPRINTF(...)
|
||||
@@ -3273,7 +3274,6 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
stat = disk_status(fs->pdrv);
|
||||
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
|
||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
|
||||
EFSPRINTF("WPEN1");
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
return FR_OK; /* The filesystem object is valid */
|
||||
@@ -3284,14 +3284,13 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */
|
||||
|
||||
fs->fs_type = 0; /* Clear the filesystem object */
|
||||
fs->part_type = 0; /* Clear the Partition object */
|
||||
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
|
||||
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
|
||||
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
|
||||
EFSPRINTF("MDNR");
|
||||
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
|
||||
}
|
||||
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check disk write protection if needed */
|
||||
EFSPRINTF("WPEN2");
|
||||
return FR_WRITE_PROTECTED;
|
||||
}
|
||||
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
|
||||
@@ -3318,6 +3317,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
EFSPRINTF("BRNL");
|
||||
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
|
||||
}
|
||||
#if FF_SIMPLE_GPT
|
||||
if (fmt >= 2) {
|
||||
/* If GPT Check the first partition */
|
||||
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
|
||||
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
|
||||
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
|
||||
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
|
||||
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
|
||||
fs->part_type = 1;
|
||||
bsect = gpt_entry->lba_start;
|
||||
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fmt >= 2) {
|
||||
EFSPRINTF("NOFAT");
|
||||
return FR_NO_FILESYSTEM; /* No FAT volume is found */
|
||||
@@ -3906,11 +3919,11 @@ FRESULT f_read (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Fast Read Aligned Sized File Without a Cache */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if FF_USE_FASTSEEK
|
||||
|
||||
FRESULT f_read_fast (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
const void* buff, /* Pointer to the data to be written */
|
||||
@@ -3988,7 +4001,6 @@ FRESULT f_read_fast (
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -4132,11 +4144,11 @@ FRESULT f_write (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Fast Write Aligned Sized File Without a Cache */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if FF_USE_FASTSEEK
|
||||
|
||||
FRESULT f_write_fast (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
const void* buff, /* Pointer to the data to be written */
|
||||
@@ -4219,7 +4231,6 @@ FRESULT f_write_fast (
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -4680,8 +4691,7 @@ FRESULT f_lseek (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_USE_FASTSEEK
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Seek File Read/Write Pointer */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -4699,16 +4709,15 @@ DWORD *f_expand_cltbl (
|
||||
}
|
||||
if (f_lseek(fp, CREATE_LINKMAP)) { /* Create cluster link table */
|
||||
ff_memfree(fp->cltbl);
|
||||
fp->cltbl = NULL;
|
||||
fp->cltbl = (void *)0;
|
||||
EFSPRINTF("CLTBLSZ");
|
||||
return NULL;
|
||||
return (void *)0;
|
||||
}
|
||||
f_lseek(fp, 0);
|
||||
|
||||
return fp->cltbl;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -5842,7 +5851,7 @@ FRESULT f_mkfs (
|
||||
UINT len /* Size of working buffer [byte] */
|
||||
)
|
||||
{
|
||||
const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
|
||||
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
|
||||
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
|
||||
@@ -5906,7 +5915,7 @@ FRESULT f_mkfs (
|
||||
} else {
|
||||
/* Create a single-partition in this function */
|
||||
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
|
||||
b_vol = (opt & FM_SFD) ? 0 : 63; /* Volume start sector */
|
||||
b_vol = (opt & FM_SFD) ? 0 : 32768; /* Volume start sector. Align to 16MB */
|
||||
if (sz_vol < b_vol) LEAVE_MKFS(FR_MKFS_ABORTED);
|
||||
sz_vol -= b_vol; /* Volume size */
|
||||
}
|
||||
@@ -6130,6 +6139,9 @@ FRESULT f_mkfs (
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
|
||||
@@ -6170,7 +6182,9 @@ FRESULT f_mkfs (
|
||||
#endif
|
||||
/* Create FAT VBR */
|
||||
mem_set(buf, 0, ss);
|
||||
mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */
|
||||
/* Boot jump code (x86), OEM name */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||
st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */
|
||||
@@ -6183,23 +6197,27 @@ FRESULT f_mkfs (
|
||||
}
|
||||
buf[BPB_Media] = 0xF8; /* Media descriptor byte */
|
||||
st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */
|
||||
st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */
|
||||
st_word(buf + BPB_NumHeads, (opt & FM_PRF2) ? 16 : 255); /* Number of heads (for int13) */
|
||||
st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */
|
||||
if (fmt == FS_FAT32) {
|
||||
st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BS_VolID32, (opt & FM_PRF2) ? 0 : GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */
|
||||
st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */
|
||||
st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */
|
||||
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
|
||||
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig32] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab32, FF_MKFS_LABEL "FAT32 ", 19);
|
||||
else mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19);
|
||||
} else {
|
||||
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
|
||||
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
|
||||
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab, FF_MKFS_LABEL "FAT ", 19);
|
||||
else mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19);
|
||||
}
|
||||
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
|
||||
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
|
||||
@@ -6217,6 +6235,16 @@ FRESULT f_mkfs (
|
||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||
}
|
||||
|
||||
/* Create PRF2SAFE info */
|
||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||
mem_set(buf, 0, ss);
|
||||
buf[16] = 0x64; /* Record type */
|
||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
||||
st_dword(buf + 36, 25); /* Entries. SYSTEM: 22. USER: 25.Static? */
|
||||
st_dword(buf + 508, 0x517BBFE0); /* Custom CRC32. SYSTEM: 0x6B673904. USER: 0x517BBFE0. */
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
}
|
||||
|
||||
/* Initialize FAT area */
|
||||
mem_set(buf, 0, (UINT)szb_buf);
|
||||
sect = b_fat; /* FAT start sector */
|
||||
@@ -6706,6 +6734,8 @@ int f_puts (
|
||||
putbuff pb;
|
||||
|
||||
|
||||
if (str == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
while (*str) putc_bfd(&pb, *str++); /* Put the string */
|
||||
return putc_flush(&pb);
|
||||
@@ -6732,6 +6762,8 @@ int f_printf (
|
||||
TCHAR c, d, str[32], *p;
|
||||
|
||||
|
||||
if (fmt == (void *)0) return EOF; /* String is NULL */
|
||||
|
||||
putc_init(&pb, fp);
|
||||
|
||||
va_start(arp, fmt);
|
||||
@@ -26,8 +26,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#include <utils/types.h> /* Basic integer types */
|
||||
#include <fatfs_cfg.h> /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
@@ -95,8 +95,8 @@ typedef DWORD FSIZE_t;
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE part_type; /* Partition type (0:MBR, 1:GPT) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
@@ -138,6 +138,7 @@ typedef struct {
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg). DMA aligned. */
|
||||
} FATFS;
|
||||
|
||||
|
||||
@@ -168,9 +169,6 @@ typedef struct {
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
@@ -184,6 +182,9 @@ typedef struct {
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window. DMA aligned. */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
@@ -246,7 +247,7 @@ typedef enum {
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS
|
||||
FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
|
||||
FR_CLTBL_NO_INIT /* (20) The cluster table for fast seek/read/write was not created */
|
||||
#else
|
||||
@@ -263,10 +264,8 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
#ifdef FF_FASTFS
|
||||
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
|
||||
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
|
||||
#endif
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
@@ -288,9 +287,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
#ifdef FF_FASTFS
|
||||
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
|
||||
#endif
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
@@ -369,6 +366,7 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
#define FM_PRF2 0x10
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
@@ -380,8 +378,11 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_DEV 0x40 /* Device */
|
||||
#define AM_RVD 0x80 /* Reserved */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -17,8 +17,8 @@
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../../../common/memory_map.h"
|
||||
#include <utils/types.h>
|
||||
#include <memory_map.h>
|
||||
/*===================
|
||||
Dynamic memory
|
||||
*===================*/
|
||||
@@ -32,7 +32,7 @@
|
||||
# define LV_MEM_ADR NYX_LV_MEM_ADR /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/
|
||||
# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE "../../../mem/heap.h" /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <mem/heap.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
@@ -149,13 +149,17 @@
|
||||
/*HAL settings*/
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "../../../utils/util.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE <utils/util.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
/*Log settings*/
|
||||
#define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#ifdef DEBUG_UART_LV_LOG
|
||||
# define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||
#else
|
||||
# define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#endif
|
||||
#if USE_LV_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
@@ -163,7 +167,7 @@
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't caused problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_ERROR
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
/* 1: Print the log with 'printf'; 0: user need to register a callback*/
|
||||
# define LV_LOG_PRINTF 1
|
||||
#endif /*USE_LV_LOG*/
|
||||
@@ -365,12 +369,5 @@
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define USE_LV_SW 1
|
||||
|
||||
/*************************
|
||||
* Non-user section
|
||||
*************************/
|
||||
#ifdef _MSC_VER /* Disable warnings for Visual Studio*/
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
@@ -357,7 +357,10 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(i->cursor != NULL &&
|
||||
(i->proc.last_point.x != data->point.x ||
|
||||
i->proc.last_point.y != data->point.y)) {
|
||||
lv_obj_set_pos(i->cursor, data->point.x, data->point.y);
|
||||
/*Use cursor's center as pointer*/
|
||||
uint32_t off_x = lv_obj_get_width(i->cursor) >> 1;
|
||||
uint32_t off_y = lv_obj_get_height(i->cursor) >> 1;
|
||||
lv_obj_set_pos(i->cursor, data->point.x - off_x, data->point.y - off_y);
|
||||
}
|
||||
|
||||
i->proc.act_point.x = data->point.x;
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_120 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_20 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_30 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_INTERUI_20 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_INTERUI_30 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_UBUNTU_MONO != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -17,7 +17,7 @@ extern "C" {
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <string.h>
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_area.h"
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file lv_color.c
|
||||
*
|
||||
@@ -12,6 +28,8 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define HUE_DEGREE 512
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -43,57 +61,68 @@
|
||||
* @param v value [0..100]
|
||||
* @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
|
||||
*/
|
||||
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
|
||||
lv_color_t lv_color_hsv_to_rgb(uint16_t hue, uint8_t sat, uint8_t val)
|
||||
{
|
||||
if(s == 0)
|
||||
return LV_COLOR_MAKE(v, v, v);
|
||||
|
||||
h = (uint32_t)((uint32_t)h * 255) / 360;
|
||||
s = (uint16_t)((uint16_t)s * 255) / 100;
|
||||
v = (uint16_t)((uint16_t)v * 255) / 100;
|
||||
|
||||
uint8_t r, g, b;
|
||||
|
||||
uint8_t region, remainder, p, q, t;
|
||||
uint32_t h = (hue * 360 * HUE_DEGREE -1) / 360;
|
||||
uint32_t s = sat * 255 / 100;
|
||||
uint32_t v = val * 255 / 100;
|
||||
uint32_t p = (256 * v - s * v) / 256;
|
||||
uint32_t region = h / (60 * 512);
|
||||
|
||||
if(sat == 0)
|
||||
return LV_COLOR_MAKE(v, v, v);
|
||||
|
||||
region = h / 43;
|
||||
remainder = (h - (region * 43)) * 6;
|
||||
if (region & 1)
|
||||
{
|
||||
uint32_t q = (256 * 60 * HUE_DEGREE * v - h * s * v + 60 * HUE_DEGREE * s * v * region) /
|
||||
(256 * 60 * HUE_DEGREE);
|
||||
|
||||
p = (v * (255 - s)) >> 8;
|
||||
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
|
||||
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
|
||||
|
||||
switch(region) {
|
||||
case 0:
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
switch (region)
|
||||
{
|
||||
case 1:
|
||||
r = q;
|
||||
g = v;
|
||||
b = p;
|
||||
break;
|
||||
case 3:
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t t = (256 * 60 * HUE_DEGREE * v + h * s * v - 60 * HUE_DEGREE * s * v * (region + 1)) /
|
||||
(256 * 60 * HUE_DEGREE);
|
||||
|
||||
switch (region)
|
||||
{
|
||||
case 0:
|
||||
r = v;
|
||||
g = t;
|
||||
b = p;
|
||||
break;
|
||||
case 2:
|
||||
r = p;
|
||||
g = v;
|
||||
b = t;
|
||||
break;
|
||||
case 3:
|
||||
r = p;
|
||||
g = q;
|
||||
b = v;
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
r = t;
|
||||
g = p;
|
||||
b = v;
|
||||
break;
|
||||
default:
|
||||
r = v;
|
||||
g = p;
|
||||
b = q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_COLOR_MAKE(r, g, b);
|
||||
@@ -432,7 +432,7 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
||||
* @param v value [0..100]
|
||||
* @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
|
||||
*/
|
||||
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
|
||||
lv_color_t lv_color_hsv_to_rgb(uint16_t hue, uint8_t sat, uint8_t val);
|
||||
|
||||
/**
|
||||
* Convert an RGB color to HSV
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user