Compare commits
941 Commits
enable-com
...
rei/develo
Author | SHA1 | Date | |
---|---|---|---|
e54d78a04b | |||
8f32478141 | |||
b002fddc29 | |||
ea62510eb6 | |||
a4598ed63e | |||
72a020127f | |||
|
373289c072 | ||
|
350bca3965 | ||
|
94cd2ba563 | ||
|
ecb3cd3e31 | ||
|
d55ec42b17 | ||
|
a1385cb481 | ||
|
de62620de1 | ||
|
7e169ee4aa | ||
|
955dda60c5 | ||
|
6cfb45e280 | ||
|
c6026aa617 | ||
|
254c85246e | ||
|
4a40d29279 | ||
|
41c461d1f6 | ||
|
17cedd6629 | ||
|
1d34e83c97 | ||
|
9e18c23aac | ||
|
12d4bc4139 | ||
|
17079fb114 | ||
|
c2b15b1446 | ||
|
7bc692eea4 | ||
|
36740498db | ||
|
5f28f89df2 | ||
|
35dcf8c860 | ||
|
f95147cf0e | ||
|
91a3e98276 | ||
|
8a71f2b9e0 | ||
|
8999158528 | ||
|
977936e8e2 | ||
|
03a2059e87 | ||
|
702f65d3ee | ||
|
20ac1cd374 | ||
|
03a510bd18 | ||
|
7f45538eb5 | ||
|
718fbdab98 | ||
|
0ce4183640 | ||
|
87a69fe52d | ||
|
0fabba1c9a | ||
|
a2218dd4ad | ||
|
619477cbd1 | ||
|
cc2d5c39ce | ||
|
dd313eb419 | ||
|
9b216bb16f | ||
|
1ffca52715 | ||
|
c77f923a33 | ||
|
83b3a2a469 | ||
|
123c801f17 | ||
|
831f93cd92 | ||
|
34506be06e | ||
|
6171c9d45d | ||
|
a6fcdec0f8 | ||
|
443408312a | ||
|
324927f2b7 | ||
|
db0f909b46 | ||
|
8485cdb54d | ||
|
4cb07bac53 | ||
|
c9f23c11b3 | ||
|
f56788465d | ||
|
78267eec40 | ||
|
a2057ebc6f | ||
|
b6b322efdd | ||
|
f7e8caa04a | ||
|
4fba1ac5ce | ||
|
27e598f3fa | ||
|
8b2e1c69f2 | ||
|
95a970a75d | ||
|
2ccf88c03c | ||
|
331de8ce8e | ||
|
4e2b0b1f10 | ||
|
d967ed7d90 | ||
|
ef17f2f981 | ||
|
e39f183efe | ||
|
b9fbee1007 | ||
|
43443eda74 | ||
|
1c0d9ef383 | ||
|
c006f05c99 | ||
|
9d3671561f | ||
|
a75912dd97 | ||
|
1d4fd9c27f | ||
|
77645b20b2 | ||
|
451d755e3d | ||
|
9535c1e651 | ||
|
ac0dc5ff47 | ||
|
875b9c4bc5 | ||
|
3005fe8710 | ||
|
4116baf72e | ||
|
09b852d8f0 | ||
|
c94e0d53bb | ||
|
015f17cd25 | ||
|
dedb397ae0 | ||
|
ae2b9d30d6 | ||
|
beddfc346d | ||
|
2b9418c7f8 | ||
|
8160748733 | ||
|
6dac0a62f4 | ||
|
4229386501 | ||
|
09a50dcc15 | ||
|
8b470d33a1 | ||
|
8061822f0c | ||
|
b31fbb4adb | ||
|
54df828665 | ||
|
b7b1af1c4c | ||
|
2e42b90009 | ||
|
b6807ee3ca | ||
|
36cb7c82f3 | ||
|
34858d0a6c | ||
|
f82aa71eb0 | ||
|
aa32159c00 | ||
|
5e83a862db | ||
|
28ccf15e13 | ||
|
3bf6b1cb16 | ||
|
d7441d18be | ||
|
129dd97b51 | ||
|
5a13c5215c | ||
|
f84a0a3897 | ||
|
ed91b5a998 | ||
|
68a7016080 | ||
|
ff73f67d6f | ||
|
943a48f189 | ||
|
82a4f9aa68 | ||
|
2607c3d799 | ||
|
b498e1d633 | ||
|
78365548f7 | ||
|
78cab3604d | ||
|
8f436e1d74 | ||
|
4761fcb63a | ||
|
a8b7fbe48b | ||
|
cd1f218dd8 | ||
|
f1194a5f74 | ||
|
88197b6632 | ||
|
f973f1c12c | ||
|
df61907073 | ||
|
1c4a56b05b | ||
|
5f2ce53877 | ||
|
fc374562dd | ||
|
76b7436dfb | ||
|
1379b7902f | ||
|
bebc072e78 | ||
|
db41d9081a | ||
|
51716898aa | ||
|
0933d60b16 | ||
|
ea14c580ca | ||
|
21da5869c5 | ||
|
dbfcb455fe | ||
|
f47b04ffd0 | ||
|
7e0b053b38 | ||
|
61a9a97e26 | ||
|
04d21dcd93 | ||
|
13c66dd54b | ||
|
204ad7ca2a | ||
|
4c92ed410f | ||
|
187d99c0f7 | ||
|
5fe5cee9ef | ||
|
8844ea60b1 | ||
|
452dd12eff | ||
|
5d974434ef | ||
|
30797b37bc | ||
|
5613449bfb | ||
|
dd47ba9782 | ||
|
dd28359571 | ||
|
43399b3832 | ||
|
1eaf258a63 | ||
|
f1c91e1ce0 | ||
|
1bfee61ef9 | ||
|
a29e30c187 | ||
|
29f0bce46b | ||
|
51640c7248 | ||
|
8dae4c8299 | ||
|
2803dd667f | ||
|
0e2b27d792 | ||
|
ef44b763d9 | ||
|
40cdb54772 | ||
|
69e4ab6be1 | ||
|
407908686a | ||
|
f829427c41 | ||
|
b857fdb9f4 | ||
|
4aaa3a3b49 | ||
|
a2a70f8eda | ||
|
04eca81a95 | ||
|
d5b78ecd66 | ||
|
a1db9fca13 | ||
|
4f649a8544 | ||
|
e332be0d7c | ||
|
87d882b151 | ||
|
d967efa197 | ||
|
5938b4b208 | ||
|
32fe7b660c | ||
|
76f63ed76a | ||
|
0930a79041 | ||
|
a9b77ae0d4 | ||
|
1ac1d5aa5a | ||
|
2daa5dcbee | ||
|
ae0724c28c | ||
|
02e94acf18 | ||
|
d86f81b9ad | ||
|
c8d998e82c | ||
|
5be2f57a78 | ||
|
1813399959 | ||
|
2bc338ceed | ||
|
698288d822 | ||
|
e73a92c29b | ||
|
f38c559089 | ||
|
b12603448c | ||
|
71c895dc71 | ||
|
9e9010c725 | ||
|
458f5b8eb8 | ||
|
bbb823b170 | ||
|
a1880ca3b8 | ||
|
a354650a9c | ||
|
cc01d6ca17 | ||
|
67f546fa33 | ||
|
b4e956227e | ||
|
314c02194a | ||
|
470db4ab99 | ||
|
6bf6bb7e2a | ||
|
688dc2fed7 | ||
|
bbc5af078d | ||
|
48e9458301 | ||
|
26ae828e39 | ||
|
f711f0f794 | ||
|
97cbe34963 | ||
|
e8fc46ba20 | ||
|
b1b9937ff7 | ||
|
dc8be2244c | ||
|
bef3e708f6 | ||
|
b8b54f47a2 | ||
|
15c3807a76 | ||
|
e82469bffa | ||
|
f86c71b2bb | ||
|
92b1e83e3e | ||
|
98ac447bdb | ||
|
b9c40100f6 | ||
|
8f38bd911b | ||
|
5c13200238 | ||
|
d6b22645e3 | ||
|
f780ac999a | ||
|
d2510d7926 | ||
|
6d74820698 | ||
|
3ebf002f9d | ||
|
ad42cdf120 | ||
|
d270275bd2 | ||
|
7a0f72ed8b | ||
|
cc259b6a4a | ||
|
94561b2331 | ||
|
5e6868d9eb | ||
|
e0013e7304 | ||
|
a65f173e3c | ||
|
7eff1dbcc6 | ||
|
f7d1b3f368 | ||
|
fb87fdb2d9 | ||
|
d034bd131e | ||
|
baa5954724 | ||
|
51d2888b52 | ||
|
54f588ce63 | ||
|
86d180a855 | ||
|
395590d2d8 | ||
|
5b7915b5c9 | ||
|
fb1946b06e | ||
|
ab059b9004 | ||
|
97668c775b | ||
|
90352af626 | ||
|
c8214bc666 | ||
|
f66fcdd3ca | ||
|
1832a6c231 | ||
|
204fc56672 | ||
|
f52d6bfa67 | ||
|
86ee7a70b7 | ||
|
319030d9e1 | ||
|
3b0b48020d | ||
|
eca0588c23 | ||
|
8ab959b4dc | ||
|
464b689a03 | ||
|
4cc95091ab | ||
|
6a5946c4e3 | ||
|
645a071b70 | ||
|
bccd77d5c9 | ||
|
1470489e7b | ||
|
0a0d1f2703 | ||
|
b9a2db1a49 | ||
|
d1e9aa1076 | ||
|
fdb5e27aea | ||
|
b62c62ee1f | ||
|
09b9130244 | ||
|
362a5ef113 | ||
|
8f46908d38 | ||
|
f4322841ff | ||
|
2e10b0fe64 | ||
|
c1aa5a5ea7 | ||
|
8fb99471c3 | ||
|
faa05eb57b | ||
|
6393a17d74 | ||
|
f841b8c984 | ||
|
a5a64800ed | ||
|
d89e38d3bf | ||
|
8f6a390c36 | ||
|
1b4b422ab6 | ||
|
3a8e66a52f | ||
|
eabbbfa373 | ||
|
2690c274af | ||
|
1dd7174480 | ||
|
91c644b43c | ||
|
f57f797ff5 | ||
|
6cf4a933b6 | ||
|
42a5cdb5b7 | ||
|
6354511c20 | ||
|
32ea01b2e9 | ||
|
ec9b5a0bd2 | ||
|
736ae08fcd | ||
|
494448b7cc | ||
|
9ffd28f735 | ||
|
589733d11e | ||
|
e104f17b1b | ||
|
23f318c3d0 | ||
|
9db5d64441 | ||
|
6a442b90a1 | ||
|
645f6f43dc | ||
|
f4daf63679 | ||
|
8539db0884 | ||
|
d29a9818af | ||
|
e8c1302cd6 | ||
|
b946b8d156 | ||
|
cd593c3862 | ||
|
f1fc7ee659 | ||
|
048ecd41e4 | ||
|
150fa3b661 | ||
|
1e4130a9cf | ||
|
62dbcbfc95 | ||
|
ae4b9e0f2e | ||
|
c00ad4af35 | ||
|
5f50f0e538 | ||
|
3eebe66d65 | ||
|
f1f2bc119a | ||
|
6879147648 | ||
|
7b04ce5eba | ||
|
0df49bd43d | ||
|
62bb6b5163 | ||
|
58d454b11f | ||
|
4a8f72bd1e | ||
|
be7931c4fb | ||
|
154e3d27ad | ||
|
797b60397c | ||
|
e0133cec36 | ||
|
ffd6c3f095 | ||
|
b72c6a5bc9 | ||
|
9525fc4273 | ||
|
b998d5e2a8 | ||
|
abbfb92fa2 | ||
|
75cf5324ba | ||
|
cccec6e1ab | ||
|
9108952e6b | ||
|
06b022fc4d | ||
|
c870f8ed30 | ||
|
48beb7c3b1 | ||
|
df04763ab4 | ||
|
900598a7ee | ||
|
657dc3a9ba | ||
|
ffb17357e7 | ||
|
ed6f0aade4 | ||
|
0ed256ba15 | ||
|
19c9667a3d | ||
|
2736fa57bb | ||
|
3a09b3614c | ||
|
b6e9e4171d | ||
|
4b2dcbb4f0 | ||
|
4349657f79 | ||
|
6e16584816 | ||
|
eb27813c18 | ||
|
1d3f0dfa9e | ||
|
bda96dc595 | ||
|
6ba2878605 | ||
|
85a25302bf | ||
|
b8dfad40bb | ||
|
054a99cf6c | ||
|
ada96ccdc8 | ||
|
1404d0186c | ||
|
a17d8bd566 | ||
|
88b017d9b1 | ||
|
fe6e4bea8c | ||
|
0705b74656 | ||
|
e8db73e0e7 | ||
|
4b7f2546bd | ||
|
ec437b1c66 | ||
|
9f0612bce8 | ||
|
871a673a46 | ||
|
34511a66ee | ||
|
2ffbf8b7b3 | ||
|
583c7ee22f | ||
|
4257073a02 | ||
|
67e077348c | ||
|
298f0f4335 | ||
|
d5e8e3ca44 | ||
|
45a90e4967 | ||
|
caec4a560b | ||
|
a326e22986 | ||
|
3375c4e187 | ||
|
c12fc5e313 | ||
|
d1583035d9 | ||
|
5eaae4175c | ||
|
e53f1bfd66 | ||
|
88e55b2504 | ||
|
a0c7b48b8e | ||
|
2314c41ad6 | ||
|
52d1906589 | ||
|
1d3098baa7 | ||
|
c3c5ab3473 | ||
|
cf9332f0e5 | ||
|
4aaf3d06bc | ||
|
dc25e7a887 | ||
|
894e3cebc0 | ||
|
e8eee76b48 | ||
|
279e63c97a | ||
|
47f73269bb | ||
|
7322f3286b | ||
|
1b2a8a5a04 | ||
|
bea5c60a11 | ||
|
29bb359e90 | ||
|
50406adc34 | ||
|
3a41bff9ea | ||
|
241d36471d | ||
|
1b937a77b9 | ||
|
f2918709d9 | ||
|
ac7b2da611 | ||
|
c4f2fb2fa4 | ||
|
624429b54c | ||
|
a631fa3518 | ||
|
5a0cf8e348 | ||
|
2fa63c7f37 | ||
|
9671a8451f | ||
|
71a64974c0 | ||
|
2e7b51c8e1 | ||
|
39157f2f19 | ||
|
a57fda6ba4 | ||
|
72900ca8aa | ||
|
947ece0bc9 | ||
|
bdf7e5293f | ||
|
1d6455c289 | ||
|
755ab72495 | ||
|
76c43ebc82 | ||
|
e6edf21552 | ||
|
18e3cc7038 | ||
|
8d61419836 | ||
|
c5282f9454 | ||
|
822b6ae6a0 | ||
|
37de10f47d | ||
|
5932391c8b | ||
|
e9c7ab4cfc | ||
|
4a5b5f954f | ||
|
cfc11ea83b | ||
|
75f0bbb7ca | ||
|
2d98530976 | ||
|
5e1f4839da | ||
|
0aa73c2279 | ||
|
f9613d28c0 | ||
|
d00687ca41 | ||
|
4cf746f167 | ||
|
22f167dd0a | ||
|
30520d262b | ||
|
4560844994 | ||
|
e051504dea | ||
|
71ce13d309 | ||
|
0fc081fe03 | ||
|
60a717b1a2 | ||
|
887c409b13 | ||
|
351c60a131 | ||
|
b19a2a760b | ||
|
d5dfa80876 | ||
|
82ca526ec2 | ||
|
85d494a987 | ||
|
da97a94a0f | ||
|
9538eb9716 | ||
|
6c3f56bb59 | ||
|
062007a8c0 | ||
|
f56bd4ce9d | ||
|
89a29e9a0d | ||
|
9363d4467f | ||
|
3681d3bbfd | ||
|
19fdf90cf4 | ||
|
dcd209a3d1 | ||
|
17c5a03938 | ||
|
d025fc7c2c | ||
|
c16f37198b | ||
|
9b46354bef | ||
|
ca2c72af0c | ||
|
b3a8228899 | ||
|
411c10ec31 | ||
|
3ed01b33e7 | ||
|
76234de7d6 | ||
|
32978b6a06 | ||
|
e2d8397c08 | ||
|
37eed43b68 | ||
|
074d3420c8 | ||
|
f45e094adf | ||
|
994f373a14 | ||
|
1c3372b319 | ||
|
ff1fce18d6 | ||
|
c4ab17f587 | ||
|
1c86796eac | ||
|
02d52d94d5 | ||
|
86bcea9e99 | ||
|
b0c4ade926 | ||
|
ab7c6e162f | ||
|
2c5015add7 | ||
|
31badd2eb3 | ||
|
60a49af886 | ||
|
d1f50157c7 | ||
|
95618dd238 | ||
|
75339323d2 | ||
|
2e7d4763dc | ||
|
c4b8ff314a | ||
|
ea1bc81925 | ||
|
bf83493c8d | ||
|
8165c8676c | ||
|
77e73fea32 | ||
|
fafb998b8c | ||
|
c7abb3dd96 | ||
|
1d76d9170e | ||
|
69ef5bfc8d | ||
|
4a59e544ba | ||
|
59ce48a3f3 | ||
|
fd4fbfddb9 | ||
|
7cd4929bfd | ||
|
55ff9b0c81 | ||
|
91b2e50252 | ||
|
6d0e68d626 | ||
|
92aeae73de | ||
|
f2357b36e5 | ||
|
7cbd56896a | ||
|
cf9e149b33 | ||
|
977faebcb8 | ||
|
9a831a6fe4 | ||
|
b969272c90 | ||
|
c99feeea31 | ||
|
1d0943bb30 | ||
|
5689898a5a | ||
|
0ca018b309 | ||
|
f99f71cc6e | ||
|
4118f97812 | ||
|
1777b9dee8 | ||
|
516f9de3e4 | ||
|
4f7c675ae3 | ||
|
98e74a3217 | ||
|
fc2241fbf4 | ||
|
c3cc83ae17 | ||
|
884c89c61c | ||
|
f1aae6af49 | ||
|
90fdea29b8 | ||
|
b2141a9050 | ||
|
aa83fa2dcf | ||
|
f61e88b842 | ||
|
9e0a7ddf57 | ||
|
a9f7153fdf | ||
|
7d1da9f1f9 | ||
|
3320eae95c | ||
|
392c7ad2ac | ||
|
9ef1babb9d | ||
|
f5725714d1 | ||
|
2aebbe3f47 | ||
|
6475330048 | ||
|
b84a546920 | ||
|
fa6c291d3e | ||
|
3442085a3c | ||
|
6cf5797049 | ||
|
1159403aee | ||
|
dafdf33062 | ||
|
de89c86ca9 | ||
|
05f8850acf | ||
|
d86ae69961 | ||
|
6aa945a4f5 | ||
|
e9bb0b3cdd | ||
|
fc922b607c | ||
|
7ba00b0157 | ||
|
d03db14129 | ||
|
d7ca217872 | ||
|
8a2b86dc83 | ||
|
980ac17388 | ||
|
b210090837 | ||
|
d7dfe5d4ed | ||
|
1c3c3c8db9 | ||
|
f3b5da0049 | ||
|
52eb94cfc4 | ||
|
e468acc99e | ||
|
5855906e49 | ||
|
f556003de3 | ||
|
7af7db74cd | ||
|
9cd0def361 | ||
|
b9e56843a2 | ||
|
cdf99b08f4 | ||
|
27366bdfdf | ||
|
1d43adcdfa | ||
|
f857a757a7 | ||
|
63477fc096 | ||
|
8f0771183c | ||
|
93d240a23b | ||
|
3eb73774a3 | ||
|
d081c41ae7 | ||
|
f221f5d744 | ||
|
f89780f332 | ||
|
2bf339a3f8 | ||
|
bfe13d9d68 | ||
|
6356c7f276 | ||
|
40765f1173 | ||
|
cf20b02c09 | ||
|
9afa412a2a | ||
|
b0bdd2be1c | ||
|
84a93b5441 | ||
|
e614af1c4a | ||
|
73d3e41cea | ||
|
c9aeef94ea | ||
|
8728ac2f6a | ||
|
f0329298ac | ||
|
977321cf64 | ||
|
1235c697c4 | ||
|
53d641736f | ||
|
3ee4876214 | ||
|
cdf5801efe | ||
|
2c83c354cf | ||
|
1fb5757655 | ||
|
3cc00771fa | ||
|
22571d4b38 | ||
|
4820b2ffe8 | ||
|
c32ba844e0 | ||
|
b31b2425f8 | ||
|
ac2ccaeff6 | ||
|
fd52ca8fe6 | ||
|
28fdc376b2 | ||
|
bd1a571399 | ||
|
6f9f0e8b0e | ||
|
3e1fe687b8 | ||
|
d69a8e84fa | ||
|
f6248a88ba | ||
|
1635bfafb3 | ||
|
00a3f84ea7 | ||
|
21d37d1e23 | ||
|
be31f417db | ||
|
8390d0ef72 | ||
|
e57ff28231 | ||
|
6c023785e5 | ||
|
31bc47d1cb | ||
|
ef9f809e14 | ||
|
2870d3ae6c | ||
|
c2fae47391 | ||
|
d2d97319e0 | ||
|
c78177eedf | ||
|
085c9ab2e1 | ||
|
fab49f8557 | ||
|
0313277ae6 | ||
|
f895da8634 | ||
|
45e7638fc2 | ||
|
969de9a8bc | ||
|
b45d7c372d | ||
|
d7293a44df | ||
|
110c82c225 | ||
|
db50131ed4 | ||
|
d832a6c908 | ||
|
51c5257548 | ||
|
2a299fe275 | ||
|
8ac1ae70cc | ||
|
2b30ff4fc6 | ||
|
c9dedfd402 | ||
|
4f6d7e2c63 | ||
|
2dd7b8ba2c | ||
|
16502b788f | ||
|
85c99797da | ||
|
40392d7b91 | ||
|
df8ea7fe52 | ||
|
b91100573e | ||
|
780a811f05 | ||
|
55f8908769 | ||
|
9c175e2f0c | ||
|
5b969ccfa9 | ||
|
81a36dc31e | ||
|
30b32e4c8a | ||
|
099364e619 | ||
|
faed0d4900 | ||
|
9851ed33d8 | ||
|
639fd3a9bd | ||
|
5789f1527c | ||
|
16ea069d55 | ||
|
3cef05b745 | ||
|
c0bb88799c | ||
|
ee44b6ff49 | ||
|
bc82905371 | ||
|
637ed8033b | ||
|
fc6458a35c | ||
|
e0d01411d7 | ||
|
477ff32edc | ||
|
044036e884 | ||
|
df8d396472 | ||
|
0eeed5ac33 | ||
|
c3d8ee14fe | ||
|
dec4bab334 | ||
|
6192775161 | ||
|
7c28de0b6f | ||
|
10f610b219 | ||
|
e51c3eee4e | ||
|
f0e9d13329 | ||
|
40afae3833 | ||
|
23bde0d18e | ||
|
fbb4e8c6ae | ||
|
6bffc7d528 | ||
|
52ee25e551 | ||
|
1d341a7aeb | ||
|
0d083a2bea | ||
|
fe33c756b7 | ||
|
cd7ca458fa | ||
|
6776776421 | ||
|
8a694adb09 | ||
|
7e92577c14 | ||
|
f1346f098e | ||
|
643077341b | ||
|
275a84b323 | ||
|
d307c6bd9e | ||
|
9fb3755088 | ||
|
707446ed52 | ||
|
81a143173f | ||
|
c086520c97 | ||
|
90ea1071d1 | ||
|
2194a339cf | ||
|
5eb56d9a06 | ||
|
ff81a72533 | ||
|
d35a54c060 | ||
|
baa7e1bf12 | ||
|
44889adda0 | ||
|
d2dc719b31 | ||
|
3e9c30a18f | ||
|
7f2ee62aed | ||
|
e9248b225e | ||
|
f7643a4d82 | ||
|
c0b84537b3 | ||
|
c50f2b70c2 | ||
|
937d3e1933 | ||
|
382db668ed | ||
|
273a94f298 | ||
|
65423b3c94 | ||
|
abd8f343e4 | ||
|
b3e6da7514 | ||
|
b7aa04e1f5 | ||
|
285ac9e4c8 | ||
|
c30e54c7b7 | ||
|
2992f4afd2 | ||
|
f244c960d3 | ||
|
10b5d30ec3 | ||
|
28abeae21b | ||
|
f9319dfb91 | ||
|
09aaa58710 | ||
|
a618f43b4d | ||
|
e6dcb3009f | ||
|
5bdef365f2 | ||
|
12aeb46889 | ||
|
79ee65bfd5 | ||
|
a0a05553cf | ||
|
e6bc485679 | ||
|
514481ef7f | ||
|
a1ba187c47 | ||
|
2e8bc634dc | ||
|
7b75ca591d | ||
|
574434550a | ||
|
6222b7c223 | ||
|
1ae22f45f9 | ||
|
f2f22184b0 | ||
|
a69be1520a | ||
|
7a6ceadb24 | ||
|
ec2469a6c1 | ||
|
34949a47c5 | ||
|
ce26ef8a67 | ||
|
e4d9636e82 | ||
|
7cc73b7832 | ||
|
a25ce5d8fc | ||
|
057de4e6b5 | ||
|
926553d043 | ||
|
487ae478ad | ||
|
1bdaf581a3 | ||
|
6b95fd841f | ||
|
54ccd2cc07 | ||
|
1ba99d2427 | ||
|
10ef3a749e | ||
|
a1a6eae43f | ||
|
bb26c68f2c | ||
|
b3e3d75d0f | ||
|
fc93bdbbba | ||
|
d666c5004f | ||
|
547b5a8699 | ||
|
1ddb1f0832 | ||
|
d6cccc2dcd | ||
|
0a0f28fff4 | ||
|
5e4d3c87e9 | ||
|
12b14176ec | ||
|
93893511f1 | ||
|
db784fc2fb | ||
|
331fc2be69 | ||
|
97c761a5c7 | ||
|
dc2b5f0c6b | ||
|
3e42297bd8 | ||
|
329482f873 | ||
|
baffa1594f | ||
|
93ccbf38e8 | ||
|
2a3e126390 | ||
|
0d24d2b81e | ||
|
fe64176e7b | ||
|
7ac6bdfe71 | ||
|
57b3397078 | ||
|
7133287b76 | ||
|
5bc40c9287 | ||
|
95b8a56dd4 | ||
|
b5eabf6604 | ||
|
a07b6382ae | ||
|
d15509f14e | ||
|
e2efb193c4 | ||
|
a5616b0bc8 | ||
|
af10747c94 | ||
|
3e70554844 | ||
|
7efe2b7c51 | ||
|
5c183bef85 | ||
|
db99ac88d9 | ||
|
4f378e8726 | ||
|
7fee2c2589 | ||
|
829b16a303 | ||
|
748e31421d | ||
|
e21f6a7f41 | ||
|
f970dc9993 | ||
|
6a91b83b12 | ||
|
084123b752 | ||
|
ffa51612fc | ||
|
da36d4a5a1 | ||
|
0842a13339 | ||
|
3e5ad49e3a | ||
|
899bee2cf5 | ||
|
06dfe14251 | ||
|
f78c9bfcab | ||
|
5ae4192d8d | ||
|
f3f5eb5739 | ||
|
6b3be0f5a1 | ||
|
07b3a507b4 | ||
|
c396925766 | ||
|
c77634ce32 | ||
|
99e26bdd4c | ||
|
f5639db8ed | ||
|
61a4642221 | ||
|
ab59b9b830 | ||
|
3b0fcc2a73 | ||
|
94aefed98f | ||
|
217f16d189 | ||
|
8031cd1b40 | ||
|
d13b0a7ec5 | ||
|
4217a8cb65 | ||
|
e28516002b | ||
|
4e435e93e0 | ||
|
38f40034b0 | ||
|
7075b7f264 | ||
|
d1842a3686 | ||
|
dea4beba13 | ||
|
69894853ac | ||
|
bdb5965f1a | ||
|
2f479e5fc7 | ||
|
2edf41be8e | ||
|
9bd180896e | ||
|
4f21748aa2 | ||
|
f317d54218 | ||
|
660a8597f6 | ||
|
0045fb16b6 | ||
|
6889cf1ed8 | ||
|
800daecf90 | ||
|
f3b40cb7a6 | ||
|
be22a9b1b8 | ||
|
878dd1a776 | ||
|
50b92e5dd6 | ||
|
d5d8438b60 | ||
|
8f16574992 | ||
|
7edfc53481 | ||
|
38ab0add48 | ||
|
14721e8f1e | ||
|
c3f854ba65 | ||
|
883700fca1 | ||
|
ef999e8dd3 | ||
|
572be3e857 | ||
|
be505fc15f | ||
|
266573deff | ||
|
607af27ba8 | ||
|
b130ffa39c | ||
|
20a24f8cf5 | ||
|
c6dca25b9f | ||
|
84a6c88e98 | ||
|
d7b73f1182 | ||
|
f5d756928f | ||
|
ab1a3900a3 | ||
|
e90e8c7426 | ||
|
006771699f | ||
|
dbc2d23405 | ||
|
d6fcbe960e | ||
|
c575754b42 | ||
|
58a8507b3d | ||
|
d7962617e4 | ||
|
17c6583937 | ||
|
a1b3537e9e | ||
|
314a8ebba0 | ||
|
d4f4ed014c | ||
|
44d7c6d00f | ||
|
bf906bd573 | ||
|
772ea0b591 | ||
|
4d1626e3b6 | ||
|
2c7ad783fc | ||
|
8fb543f4c3 | ||
|
346d20db52 | ||
|
0ce98c7ac7 | ||
|
6d524ebea2 | ||
|
239b5547ea | ||
|
21b6f85140 | ||
|
123c6f1917 | ||
|
049174bd35 | ||
|
b1925ff286 | ||
|
caca6a5cff | ||
|
d0df278b0b | ||
|
ff00873f97 | ||
|
7f9cc51b05 | ||
|
f2d01166c3 | ||
|
79f0fcb07a | ||
|
1b6acdedc2 | ||
|
c0b0f8cb73 | ||
|
287399f993 | ||
|
c6969268fc | ||
|
b393105082 | ||
|
565601ef50 | ||
|
5c413016a7 | ||
|
249b6db6f5 | ||
|
5daaa5cf75 | ||
|
108bbc3642 | ||
|
6a92529272 | ||
|
a4968b5029 | ||
|
378fa6b401 | ||
|
8568b5f31b | ||
|
f6f28a95f6 | ||
|
9e8dd9a1e6 | ||
|
56af4a0b83 | ||
|
5da65494b3 | ||
|
d13dd6dee3 |
@ -8,9 +8,9 @@ AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
@ -83,6 +83,8 @@ IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
# Requires Clang >= 15, could also cause incorrect code formatting:
|
||||
# InsertBraces: true
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
|
12
.clang-tidy
@ -1,28 +1,36 @@
|
||||
Checks: '*,
|
||||
-altera-unroll-loops,
|
||||
-llvmlibc-callee-namespace,
|
||||
-llvmlibc-implementation-in-namespace,
|
||||
-llvmlibc-restrict-system-libc-headers,
|
||||
-llvm-header-guard,
|
||||
-llvm-namespace-comment,
|
||||
-google-build-using-namespace,
|
||||
-google-runtime-int,
|
||||
-google-readability-namespace-comments,
|
||||
-fuchsia-statically-constructed-objects,
|
||||
-cppcoreguidelines-prefer-member-initializer,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
-cppcoreguidelines-pro-type-union-access,
|
||||
-cppcoreguidelines-pro-type-cstyle-cast,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
-cppcoreguidelines-special-member-functions,
|
||||
-readability-magic-numbers,
|
||||
-readability-uppercase-literal-suffix,
|
||||
-modernize-use-trailing-return-type,
|
||||
-modernize-avoid-c-arrays,
|
||||
-hicpp-signed-bitwise,
|
||||
-hicpp-no-assembler,
|
||||
-hicpp-avoid-c-arrays,
|
||||
-hicpp-uppercase-literal-suffix,
|
||||
-hicpp-vararg,
|
||||
-hicpp-no-assembler,
|
||||
-hicpp-no-array-decay,
|
||||
-hicpp-signed-bitwise,
|
||||
-hicpp-special-member-functions,
|
||||
-cert-err58-cpp,
|
||||
-cert-err60-cpp'
|
||||
CheckOptions:
|
||||
|
65
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,65 @@
|
||||
FROM ubuntu:latest
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update -qq \
|
||||
&& apt-get install -y \
|
||||
# x86_64 / generic packages
|
||||
bash \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
make \
|
||||
python3 \
|
||||
python3-pip \
|
||||
tar \
|
||||
unzip \
|
||||
wget \
|
||||
curl \
|
||||
dos2unix \
|
||||
clang-format-12 \
|
||||
clang-tidy \
|
||||
locales \
|
||||
libncurses5 \
|
||||
# aarch64 packages
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
python3-dev \
|
||||
rustc \
|
||||
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/*;
|
||||
|
||||
#SET LOCALE
|
||||
RUN locale-gen en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN pip3 install adafruit-nrfutil
|
||||
# required for McuBoot
|
||||
RUN pip3 install setuptools_rust
|
||||
|
||||
WORKDIR /opt/
|
||||
# build.sh knows how to compile but it problimatic on Win10
|
||||
COPY build.sh .
|
||||
RUN chmod +x build.sh
|
||||
# create_build_openocd.sh uses cmake to crate to build directory
|
||||
COPY create_build_openocd.sh .
|
||||
RUN chmod +x create_build_openocd.sh
|
||||
# Lets get each in a separate docker layer for better downloads
|
||||
# GCC
|
||||
# RUN bash -c "source /opt/build.sh; GetGcc;"
|
||||
RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O - | tar -xj -C /opt
|
||||
# NrfSdk
|
||||
# RUN bash -c "source /opt/build.sh; GetNrfSdk;"
|
||||
RUN wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip" -O /tmp/nRF5_SDK_15.3.0_59ac345
|
||||
RUN unzip -q /tmp/nRF5_SDK_15.3.0_59ac345 -d /opt
|
||||
RUN rm /tmp/nRF5_SDK_15.3.0_59ac345
|
||||
# McuBoot
|
||||
# RUN bash -c "source /opt/build.sh; GetMcuBoot;"
|
||||
RUN git clone https://github.com/mcu-tools/mcuboot.git
|
||||
RUN pip3 install -r ./mcuboot/scripts/requirements.txt
|
||||
|
||||
RUN adduser infinitime
|
||||
|
||||
ENV NRF5_SDK_PATH /opt/nRF5_SDK_15.3.0_59ac345
|
||||
ENV ARM_NONE_EABI_TOOLCHAIN_PATH /opt/gcc-arm-none-eabi-9-2020-q2-update
|
||||
ENV SOURCES_DIR /workspaces/InfiniTime
|
60
.devcontainer/README.md
Normal file
@ -0,0 +1,60 @@
|
||||
# VS Code Dev Container
|
||||
This is a docker-based interactive development environment using VS Code and Docker Dev Containers removing the need to install any tools locally*
|
||||
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
- VS Code
|
||||
- [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
|
||||
- Docker
|
||||
- OpenOCD - For debugging
|
||||
|
||||
## Using
|
||||
|
||||
### Code editing, and building.
|
||||
|
||||
1. Clone InfiniTime and update submodules
|
||||
2. Launch VS Code
|
||||
3. Open InfiniTime directory,
|
||||
4. Allow VS Code to open folder with devcontainer.
|
||||
|
||||
After this the environment will be built if you do not currently have a container setup, it will install all the necessary tools and extra VSCode extensions.
|
||||
|
||||
In order to build InfiniTime we need to run the initial submodule init and CMake commands.
|
||||
|
||||
#### Manually
|
||||
|
||||
You can use the VS Code terminal to run the CMake commands as outlined in the [build instructions](blob/develop/doc/buildAndProgram.md)
|
||||
|
||||
#### Script
|
||||
|
||||
The dev environment comes with some scripts to make this easier, They are located in /opt/.
|
||||
|
||||
There are also VS Code tasks provided should you desire to use those.
|
||||
|
||||
The task "update submodules" will update the git submodules
|
||||
|
||||
|
||||
|
||||
### Build
|
||||
|
||||
You can use the build.sh script located in /opt/
|
||||
|
||||
CMake is also configured and controls for the CMake plugin are available in VS Code
|
||||
|
||||
|
||||
|
||||
### Debugging
|
||||
|
||||
Docker on windows does not support passing USB devices to the underlying WSL2 subsystem, To get around this we use OpenOCD in server mode running on the host.
|
||||
|
||||
`openocd -f <yourinterface> -f <nrf52.cfg target file>`
|
||||
|
||||
This will launch OpenOCD in server mode and attach it to the MCU.
|
||||
|
||||
The default launch.json file expects OpenOCD to be listening on port 3333, edit if needed
|
||||
|
||||
|
||||
## Current Issues
|
||||
Currently WSL2 Has some real performance issues with IO on a windows host. Accessing files on the virtualized filesystem is much faster. Using VS Codes "clone in container" feature of the Remote - Containers will get around this. After the container is built you will need to update the submodules and follow the build instructions like normal
|
78
.devcontainer/build.sh
Normal file
@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
(return 0 2>/dev/null) && SOURCED="true" || SOURCED="false"
|
||||
export LC_ALL=C.UTF-8
|
||||
export LANG=C.UTF-8
|
||||
set -x
|
||||
set -e
|
||||
|
||||
# Default locations if the var isn't already set
|
||||
export TOOLS_DIR="${TOOLS_DIR:=/opt}"
|
||||
export SOURCES_DIR="${SOURCES_DIR:=/sources}"
|
||||
export BUILD_DIR="${BUILD_DIR:=$SOURCES_DIR/build}"
|
||||
export OUTPUT_DIR="${OUTPUT_DIR:=$BUILD_DIR/output}"
|
||||
|
||||
export BUILD_TYPE=${BUILD_TYPE:=Release}
|
||||
export GCC_ARM_VER=${GCC_ARM_VER:="gcc-arm-none-eabi-9-2020-q2-update"}
|
||||
export NRF_SDK_VER=${NRF_SDK_VER:="nRF5_SDK_15.3.0_59ac345"}
|
||||
|
||||
MACHINE="$(uname -m)"
|
||||
[[ "$MACHINE" == "arm64" ]] && MACHINE="aarch64"
|
||||
|
||||
main() {
|
||||
local target="$1"
|
||||
|
||||
mkdir -p "$TOOLS_DIR"
|
||||
|
||||
[[ ! -d "$TOOLS_DIR/$GCC_ARM_VER" ]] && GetGcc
|
||||
[[ ! -d "$TOOLS_DIR/$NRF_SDK_VER" ]] && GetNrfSdk
|
||||
[[ ! -d "$TOOLS_DIR/mcuboot" ]] && GetMcuBoot
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
CmakeGenerate
|
||||
CmakeBuild $target
|
||||
BUILD_RESULT=$?
|
||||
if [ "$DISABLE_POSTBUILD" != "true" -a "$BUILD_RESULT" == 0 ]; then
|
||||
source "$BUILD_DIR/post_build.sh"
|
||||
fi
|
||||
}
|
||||
|
||||
GetGcc() {
|
||||
GCC_SRC="$GCC_ARM_VER-$MACHINE-linux.tar.bz"
|
||||
wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/$GCC_SRC -O - | tar -xj -C $TOOLS_DIR/
|
||||
}
|
||||
|
||||
GetMcuBoot() {
|
||||
git clone https://github.com/mcu-tools/mcuboot.git "$TOOLS_DIR/mcuboot"
|
||||
pip3 install -r "$TOOLS_DIR/mcuboot/scripts/requirements.txt"
|
||||
}
|
||||
|
||||
GetNrfSdk() {
|
||||
wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/$NRF_SDK_VER.zip" -O /tmp/$NRF_SDK_VER
|
||||
unzip -q /tmp/$NRF_SDK_VER -d "$TOOLS_DIR/"
|
||||
rm /tmp/$NRF_SDK_VER
|
||||
}
|
||||
|
||||
CmakeGenerate() {
|
||||
# We can swap the CD and trailing SOURCES_DIR for -B and -S respectively
|
||||
# once we go to newer CMake (Ubuntu 18.10 gives us CMake 3.10)
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DUSE_OPENOCD=1 \
|
||||
-DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_VER" \
|
||||
-DNRF5_SDK_PATH="$TOOLS_DIR/$NRF_SDK_VER" \
|
||||
"$SOURCES_DIR"
|
||||
cmake -L -N .
|
||||
}
|
||||
|
||||
CmakeBuild() {
|
||||
local target="$1"
|
||||
[[ -n "$target" ]] && target="--target $target"
|
||||
if cmake --build "$BUILD_DIR" --config $BUILD_TYPE $target -- -j$(nproc)
|
||||
then return 0; else return 1;
|
||||
fi
|
||||
}
|
||||
|
||||
[[ $SOURCED == "false" ]] && main "$@" || echo "Sourced!"
|
2
.devcontainer/build_app.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
cmake --build /workspaces/Pinetime/build --config Release -- -j6 pinetime-app
|
3
.devcontainer/create_build_openocd.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
rm -rf build/
|
||||
cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 -S . -Bbuild
|
38
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,38 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.2/containers/cpp
|
||||
{
|
||||
// "name": "Pinetime",
|
||||
// "image": "feabhas/pinetime-dev"
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
// "args": { "VARIANT": "ubuntu-20.04" }
|
||||
},
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash",
|
||||
"editor.formatOnSave": true,
|
||||
"clang-format.executable": "clang-format-12"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"ms-vscode.cmake-tools",
|
||||
"marus25.cortex-debug",
|
||||
"notskm.clang-tidy",
|
||||
"mjohns.clang-format"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "bash /opt/create_build_openocd.sh",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
// "remoteUser": "vscode"
|
||||
"remoteUser": "infinitime"
|
||||
}
|
2
.devcontainer/make_build_dir.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 ${SOURCES_DIR}
|
59
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
name: Bug Report
|
||||
description: File a bug report
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thanks for taking the time to fill out this bug report!**
|
||||
*Please, before opening a bug report, check if similar issues already exist. In that case, use those issues to provide your feedback instead.*
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Verification
|
||||
options:
|
||||
- label: I searched for similar bug reports and found none was relevant.
|
||||
required: true
|
||||
- type: input
|
||||
id: desc-brief
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: A one-line description of the bug.
|
||||
placeholder: "Ex. I woke up as a Kafkian insect this morning."
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: desc-expected
|
||||
attributes:
|
||||
label: What should happen instead?
|
||||
description: The behaviour you were expecting to see.
|
||||
placeholder: "Ex. I was expecting to wake up as a human."
|
||||
- type: textarea
|
||||
id: desc-steps
|
||||
attributes:
|
||||
label: Reproduction steps
|
||||
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desc-long
|
||||
attributes:
|
||||
label: More details?
|
||||
description: Give us more details about the bug and any personal attempts you made to fix it.
|
||||
placeholder: Tell us more!
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: |
|
||||
What [version of the firmware](https://github.com/JF002/InfiniTime/blob/develop/doc/gettingStarted/gettingStarted-1.0.md#how-to-check-the-version-of-infinitime-and-the-bootloader) are you running?
|
||||
If you are running an older version, please consider [updating to the latest firmware](https://github.com/JF002/InfiniTime/blob/develop/doc/gettingStarted/gettingStarted-1.0.md#how-to-update-your-pinetime).
|
||||
If you are running directly from git, specify the branch or the commit hash directly.
|
||||
placeholder: "Ex. v1.6.0 or develop or fc922b60"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: companion-app
|
||||
attributes:
|
||||
label: Companion app
|
||||
description: Which companion app are you using (if relevant)?
|
||||
placeholder: "Ex. Gadgetbridge v0.60.0, Siglo v0.9.4"
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: PineTime community chat (Matrix)
|
||||
url: https://app.element.io/#/room/#pinetime:matrix.org
|
||||
about: Please ask questions about PineTime here.
|
||||
- name: PineTime developers chat (Matrix)
|
||||
url: https://app.element.io/#/room/#pinetime-dev:matrix.org
|
||||
about: Please ask questions about PineTime development here.
|
41
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
name: Feature Request
|
||||
description: File a feature request
|
||||
labels: ["feature request"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thanks for taking the time to fill out this feature request!**
|
||||
*Please, before opening a feature request, check if similar issues already exist. In that case, use those issues to provide your feedback instead.*
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Verification
|
||||
options:
|
||||
- label: I searched for similar feature request and found none was relevant.
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Note:** keep in mind that, while InfiniTime is usable, it is still under heavy development and as such it is continuously evolving.
|
||||
Some features you want to see implemented might not be compatible with the current state of the project, or might not even be suitable to include *in the firmware* of the watch.
|
||||
- type: input
|
||||
id: desc-brief
|
||||
attributes:
|
||||
label: Pitch us your idea!
|
||||
description: A one-line elevator pitch of the feature you'd like to see implemented.
|
||||
placeholder: "Ex. My dog wants InfiniTime on its smart collar."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desc-long
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Give us a detailed description of the feature you are proposing. Mockups or a description of the possible use cases are highly appreciated.
|
||||
Tell us why this should be included in the firmware.
|
||||
placeholder: "Ex. Here is a drawing of my dog wearing an InfiniTime collar and smiling."
|
||||
- type: markdown
|
||||
id: companion-app
|
||||
attributes:
|
||||
value: |
|
||||
If this requires features missing from other software (for example a companion app), please take care of opening any relevant feature request over there as well.
|
37
.github/workflows/format.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Code formatting
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master, develop ]
|
||||
paths:
|
||||
- '**.cpp'
|
||||
- '**.h'
|
||||
- '!src/libs/**'
|
||||
- '!src/FreeRTOS/**'
|
||||
|
||||
jobs:
|
||||
test-format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1000
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git fetch origin "$GITHUB_BASE_REF":"$GITHUB_BASE_REF" --depth=1000
|
||||
|
||||
- name: Install clang-format
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install clang-format-12
|
||||
|
||||
- name: Check formatting
|
||||
run: tests/test-format.sh
|
||||
|
||||
- name: Upload patches
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: Patches
|
||||
path: ./*.patch
|
66
.github/workflows/lv_sim.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
# GitHub Actions Workflow to build Simulator for PineTime Smart Watch LVGL Interface
|
||||
|
||||
name: Build PineTime LVGL Simulator
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, develop ]
|
||||
pull_request:
|
||||
branches: [ master, develop ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
#########################################################################################
|
||||
# Download and Install Dependencies
|
||||
|
||||
- name: Install cmake
|
||||
uses: lukka/get-cmake@v3.18.3
|
||||
|
||||
- name: Install SDL2 development package
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install libsdl2-dev
|
||||
|
||||
- name: Install lv_font_conv
|
||||
run:
|
||||
npm i -g lv_font_conv@1.5.2
|
||||
|
||||
#########################################################################################
|
||||
# Checkout
|
||||
|
||||
- name: Checkout source files
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
#########################################################################################
|
||||
# get InfiniSim repo
|
||||
|
||||
- name: Get InfiniSim repo
|
||||
run: |
|
||||
git clone https://github.com/InfiniTimeOrg/InfiniSim.git --depth 1 --branch main
|
||||
git -C InfiniSim submodule update --init lv_drivers libpng
|
||||
|
||||
#########################################################################################
|
||||
# CMake
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -G Ninja -S InfiniSim -B build_lv_sim -DInfiniTime_DIR="${PWD}"
|
||||
|
||||
#########################################################################################
|
||||
# Build and Upload simulator
|
||||
|
||||
- name: Build simulator executable
|
||||
run: |
|
||||
cmake --build build_lv_sim
|
||||
|
||||
- name: Upload simulator executable
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: infinisim-${{ github.head_ref }}
|
||||
path: build_lv_sim/infinisim
|
178
.github/workflows/main.yml
vendored
@ -3,169 +3,45 @@
|
||||
# Based on https://github.com/JF002/InfiniTime/blob/master/doc/buildAndProgram.md
|
||||
# and https://github.com/JF002/InfiniTime/blob/master/bootloader/README.md
|
||||
|
||||
# Name of this Workflow
|
||||
name: Build PineTime Firmware
|
||||
|
||||
# When to run this Workflow...
|
||||
on:
|
||||
|
||||
# Run this Workflow when files are updated (Pushed) in the "master" Branch
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
# Also run this Workflow when a Pull Request is created or updated in the "master" Branch
|
||||
branches: [ master, develop ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches: [ master, develop ]
|
||||
|
||||
# Steps to run for the Workflow
|
||||
jobs:
|
||||
build:
|
||||
|
||||
# Run these steps on Ubuntu
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container:
|
||||
image: infinitime/infinitime-build
|
||||
steps:
|
||||
|
||||
#########################################################################################
|
||||
# Download and Cache Dependencies
|
||||
|
||||
- name: Install cmake
|
||||
uses: lukka/get-cmake@v3.18.3
|
||||
|
||||
- name: Check cache for Embedded Arm Toolchain arm-none-eabi-gcc
|
||||
id: cache-toolchain
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-toolchain-9-2020-q2
|
||||
with:
|
||||
path: ${{ runner.temp }}/arm-none-eabi
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
|
||||
- name: Install Embedded Arm Toolchain arm-none-eabi-gcc
|
||||
if: steps.cache-toolchain.outputs.cache-hit != 'true' # Install toolchain if not found in cache
|
||||
uses: fiam/arm-none-eabi-gcc@v1.0.2
|
||||
with:
|
||||
# GNU Embedded Toolchain for Arm release name, in the V-YYYY-qZ format (e.g. "9-2019-q4")
|
||||
release: 9-2020-q2
|
||||
# Directory to unpack GCC to. Defaults to a temporary directory.
|
||||
directory: ${{ runner.temp }}/arm-none-eabi
|
||||
|
||||
- name: Check cache for nRF5 SDK
|
||||
id: cache-nrf5sdk
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-nrf5sdk
|
||||
with:
|
||||
path: ${{ runner.temp }}/nrf5_sdk
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
|
||||
- name: Install nRF5 SDK
|
||||
if: steps.cache-nrf5sdk.outputs.cache-hit != 'true' # Install SDK if not found in cache
|
||||
run: |
|
||||
cd ${{ runner.temp }}
|
||||
curl https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip -o nrf5_sdk.zip
|
||||
unzip nrf5_sdk.zip
|
||||
mv nRF5_SDK_15.3.0_59ac345 nrf5_sdk
|
||||
|
||||
- name: Check cache for MCUBoot
|
||||
id: cache-mcuboot
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-mcuboot
|
||||
with:
|
||||
path: ${{ runner.temp }}/mcuboot
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}
|
||||
|
||||
- name: Install MCUBoot
|
||||
if: steps.cache-mcuboot.outputs.cache-hit != 'true' # Install MCUBoot if not found in cache
|
||||
run: |
|
||||
cd ${{ runner.temp }}
|
||||
git clone --branch v1.5.0 https://github.com/JuulLabs-OSS/mcuboot
|
||||
|
||||
- name: Install imgtool dependencies
|
||||
run: pip3 install --user -r ${{ runner.temp }}/mcuboot/scripts/requirements.txt
|
||||
|
||||
- name: Install adafruit-nrfutil
|
||||
run: |
|
||||
pip3 install --user wheel
|
||||
pip3 install --user setuptools
|
||||
pip3 install --user adafruit-nrfutil
|
||||
|
||||
#########################################################################################
|
||||
# Checkout
|
||||
|
||||
# This workaround fixes the error "unsafe repository (REPO is owned by someone else)".
|
||||
# See https://github.com/actions/checkout/issues/760 and https://github.com/actions/checkout/issues/766
|
||||
# The fix in "actions/checkout@v2" was not sufficient as the build process also uses git (to get the current
|
||||
# commit hash, for example).
|
||||
- name: Workaround permission issues
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- name: Checkout source files
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Show files
|
||||
run: set ; pwd ; ls -l
|
||||
|
||||
#########################################################################################
|
||||
# CMake
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=${{ runner.temp }}/arm-none-eabi -DNRF5_SDK_PATH=${{ runner.temp }}/nrf5_sdk -DUSE_OPENOCD=1 ../
|
||||
|
||||
#########################################################################################
|
||||
# Make and Upload DFU Package
|
||||
# pinetime-mcuboot-app.img must be flashed at address 0x8000 in the internal flash memory with OpenOCD:
|
||||
# program image.bin 0x8000
|
||||
|
||||
# For Debugging Builds: Remove "make" option "-j" for clearer output. Add "--trace" to see details.
|
||||
# For Faster Builds: Add "make" option "-j"
|
||||
|
||||
- name: Make pinetime-mcuboot-app
|
||||
run: |
|
||||
cd build
|
||||
make pinetime-mcuboot-app
|
||||
|
||||
- name: Create firmware image
|
||||
run: |
|
||||
# The generated firmware binary looks like "pinetime-mcuboot-app-0.8.2.bin"
|
||||
ls -l build/src/pinetime-mcuboot-app*.bin
|
||||
${{ runner.temp }}/mcuboot/scripts/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header build/src/pinetime-mcuboot-app*.bin build/src/pinetime-mcuboot-app-img.bin
|
||||
${{ runner.temp }}/mcuboot/scripts/imgtool.py verify build/src/pinetime-mcuboot-app-img.bin
|
||||
|
||||
- name: Create DFU package
|
||||
run: |
|
||||
~/.local/bin/adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application build/src/pinetime-mcuboot-app-img.bin build/src/pinetime-mcuboot-app-dfu.zip
|
||||
unzip -v build/src/pinetime-mcuboot-app-dfu.zip
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build
|
||||
shell: bash
|
||||
env:
|
||||
SOURCES_DIR: .
|
||||
run: /opt/build.sh all
|
||||
# Unzip the package because Upload Artifact will zip up the files
|
||||
unzip build/src/pinetime-mcuboot-app-dfu.zip -d build/src/pinetime-mcuboot-app-dfu
|
||||
|
||||
- name: Upload DFU package
|
||||
uses: actions/upload-artifact@v2
|
||||
- name: Unzip DFU package
|
||||
run: unzip ./build/output/pinetime-mcuboot-app-dfu-*.zip -d ./build/output/pinetime-mcuboot-app-dfu
|
||||
- name: Upload DFU artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: pinetime-mcuboot-app-dfu
|
||||
path: build/src/pinetime-mcuboot-app-dfu/*
|
||||
|
||||
#########################################################################################
|
||||
# Make and Upload Standalone Firmware
|
||||
|
||||
- name: Make pinetime-app
|
||||
run: |
|
||||
cd build
|
||||
make pinetime-app
|
||||
|
||||
- name: Upload standalone firmware
|
||||
uses: actions/upload-artifact@v2
|
||||
name: InfiniTime DFU ${{ github.head_ref }}
|
||||
path: ./build/output/pinetime-mcuboot-app-dfu/*
|
||||
- name: Upload MCUBoot image artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: pinetime-app.out
|
||||
path: build/src/pinetime-app*.out
|
||||
|
||||
#########################################################################################
|
||||
# Finish
|
||||
|
||||
- name: Find output
|
||||
run: |
|
||||
find . -name "pinetime-app.*" -ls
|
||||
find . -name "pinetime-mcuboot-app.*" -ls
|
||||
|
||||
# Embedded Arm Toolchain and nRF5 SDK will only be cached if the build succeeds.
|
||||
# So make sure that the first build always succeeds, e.g. comment out the "Make" step.
|
||||
name: InfiniTime MCUBoot image ${{ github.head_ref }}
|
||||
path: ./build/output/pinetime-mcuboot-app-image-*.bin
|
||||
|
10
.gitignore
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
# CMake
|
||||
cmake-build-*
|
||||
cmake-*
|
||||
cmake-*/
|
||||
CMakeFiles
|
||||
**/CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
@ -39,3 +39,11 @@ Testing/Temporary/
|
||||
|
||||
# Windows
|
||||
**/thumbs.db
|
||||
|
||||
#VSCODE
|
||||
.vscode/.cortex-debug.registers.state.json
|
||||
.vscode/.cortex-debug.peripherals.state.json
|
||||
|
||||
#build files
|
||||
src/nRF5_SDK_15.3.0_59ac345
|
||||
src/arm-none-eabi
|
||||
|
6
.gitmodules
vendored
@ -1,3 +1,9 @@
|
||||
[submodule "src/libs/lvgl"]
|
||||
path = src/libs/lvgl
|
||||
url = https://github.com/joaquimorg/lvgl.git
|
||||
[submodule "src/libs/littlefs"]
|
||||
path = src/libs/littlefs
|
||||
url = https://github.com/littlefs-project/littlefs.git
|
||||
[submodule "src/libs/QCBOR"]
|
||||
path = src/libs/QCBOR
|
||||
url = https://github.com/laurencelundblade/QCBOR.git
|
||||
|
23
.idea/codeStyles/Project.xml
generated
@ -12,6 +12,29 @@
|
||||
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||
</Objective-C>
|
||||
<Objective-C-extensions>
|
||||
<rules>
|
||||
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
||||
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||
</rules>
|
||||
</Objective-C-extensions>
|
||||
<clangFormatSettings>
|
||||
<option name="ENABLED" value="true" />
|
||||
</clangFormatSettings>
|
||||
<codeStyleSettings language="ObjectiveC">
|
||||
<option name="RIGHT_MARGIN" value="140" />
|
||||
<option name="IF_BRACE_FORCE" value="3" />
|
||||
|
20
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "nrfCC",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/src/**",
|
||||
"${workspaceFolder}/src"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++14",
|
||||
"intelliSenseMode": "linux-gcc-arm",
|
||||
"configurationProvider": "ms-vscode.cpp-tools",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
62
.vscode/cmake-variants.json
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"buildType": {
|
||||
"default": "release",
|
||||
"choices": {
|
||||
"debug": {
|
||||
"short": "Debug",
|
||||
"long": "Emit debug information without performing optimizations",
|
||||
"buildType": "Debug"
|
||||
},
|
||||
"release": {
|
||||
"short": "Release",
|
||||
"long": "Perform optimizations",
|
||||
"buildType": "Release"
|
||||
}
|
||||
}
|
||||
},
|
||||
"programmer":{
|
||||
"default": "OpenOCD",
|
||||
"choices":{
|
||||
"OpenOCD":{
|
||||
"short":"OpenOCD",
|
||||
"long": "Use OpenOCD",
|
||||
"settings":{
|
||||
"USE_OPENOCD":1
|
||||
}
|
||||
},
|
||||
"JLink":{
|
||||
"short":"JLink",
|
||||
"long": "Use JLink",
|
||||
"settings":{
|
||||
"USE_JLINK":1
|
||||
}
|
||||
},
|
||||
"GDB":{
|
||||
"short":"GDB",
|
||||
"long": "Use GDB",
|
||||
"settings":{
|
||||
"USE_GDB_CLIENT":1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DFU": {
|
||||
"default": "no",
|
||||
"choices": {
|
||||
"no": {
|
||||
"short": "No DFU",
|
||||
"long": "Do not build DFU",
|
||||
"settings": {
|
||||
"BUILD_DFU":"0"
|
||||
}
|
||||
},
|
||||
"yes": {
|
||||
"short": "Build DFU",
|
||||
"long": "Build DFU",
|
||||
"settings": {
|
||||
"BUILD_DFU":"1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["ms-vscode.cpptools","ms-vscode.cmake-tools","marus25.cortex-debug"]
|
||||
}
|
64
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug - Openocd docker Remote",
|
||||
"type":"cortex-debug",
|
||||
"cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"executable": "${command:cmake.launchTargetPath}",
|
||||
"request": "launch",
|
||||
"servertype": "external",
|
||||
// This may need to be arm-none-eabi-gdb depending on your system
|
||||
"gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
|
||||
// Connect to an already running OpenOCD instance
|
||||
"gdbTarget": "host.docker.internal:3333",
|
||||
"svdFile": "${workspaceRoot}/nrf52.svd",
|
||||
"runToMain": true,
|
||||
// Work around for stopping at main on restart
|
||||
"postRestartCommands": [
|
||||
"break main",
|
||||
"continue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Debug - Openocd Local",
|
||||
"type":"cortex-debug",
|
||||
"cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"executable": "${command:cmake.launchTargetPath}",
|
||||
"request": "launch",
|
||||
"servertype": "openocd",
|
||||
// This may need to be arm-none-eabi-gdb depending on your system
|
||||
"gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
|
||||
// Connect to an already running OpenOCD instance
|
||||
"gdbTarget": "localhost:3333",
|
||||
"svdFile": "${workspaceRoot}/nrf52.svd",
|
||||
"runToMain": true,
|
||||
// Work around for stopping at main on restart
|
||||
"postRestartCommands": [
|
||||
"break main",
|
||||
"continue"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cwd": "${workspaceRoot}",
|
||||
// TODO: find better way to get latest build filename
|
||||
"executable": "./build/src/pinetime-app-1.3.0.out",
|
||||
"name": "Debug OpenOCD ST-LINK pinetime-app-1.3.0.out",
|
||||
"request": "launch",
|
||||
"type": "cortex-debug",
|
||||
"showDevDebugOutput": false,
|
||||
"servertype": "openocd",
|
||||
"runToMain": true,
|
||||
// Only use armToolchainPath if your arm-none-eabi-gdb is not in your path (some GCC packages does not contain arm-none-eabi-gdb)
|
||||
"armToolchainPath": "${workspaceRoot}/../gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin",
|
||||
"svdFile": "${workspaceRoot}/nrf52.svd",
|
||||
"configFiles": [
|
||||
"interface/stlink.cfg",
|
||||
"target/nrf52.cfg"
|
||||
],
|
||||
}
|
||||
|
||||
]
|
||||
}
|
18
.vscode/settings.json
vendored
@ -1,22 +1,26 @@
|
||||
{
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||
"cmake.configureArgs": [
|
||||
"-DARM_NONE_EABI_TOOLCHAIN_PATH=${env:ARM_NONE_EABI_TOOLCHAIN_PATH}",
|
||||
"-DNRF5_SDK_PATH=${env:NRF5_SDK_PATH}",
|
||||
],
|
||||
"cmake.generator": "Unix Makefiles",
|
||||
"clang-tidy.buildPath": "build/compile_commands.json",
|
||||
"files.associations": {
|
||||
"chrono": "cpp",
|
||||
"list": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
@ -29,7 +33,6 @@
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"netfwd": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
@ -43,16 +46,13 @@
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
|
44
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "create openocd build",
|
||||
"type": "shell",
|
||||
"command": "/opt/create_build_openocd.sh",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "update submodules",
|
||||
"type": "shell",
|
||||
"command": "git submodule update --init",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "BuildInit",
|
||||
"dependsOn": [
|
||||
"update submodules",
|
||||
"create openocd build"
|
||||
],
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(pinetime VERSION 1.1.0 LANGUAGES C CXX ASM)
|
||||
project(pinetime VERSION 1.9.0 LANGUAGES C CXX ASM)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
@ -21,10 +21,6 @@ if (NOT NRF5_SDK_PATH)
|
||||
message(FATAL_ERROR "The path to the NRF52 SDK must be specified on the command line (add -DNRF5_SDK_PATH=<path>")
|
||||
endif ()
|
||||
|
||||
if(NOT USE_JLINK AND NOT USE_GDB_CLIENT AND NOT USE_OPENOCD)
|
||||
set(USE_JLINK true)
|
||||
endif()
|
||||
|
||||
if(USE_JLINK)
|
||||
if (NOT NRFJPROG)
|
||||
message(FATAL_ERROR "the path to the tool nrfjprog must be specified on the command line (add -DNRFJPROG=<path>")
|
||||
@ -55,6 +51,14 @@ if(BUILD_DFU)
|
||||
set(BUILD_DFU true)
|
||||
endif()
|
||||
|
||||
option(WATCH_COLMI_P8 "Build for the Colmi P8" OFF)
|
||||
set(TARGET_DEVICE "PineTime")
|
||||
|
||||
if(WATCH_COLMI_P8)
|
||||
set(TARGET_DEVICE "Colmi P8")
|
||||
add_definitions(-DWATCH_P8)
|
||||
endif()
|
||||
|
||||
set(PROJECT_GIT_COMMIT_HASH "")
|
||||
|
||||
execute_process(COMMAND git rev-parse --short HEAD
|
||||
@ -62,7 +66,7 @@ execute_process(COMMAND git rev-parse --short HEAD
|
||||
OUTPUT_VARIABLE PROJECT_GIT_COMMIT_HASH
|
||||
RESULT_VARIABLE PROJECT_GIT_COMMIT_HASH_SUCCESS)
|
||||
|
||||
string(STRIP ${PROJECT_GIT_COMMIT_HASH} PROJECT_GIT_COMMIT_HASH)
|
||||
string(STRIP "${PROJECT_GIT_COMMIT_HASH}" PROJECT_GIT_COMMIT_HASH)
|
||||
|
||||
message("PROJECT_GIT_COMMIT_HASH_SUCCESS? " ${PROJECT_GIT_COMMIT_HASH_SUCCESS})
|
||||
|
||||
@ -72,6 +76,7 @@ message(" * Version : " ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${P
|
||||
message(" * Toolchain : " ${ARM_NONE_EABI_TOOLCHAIN_PATH})
|
||||
message(" * GitRef(S) : " ${PROJECT_GIT_COMMIT_HASH})
|
||||
message(" * NRF52 SDK : " ${NRF5_SDK_PATH})
|
||||
message(" * Target device : " ${TARGET_DEVICE})
|
||||
set(PROGRAMMER "???")
|
||||
if(USE_JLINK)
|
||||
message(" * Programmer/debugger : JLINK")
|
||||
@ -95,7 +100,7 @@ else()
|
||||
endif()
|
||||
|
||||
set(VERSION_EDIT_WARNING "// Do not edit this file, it is automatically generated by CMAKE!")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/Version.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/Version.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docker/post_build.sh.in ${CMAKE_CURRENT_BINARY_DIR}/post_build.sh)
|
||||
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
This contribution guide is in progress, improvements are welcome.
|
||||
|
||||
### Code style
|
||||
|
||||
Any C++ code PRs should aim to follow the style of existing code in the project.
|
||||
|
||||
Using an autoformatter is heavily recommended, but make sure it's configured properly.
|
||||
|
||||
There's currently preconfigured autoformatter rules for:
|
||||
|
||||
* CLion (IntelliJ) in .idea/codeStyles/Project.xml
|
||||
|
||||
You can use those to configure your own IDE if it's not already on the list.
|
||||
|
||||
#### Linting errors and compiler warnings
|
||||
|
||||
Try to avoid any currently enabled warnings and try to reduce the amount of linter errors.
|
||||
|
||||
#### Spelling
|
||||
|
||||
Make sure you spellcheck your code before commiting it.
|
||||
|
||||
#### TODO, FIXME
|
||||
|
||||
Check before commiting that you haven't forgotten anything, preferably don't leave these in your commits.
|
||||
|
||||
#### Licence headers
|
||||
|
||||
You should add your name to the comma-space separated list of contributors if there's a license header.
|
||||
|
||||
### License
|
||||
|
||||
By contributing you agree to licence your code under the repository's general license (which is currently GPL-v3+).
|
1
CONTRIBUTING.md
Symbolic link
@ -0,0 +1 @@
|
||||
doc/contribute.md
|
133
README.md
@ -1,130 +1,62 @@
|
||||
# [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)
|
||||
|
||||
# PineTime
|
||||
[![Build PineTime Firmware](https://github.com/InfiniTimeOrg/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/InfiniTimeOrg/InfiniTime/actions)
|
||||
|
||||
[![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions)
|
||||
![InfiniTime logo](images/infinitime-logo-small.jpg "InfiniTime Logo")
|
||||
|
||||
> The PineTime is a free and open source smartwatch capable of running custom-built open operating systems. Some of the notable features include a heart rate monitor, a week-long battery as well as a capacitive touch IPS display that is legible in direct sunlight. It is a fully community driven side-project, which means that it will ultimately be up to the developers and end-users to determine when they deem the PineTime ready to ship.
|
||||
Fast open-source firmware for the [PineTime smartwatch](https://www.pine64.org/pinetime/) with many features, written in modern C++.
|
||||
|
||||
> We envision the PineTime as a companion for not only your PinePhone but also for your favorite devices — any phone, tablet, or even PC.
|
||||
## New to InfiniTime?
|
||||
|
||||
*https://www.pine64.org/pinetime/*
|
||||
- [Getting started with InfiniTime](doc/gettingStarted/gettingStarted-1.0.md)
|
||||
- [Updating the software](doc/gettingStarted/updating-software.md)
|
||||
- [About the firmware and bootloader](doc/gettingStarted/about-software.md)
|
||||
### Companion apps
|
||||
- [Gadgetbridge](https://gadgetbridge.org/) (Android)
|
||||
- [AmazFish](https://openrepos.net/content/piggz/amazfish/) (SailfishOS)
|
||||
- [Siglo](https://github.com/alexr4535/siglo) (Linux)
|
||||
- [InfiniLink](https://github.com/InfiniTimeOrg/InfiniLink) **[Experimental]** **[Unmaintained, looking for developers/maintainers]** (iOS)
|
||||
- [ITD](https://gitea.arsenm.dev/Arsen6331/itd) (Linux)
|
||||
|
||||
The **Pinetime** smartwatch is built around the NRF52832 MCU (512KB Flash, 64KB RAM), a 240*240 LCD display driven by the ST7789 controller, an accelerometer, a heart rate sensor, and a vibration motor.
|
||||
## Development
|
||||
|
||||
# InfiniTime
|
||||
![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo")
|
||||
|
||||
The goal of this project is to design an open-source firmware for the Pinetime smartwatch :
|
||||
|
||||
- Code written in **modern C++**;
|
||||
- Build system based on **CMake**;
|
||||
- Based on **[FreeRTOS 10.0.0](https://freertos.org)** real-time OS.
|
||||
- Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library...
|
||||
- ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack.
|
||||
|
||||
## Overview
|
||||
|
||||
![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens")
|
||||
|
||||
As of now, here is the list of achievements of this project:
|
||||
|
||||
- Fast and optimized LCD driver
|
||||
- BLE communication
|
||||
- Rich user interface via display, touchscreen and pushbutton
|
||||
- Time synchronization via BLE
|
||||
- Notification via BLE
|
||||
- Heart rate measurements
|
||||
- Step counting
|
||||
- Wake-up on wrist rotation
|
||||
- Quick actions
|
||||
* Disable vibration on notification
|
||||
* Brightness settings
|
||||
* Flashlight
|
||||
* Settings
|
||||
- 2 watch faces:
|
||||
* Digital
|
||||
* Analog
|
||||
- Multiple 'apps' :
|
||||
* Music (control the playback of the music on your phone)
|
||||
* Heart rate (controls the heart rate sensor and display current heartbeat)
|
||||
* Navigation (displays navigation instructions coming from the companion app)
|
||||
* Notification (displays the last notification received)
|
||||
* Paddle (single player pong-like game)
|
||||
* Two (2048 clone game)
|
||||
* Stopwatch (with all the necessary functions such as play, pause, lap, stop)
|
||||
* Motion sensor and step counter (displays the number of steps and the state of the motion sensor in real-time)
|
||||
- User settings:
|
||||
* Display timeout
|
||||
* Wake-up condition
|
||||
* Time format (12/24h)
|
||||
* Default watch face
|
||||
* Battery status
|
||||
* Firmware validation
|
||||
* System information
|
||||
- Supported by 3 companion apps (development is in progress):
|
||||
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/) (on Android)
|
||||
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux)
|
||||
* [Siglo](https://github.com/alexr4535/siglo) (on Linux)
|
||||
* **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY)
|
||||
- OTA (Over-the-air) update via BLE
|
||||
- [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
|
||||
|
||||
## Documentation
|
||||
|
||||
### Getting started
|
||||
- [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md)
|
||||
- [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md)
|
||||
|
||||
### Develop
|
||||
- [Rough structure of the code](doc/code/Intro.md)
|
||||
- [How to implement an application](doc/code/Apps.md)
|
||||
- [Generate the fonts and symbols](src/displayapp/fonts/README.md)
|
||||
- [Creating a stopwatch in Pinetime(article)](https://pankajraghav.com/2021/04/03/PINETIME-STOPCLOCK.html)
|
||||
- [Tips on designing an app UI](doc/ui_guidelines.md)
|
||||
|
||||
### InfiniSim Simulator
|
||||
Use the [InfiniSim Simulator](https://github.com/InfiniTimeOrg/InfiniSim) to experience the `InfiniTime` user interface directly on your PC, to shorten the time until you get your hands on a real [PineTime smartwatch](https://www.pine64.org/pinetime/).
|
||||
Or use it to develop new Watchfaces, new Screens, or quickly iterate on the user interface.
|
||||
|
||||
### Contributing
|
||||
- [How to contribute?](/doc/contribute.md)
|
||||
- [Coding conventions](/doc/coding-convention.md)
|
||||
|
||||
### Build, flash and debug
|
||||
|
||||
- [Project branches](doc/branches.md)
|
||||
- [Versioning](doc/versioning.md)
|
||||
- [Files included in the release notes](doc/filesInReleaseNotes.md)
|
||||
- [Build the project](doc/buildAndProgram.md)
|
||||
- [Flash the firmware using OpenOCD and STLinkV2](doc/openOCD.md)
|
||||
- [Flash the firmware using SWD interface](doc/SWD.md)
|
||||
- [Build the project with Docker](doc/buildWithDocker.md)
|
||||
- [Build the project with VSCode](doc/buildWithVScode.md)
|
||||
- [Bootloader, OTA and DFU](./bootloader/README.md)
|
||||
- [Stub using NRF52-DK](./doc/PinetimeStubWithNrf52DK.md)
|
||||
- Logging with JLink RTT.
|
||||
- Using files from the releases
|
||||
|
||||
### Contribute
|
||||
- [How to contribute ?](doc/contribute.md)
|
||||
|
||||
### API
|
||||
|
||||
- [BLE implementation and API](./doc/ble.md)
|
||||
|
||||
### Architecture and technical topics
|
||||
|
||||
- [Memory analysis](./doc/MemoryAnalysis.md)
|
||||
|
||||
### Using the firmware
|
||||
- [Integration with Gadgetbridge](doc/companionapps/Gadgetbridge.md)
|
||||
- [Integration with AmazFish](doc/companionapps/Amazfish.md)
|
||||
- [Firmware update, OTA](doc/companionapps/NrfconnectOTA.md)
|
||||
|
||||
|
||||
## TODO - contribute
|
||||
|
||||
This project is far from being finished, and there are still a lot of things to do for this project to become a firmware usable by the general public.
|
||||
|
||||
Here a quick list out of my head of things to do for this project:
|
||||
|
||||
- Improve BLE communication stability and reliability
|
||||
- Improve OTA and MCUBoot bootloader
|
||||
- Add more functionalities : Alarm, chronometer, configuration, activities, heart rate logging, games,...
|
||||
- Add more BLE functionalities : call notifications, agenda, configuration, data logging,...
|
||||
- Measure power consumption and improve battery life
|
||||
- Improve documentation, take better pictures and video than mine
|
||||
- Improve the UI
|
||||
- Create companion app for multiple OSes (Linux, Android, iOS) and platforms (desktop, ARM, mobile). Do not forget the other devices from Pine64 like [the Pinephone](https://www.pine64.org/pinephone/) and the [Pinebook Pro](https://www.pine64.org/pinebook-pro/).
|
||||
- Design a simple CI (preferably self-hosted and easy to reproduce).
|
||||
|
||||
Do not hesitate to clone/fork the code, hack it and create pull-requests. I'll do my best to review and merge them :)
|
||||
|
||||
## Licenses
|
||||
|
||||
This project is released under the GNU General Public License version 3 or, at your option, any later version.
|
||||
|
||||
It integrates the following projects:
|
||||
@ -134,6 +66,7 @@ It integrates the following projects:
|
||||
- Font : **[Jetbrains Mono](https://www.jetbrains.com/fr-fr/lp/mono/)** under the Apache 2.0 license
|
||||
|
||||
## Credits
|
||||
|
||||
I’m not working alone on this project. First, many people create PR for this projects. Then, there is the whole #pinetime community : a lot of people all around the world who are hacking, searching, experimenting and programming the Pinetime. We exchange our ideas, experiments and code in the chat rooms and forums.
|
||||
|
||||
Here are some people I would like to highlight:
|
||||
|
@ -1,5 +1,5 @@
|
||||
# About this bootloader
|
||||
The [bootloader](https://github.com/lupyuen/pinetime-rust-mynewt/tree/master/libs/pinetime_boot/src) is mostly developed by [Lup Yuen](https://github.com/lupyuen). It is based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) and [Mynewt](https://mynewt.apache.org/).
|
||||
The [bootloader](https://github.com/lupyuen/pinetime-rust-mynewt/tree/master/libs/pinetime_boot/src) is mostly developed by [Lup Yuen](https://github.com/lupyuen). It is based on [MCUBoot](https://www.mcuboot.com) and [Mynewt](https://mynewt.apache.org/).
|
||||
|
||||
The goal of this project is to provide a common bootloader for multiple (all?) Pinetime projects. It allows to upgrade the current bootloader and even replace the current application by another one that supports the same bootloader.
|
||||
|
||||
@ -9,14 +9,14 @@ Integrating a BLE stack for the OTA functionality would have used to much memory
|
||||
|
||||
When it is run, this bootloader looks in the SPI flash memory if a new firmware is available. It there is one, it *swaps* the current firmware with the new one (the new one is copied in the main flash memory, and the current one is copied in the SPI flash memory) and run the new one. If the new one fails to run properly, the bootloader is able to revert to the old one and mark the new one as not working.
|
||||
|
||||
As this bootloader does not provide any OTA capability, it is not able to actually download a new version of the application. Providing OTA functionality is thus the responsability of the application firmware.
|
||||
As this bootloader does not provide any OTA capability, it is not able to actually download a new version of the application. Providing OTA functionality is thus the responsibility of the application firmware.
|
||||
|
||||
# About MCUBoot
|
||||
MCUBoot is run at boot time. In normal operation, it just jumps to the reset handler of the application firmware to run it. Once the application firmware is running, MCUBoot does not run at all.
|
||||
|
||||
![MCUBoot boot sequence diagram](../doc/bootloader/boot.png "MCUBoot boot sequence diagram")
|
||||
|
||||
But MCUBoot does much more than that : it can upgrade the firmware that is currently running by a new one, and it is also able to revert to the previous version of the firmware in case the new one does not run propertly.
|
||||
But MCUBoot does much more than that : it can upgrade the firmware that is currently running by a new one, and it is also able to revert to the previous version of the firmware in case the new one does not run properly.
|
||||
|
||||
To do this, it uses 2 memory 'slots' :
|
||||
- **The primary slot** : it contains the current firmware, the one that will be executed by MCUBoot
|
||||
@ -40,7 +40,7 @@ This chapter describes degraded cases that are handled by our bootloader and tho
|
||||
Case | Current bootloader | Solution
|
||||
-----|--------------------|----------------------------------------------
|
||||
Data got corrupted during file transfer | [OK] Application firmware does a CRC check before applying the update, and does not proceed if it fails. | N/A
|
||||
New firmware does not run at all (bad file) (1) | [NOK] MCU executes unknown instructions and will most likely end up in an infinite loop or freeze in an error handler. The bootloader does not run, it can do nothing, the MCU is stucked until next reset | [OK] The bootloader starts the watchdog just before running the new firmware. This way, the watchdog will reset the MCU after ~7s because the firmware does not refresh it. Bootloader reverts to the previous version of the firmware during the reset.
|
||||
New firmware does not run at all (bad file) (1) | [NOK] MCU executes unknown instructions and will most likely end up in an infinite loop or freeze in an error handler. The bootloader does not run, it can do nothing, the MCU is stuck until next reset | [OK] The bootloader starts the watchdog just before running the new firmware. This way, the watchdog will reset the MCU after ~7s because the firmware does not refresh it. Bootloader reverts to the previous version of the firmware during the reset.
|
||||
New firmware runs, does not set the valid bit and does not refresh the watchdog | [NOK] The new firmware runs until the next reset. The bootloader will be able to revert to the previous firmware only during the next reset. If the new firmware does not run properly and does not reset, the bootloader can do nothing until the next reset | [OK] The bootloader starts the watchdog just before running the new firmware. This way, the watchdog will reset the MCU after ~7s because the firmware does not refresh it. Bootloader reverts to the previous version of the firmware during the reset.
|
||||
New firmware does not run properly, does not set the valid bit but refreshes the watchdog | [NOK] The bootloader will be able to revert to the previous firmware only during the next reset. If the new firmware does not run properly and does not reset, the bootloader can do nothing until the next reset | [~] Wait for the battery to drain. The CPU will reset the next time the device is charged and will be able to rollback to the previous version.
|
||||
New firmware does not run properly but sets the valid bit and refreshes the watchdog | [NOK] The bootloader won't revert to the previous version because the valid flag is set | [~] Wait for the battery to drain. The CPU will reset the next time the device is charged. Then, the bootloader must provide a way for the user to force the rollback to the previous version
|
||||
@ -86,7 +86,7 @@ make pinetime-mcuboot-app
|
||||
|
||||
The binary is located in *<build directory>/src/pinetime-mcuboot-app.bin*.
|
||||
|
||||
It must me converted into a MCUBoot image using *imgtool.py* from [MCUBoot](https://github.com/JuulLabs-OSS/mcuboot/tree/master/scripts). Simply checkout the project and run the script <mcuboot root>/scripts/imgtool.py with the following command line:
|
||||
It must me converted into a MCUBoot image using *imgtool.py* from [MCUBoot](https://github.com/mcu-tools/mcuboot/tree/master/scripts). Simply checkout the project and run the script <mcuboot root>/scripts/imgtool.py with the following command line:
|
||||
|
||||
`
|
||||
imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header <build directory>/src/pinetime-mcuboot-app.bin image.bin
|
||||
@ -115,8 +115,6 @@ sudo dfu.py -z /home/jf/nrf52/bootloader/dfu.zip -a <pinetime MAC address> --leg
|
||||
|
||||
**Note** : dfu.py is a slightly modified version of [this repo](https://github.com/daniel-thompson/ota-dfu-python).
|
||||
|
||||
See [this page](../doc/CompanionApps/NrfconnectOTA.md) for more info about OTA with NRFConect
|
||||
|
||||
### Firmware validation
|
||||
Once the OTA is done, InfiniTime will reset the watch to apply the update. When the watch reboots, the new firmware is running.
|
||||
|
||||
@ -126,12 +124,12 @@ If the new firmware is working correctly, open the application menu and tap on t
|
||||
|
||||
Firmware validation application in the menu:
|
||||
|
||||
![Firmware Validation App](../doc/CompanionApps/firmwareValidationApp.jpg "Firmware Validation App")
|
||||
![Firmware Validation App](../doc/bootloader/firmwareValidationApp.jpg "Firmware Validation App")
|
||||
|
||||
The firmware is not validated yet. Tap 'Validate' to validate it, or 'Reset' to rollback to the previous version.
|
||||
|
||||
![Firmware Not Validated](../doc/CompanionApps/firmwareNoValidated.jpg "Firmware Not Validated")
|
||||
![Firmware Not Validated](../doc/bootloader/firmwareNoValidated.jpg "Firmware Not Validated")
|
||||
|
||||
The firmware is validated!
|
||||
|
||||
![Firmware Validated](../doc/CompanionApps/firmwareValidated.jpg "Firmware Validated")
|
||||
![Firmware Validated](../doc/bootloader/firmwareValidated.jpg "Firmware Validated")
|
||||
|
1
bootloader/ota-dfu-python/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
__pycache__
|
@ -236,7 +236,7 @@ class BleDfuControllerSecure(NrfBleDfuController):
|
||||
self._dfu_send_command(Procedures.EXECUTE)
|
||||
self._wait_and_parse_notify()
|
||||
|
||||
print("Init packet successfully transfered")
|
||||
print("Init packet successfully transferred")
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Send the Firmware image to peripheral device.
|
||||
@ -319,5 +319,5 @@ class BleDfuControllerSecure(NrfBleDfuController):
|
||||
self._dfu_send_command(Procedures.EXECUTE)
|
||||
self._wait_and_parse_notify()
|
||||
|
||||
# If everything executed correctly, return amount of bytes transfered
|
||||
# If everything executed correctly, return amount of bytes transferred
|
||||
return obj_max_size
|
||||
|
@ -106,7 +106,6 @@ macro(nRF5x_setup)
|
||||
${NRF5_SDK_PATH}/external/freertos/source/stream_buffer.c
|
||||
${NRF5_SDK_PATH}/external/freertos/source/tasks.c
|
||||
${NRF5_SDK_PATH}/external/freertos/source/timers.c
|
||||
${NRF5_SDK_PATH}/components/libraries/timer/app_timer_freertos.c
|
||||
)
|
||||
|
||||
# freertos include
|
||||
@ -335,7 +334,6 @@ endmacro(nRF5x_addAppFIFO)
|
||||
# adds app-level Timer libraries
|
||||
macro(nRF5x_addAppTimer)
|
||||
list(APPEND SDK_SOURCE_FILES
|
||||
"${NRF5_SDK_PATH}/components/libraries/timer/app_timer.c"
|
||||
)
|
||||
endmacro(nRF5x_addAppTimer)
|
||||
|
||||
|
@ -7,7 +7,7 @@ Cmake script for projects targeting Nordic Semiconductor nRF5x series devices us
|
||||
The script makes use of the following tools:
|
||||
|
||||
- nRF5x SDK by Nordic Semiconductor - SoC specific drivers and libraries (also includes a lot of examples)
|
||||
- JLink by Segger - interface software for the JLink familiy of programmers
|
||||
- JLink by Segger - interface software for the JLink family of programmers
|
||||
- nrfjprog by Nordic Semiconductor - Wrapper utility around JLink
|
||||
- arm-non-eabi-gcc by ARM and the GCC Team - compiler toolchain for embedded (= bare metal) ARM chips
|
||||
|
||||
@ -15,11 +15,11 @@ The script makes use of the following tools:
|
||||
|
||||
1. Download this repo (or add as submodule) to the directory `cmake-nRF5x` in your project
|
||||
|
||||
1. Search the SDK `example` directory for a `sdk_config.h`, `main.c` and a linker script (normally named `<project_name>_gcc_<chip familly>.ld`) that fits your chip and project needs.
|
||||
1. Search the SDK `example` directory for a `sdk_config.h`, `main.c` and a linker script (normally named `<project_name>_gcc_<chip family>.ld`) that fits your chip and project needs.
|
||||
|
||||
1. Copy the `sdk_config.h` and the project `main.c` into a new directory `src`. Modify them as required for your project.
|
||||
|
||||
1. Copy the linker script into the root of your project. Rename it to just `gcc_<chip familly>.ld` For example:
|
||||
1. Copy the linker script into the root of your project. Rename it to just `gcc_<chip family>.ld` For example:
|
||||
|
||||
```
|
||||
gcc_nrf51.ld
|
||||
@ -98,7 +98,7 @@ The script makes use of the following tools:
|
||||
|
||||
After setup you can use cmake as usual:
|
||||
|
||||
1. Generate the actual build files (out-of-source builds are strongly recomended):
|
||||
1. Generate the actual build files (out-of-source builds are strongly recommended):
|
||||
|
||||
```commandline
|
||||
cmake -H. -B"cmake-build" -G "Unix Makefiles"
|
||||
|
167
doc/BLEFS.md
Normal file
@ -0,0 +1,167 @@
|
||||
# BLE FS
|
||||
---
|
||||
|
||||
The BLE FS protocol in InfiniTime is mostly Adafruit's BLE file transfer protocol, as described in [adafruit/Adafruit_CircuitPython_BLE_File_Transfer](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer). There are some deviations, such as the status codes. These will be described later in the document.
|
||||
|
||||
---
|
||||
|
||||
## UUIDs
|
||||
|
||||
There are two relevant UUIDs in this protocol: the version characteristic, and the raw transfer characteristic.
|
||||
|
||||
### Version
|
||||
|
||||
UUID: `adaf0100-4669-6c65-5472-616e73666572`
|
||||
|
||||
The version characteristic returns the version of the protocol to which the sender adheres. It returns a single unsigned 32-bit integer. The latest version at the time of writing this is 4.
|
||||
|
||||
### Transfer
|
||||
|
||||
UUID: `adaf0200-4669-6c65-5472-616e73666572`
|
||||
|
||||
The transfer characteristic is responsible for all the data transfer between the client and the watch. It supports write and notify. Writing a packet on the characteristic results in a response via notify.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
The separator for paths is `/`, and absolute paths must start with `/`.
|
||||
|
||||
All of the following commands and responses are transferred via the transfer characteristic
|
||||
|
||||
### Read file
|
||||
|
||||
To begin reading a file, a header must first be sent. The header packet should be formatted like so:
|
||||
|
||||
- Command (single byte): `0x10`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- Unsigned 32-bit integer encoding the location at which to start reading the first chunk.
|
||||
- Unsigned 32-bit integer encoding the amount of bytes to be read.
|
||||
- File path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
To continue reading the file after this initial packet, the following packet should be sent until all the data has been received. No close command is required after the data has been received.
|
||||
|
||||
- Command (single byte): `0x12`
|
||||
- Status: `0x01`
|
||||
- 2 bytes of padding
|
||||
- Unsigned 32-bit integer encoding the location at which to start reading the next chunk.
|
||||
- Unsigned 32-bit integer encoding the amount of bytes to be read. This may be different from the size in the header.
|
||||
|
||||
Both of these commands receive the following response:
|
||||
|
||||
- Command (single byte): `0x11`
|
||||
- Status (signed 8-bit integer)
|
||||
- 2 bytes of padding
|
||||
- Unsigned 32-bit integer encoding the offset of this chunk
|
||||
- Unsigned 32-bit integer encoding the total size of the file
|
||||
- Unsigned 32-bit integer encoding the amount of data in the current chunk
|
||||
- Contents of the current chunk
|
||||
|
||||
### Write file
|
||||
|
||||
To begin writing to a file, a header must first be sent. The header packet should be formatted like so:
|
||||
|
||||
- Command (single byte): `0x20`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- Unsigned 32-bit integer encoding the location at which to start writing to the file.
|
||||
- Unsigned 64-bit integer encoding the unix timestamp with nanosecond resolution. This will be used as the modification time. At the time of writing, this is not implemented in InfiniTime, but may be in the future.
|
||||
- Unsigned 32-bit integer encoding the size of the file that will be sent
|
||||
- File path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
To continue reading the file after this initial packet, the following packet should be sent until all the data has been sent and a response had been received with 0 free space. No close command is required after the data has been received.
|
||||
|
||||
- Command (single byte): `0x22`
|
||||
- Status: `0x01`
|
||||
- 2 bytes of padding.
|
||||
- Unsigned 32-bit integer encoding the location at which to write the next chunk.
|
||||
- Unsigned 32-bit integer encoding the amount of bytes to be written.
|
||||
- Data
|
||||
|
||||
Both of these commands receive the following response:
|
||||
|
||||
- Command (single byte): `0x21`
|
||||
- Status (signed 8-bit integer)
|
||||
- 2 bytes of padding
|
||||
- Unsigned 32-bit integer encoding the current offset in the file
|
||||
- Unsigned 64-bit integer encoding the unix timestamp with nanosecond resolution. This will be used as the modification time. At the time of writing, this is not implemented in InfiniTime, but may be in the future.
|
||||
- Unsigned 32-bit integer encoding the amount of data the client can send until the file is full.
|
||||
|
||||
### Delete file
|
||||
|
||||
- Command (single byte): `0x30`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- File path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
The response to this packet will be as follows:
|
||||
|
||||
- Command (single byte): `0x31`
|
||||
- Status (signed 8-bit integer)
|
||||
|
||||
### Make directory
|
||||
|
||||
- Command (single byte): `0x40`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- 4 bytes of padding
|
||||
- Unsigned 64-bit integer encoding the unix timestamp with nanosecond resolution.
|
||||
- File path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
The response to this packet will be as follows:
|
||||
|
||||
- Command (single byte): `0x41`
|
||||
- Status (signed 8-bit integer)
|
||||
- 6 bytes of padding
|
||||
- Unsigned 64-bit integer encoding the unix timestamp with nanosecond resolution.
|
||||
|
||||
### List directory
|
||||
|
||||
Paths returned by this command are relative to the path given in the request
|
||||
|
||||
- Command (single byte): `0x50`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- File path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
The response to this packet will be as follows. Responses will be sent until the final entry, which will have entry number == total entries
|
||||
|
||||
- Command (single byte): `0x51`
|
||||
- Status (signed 8-bit integer)
|
||||
- Unsigned 16-bit integer encoding the length of the file path.
|
||||
- Unsigned 32-bit integer encoding the entry number
|
||||
- Unsigned 32-bit integer encoding the total amount of entries
|
||||
- Flags: unsigned 32-bit integer
|
||||
+ Bit 0: Set when entry is a directory
|
||||
+ Bits 1-7: Reserved
|
||||
- Unsigned 64-bit integer encoding the unix timestamp of the modification time with nanosecond resolution
|
||||
- Unsigned 32-bit integer encoding the size of the file
|
||||
- Path: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
### Move file or directory
|
||||
|
||||
- Command (single byte): `0x60`
|
||||
- 1 byte of padding
|
||||
- Unsigned 16-bit integer encoding the length of the old path
|
||||
- Unsigned 16-bit integer encoding the length of the new path
|
||||
- Old path: UTF-8 encoded string that is _not_ null terminated.
|
||||
- 1 byte of padding
|
||||
- Newpath: UTF-8 encoded string that is _not_ null terminated.
|
||||
|
||||
The response to this packet will be as follows:
|
||||
|
||||
- Command (single byte): `0x61`
|
||||
- Status (signed 8-bit integer)
|
||||
|
||||
---
|
||||
|
||||
## Deviations
|
||||
|
||||
This section describes the differences between Adafruit's spec and InfiniTime's implementation.
|
||||
|
||||
### Status codes
|
||||
|
||||
The status codes returned by InfiniTime are a signed 8-bit integer, rather than an unsigned one as described in the spec.
|
||||
|
||||
InfiniTime uses LittleFS error codes rather than the ones described in the spec. Those codes can be found in [lfs.h](https://github.com/littlefs-project/littlefs/blob/master/lfs.h#L70).
|
@ -1,7 +1,274 @@
|
||||
# Memory analysis
|
||||
The PineTime is equipped with the following memories:
|
||||
- The internal RAM : **64KB**
|
||||
- The internal Flash : **512KB**
|
||||
- The external (SPI) Flash : **4MB**
|
||||
|
||||
Note that the NRF52832 cannot execute code stored in the external flash : we need to store the whole firmware in the internal flash memory, and use the external one to store graphicals assets, fonts...
|
||||
|
||||
This document describes how the RAM and Flash memories are used in InfiniTime and how to analyze and monitor their usage. It was written in the context of [this memory analysis effort](https://github.com/InfiniTimeOrg/InfiniTime/issues/313).
|
||||
|
||||
## Code sections
|
||||
A binary is composed of multiple sections. Most of the time, these sections are : .text, .rodata, .data and .bss but more sections can be defined in the linker script.
|
||||
|
||||
Here is a small description of these sections and where they end up in memory:
|
||||
|
||||
- **TEXT** = code (FLASH)
|
||||
- **RODATA** = constants (FLASH)
|
||||
- **DATA** = initialized variables (FLASH + RAM)
|
||||
- **BSS** = uninitialized variables (RAM)
|
||||
|
||||
|
||||
## Internal FLASH
|
||||
The internal flash memory stores the whole firmware: code, variable that are not default-initialized, constants...
|
||||
|
||||
The content of the flash memory can be easily analyzed thanks to the MAP file generated by the compiler. This file lists all the symbols from the program along with their size and location (section and addresses) in RAM and FLASH.
|
||||
|
||||
![Map file](./memoryAnalysis/mapfile.png)
|
||||
|
||||
As you can see on the picture above, this file contains a lot of information and is not easily readable by a human being. Fortunately, you can easily find tools that parse and display the content of the MAP file in a more understandable way.
|
||||
|
||||
In this analysis, I used [Linkermapviz](https://github.com/PromyLOPh/linkermapviz).
|
||||
|
||||
### Linkermapviz
|
||||
|
||||
[Linkermapviz](https://github.com/PromyLOPh/linkermapviz) parses the MAP file and displays its content on an HTML page as a graphic:
|
||||
|
||||
![linkermapviz](./memoryAnalysis/linkermapviz.png)
|
||||
|
||||
Using this tool, you can compare the relative size of symbols. This can be helpful for checking memory usage at a glance.
|
||||
|
||||
Also, as Linkermapviz is written in Python, you can easily modify and adapt it to your firmware or export data in another format. For example, [here it is modified to parse the contents of the MAP file and export it in a CSV file](https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-842338620). This file could later be opened in LibreOffice Calc where sort/filter functionality could be used to search for specific symbols in specific files...
|
||||
|
||||
### Puncover
|
||||
[Puncover](https://github.com/HBehrens/puncover) is another useful tools that analyses the binary file generated by the compiler (the .out file that contains all debug information). It provides valuable information about the symbols (data and code): name, position, size, max stack of each functions, callers, callees...
|
||||
![Puncover](./memoryAnalysis/puncover.png)
|
||||
|
||||
Puncover is really easy to install:
|
||||
|
||||
- Clone the repo and cd into the cloned directory
|
||||
- Setup a venv
|
||||
- `python -m virtualenv venv`
|
||||
- `source venv/bin/activate`
|
||||
- Install : `pip install .`
|
||||
- Run : `puncover --gcc_tools_base=/path/to/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/arm-none-eabi- --elf_file /path/to/build/directory/src/pinetime-app-1.1.0.out --src_root /path/to/sources --build_dir /path/to/build/directory`
|
||||
- Replace
|
||||
* `/path/to/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin` with the path to your gcc-arm-none-eabi toolchain
|
||||
* `/path/to/build/directory/src/pinetime-app-1.1.0.out` with the path to the binary generated by GCC (.out file)
|
||||
* `/path/to/sources` with the path to the root folder of the sources (checkout directory)
|
||||
* `/path/to/build/directory` with the path to the build directory
|
||||
- Launch a browser at http://localhost:5000/
|
||||
|
||||
### Analysis
|
||||
Using the MAP file and tools, we can easily see what symbols are using most of the flash memory. In this case, unsurprisingly, fonts and graphics are the largest use of flash memory.
|
||||
|
||||
![Puncover](./memoryAnalysis/puncover-all-symbols.png)
|
||||
|
||||
This way, you can easily check what needs to be optimized. We should find a way to store big static data (like fonts and graphics) in the external flash memory, for example.
|
||||
|
||||
It's always a good idea to check the flash memory space when working on the project. This way, you can easily check that your developments are using a reasonable amount of space.
|
||||
|
||||
### Links
|
||||
- Analysis with linkermapviz : https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-842338620
|
||||
- Analysis with Puncover : https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-847311392
|
||||
|
||||
## RAM
|
||||
RAM memory contains all the data that can be modified at run-time: variables, stack, heap...
|
||||
|
||||
### Data
|
||||
RAM memory can be *statically* allocated, meaning that the size and position of the data are known at compile-time:
|
||||
|
||||
You can easily analyze the memory used by variables declared in the global scope using the MAP. You'll find them in the .BSS or .DATA sections. Linkermapviz and Puncover can be used to analyze their memory usage.
|
||||
|
||||
Variables declared in the scope of a function will be allocated on the stack. It means that the stack usage will vary according to the state of the program, and cannot be easily analyzed at compile time.
|
||||
```
|
||||
uint8_t buffer[1024]
|
||||
|
||||
int main() {
|
||||
int a;
|
||||
}
|
||||
```
|
||||
|
||||
#### Analysis
|
||||
In Infinitime 1.1, the biggest buffers are the buffers allocated for LVGL (14KB) and the one for FreeRTOS (16KB). Nimble also allocated 9KB of RAM.
|
||||
|
||||
### Stack
|
||||
The stack will be used for everything except tasks, which have their own stack allocated by FreeRTOS. The stack is 8192B and is allocated in the [linker script](https://github.com/InfiniTimeOrg/InfiniTime/blob/develop/nrf_common.ld#L148).
|
||||
An easy way to monitor its usage is by filling the section with a known pattern at boot time, then use the firmware and dump the memory. You can then check the maximum stack usage by checking the address from the beginning of the stack that were overwritten.
|
||||
|
||||
#### Fill the stack section by a known pattern:
|
||||
Edit <NRFSDK>/modules/nrfx/mdk/gcc_startup_nrf52.S and add the following code after the copy of the data from read only memory to RAM at around line 243:
|
||||
|
||||
```
|
||||
/* Loop to copy data from read only memory to RAM.
|
||||
* The ranges of copy from/to are specified by following symbols:
|
||||
* __etext: LMA of start of the section to copy from. Usually end of text
|
||||
* __data_start__: VMA of start of the section to copy to.
|
||||
* __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__
|
||||
* the user can add their own initialized data section before BSS section with the INTERT AFTER command.
|
||||
*
|
||||
* All addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__bss_start__
|
||||
|
||||
subs r3, r3, r2
|
||||
ble .L_loop1_done
|
||||
|
||||
.L_loop1:
|
||||
subs r3, r3, #4
|
||||
ldr r0, [r1,r3]
|
||||
str r0, [r2,r3]
|
||||
bgt .L_loop1
|
||||
|
||||
.L_loop1_done:
|
||||
|
||||
|
||||
/* Add this code to fill the stack section with 0xFFEEDDBB */
|
||||
ldr r0, =__StackLimit
|
||||
ldr r1, =8192
|
||||
ldr r2, =0xFFEEDDBB
|
||||
.L_fill:
|
||||
str r2, [r0]
|
||||
adds r0, 4
|
||||
subs r1, 4
|
||||
bne .L_fill
|
||||
/* -- */
|
||||
```
|
||||
|
||||
#### Dump RAM memory and check usage
|
||||
Dumping the content of the ram is easy using JLink debugger and `nrfjprog`:
|
||||
|
||||
```
|
||||
nrfjprog --readram ram.bin
|
||||
```
|
||||
|
||||
You can then display the file using objdump:
|
||||
|
||||
```
|
||||
hexdump ram.bin -v | less
|
||||
```
|
||||
|
||||
The stack is positioned at the end of the RAM -> 0xFFFF. Its size is 8192 bytes, so the end of the stack is at 0xE000.
|
||||
On the following dump, the maximum stack usage is 520 bytes (0xFFFF - 0xFDF8):
|
||||
|
||||
```
|
||||
000fdb0 ddbb ffee ddbb ffee ddbb ffee ddbb ffee
|
||||
000fdc0 ddbb ffee ddbb ffee ddbb ffee ddbb ffee
|
||||
000fdd0 ddbb ffee ddbb ffee ddbb ffee ddbb ffee
|
||||
000fde0 ddbb ffee ddbb ffee ddbb ffee ddbb ffee
|
||||
000fdf0 ddbb ffee ddbb ffee ffff ffff c24b 0003
|
||||
000fe00 ffff ffff ffff ffff ffff ffff 0000 0000
|
||||
000fe10 0018 0000 0000 0000 0000 0000 fe58 2000
|
||||
000fe20 0000 0000 0000 00ff ddbb 00ff 0018 0000
|
||||
000fe30 929c 2000 0000 0000 0018 0000 0000 0000
|
||||
000fe40 92c4 2000 0458 2000 0000 0000 80e7 0003
|
||||
000fe50 0000 0000 8cd9 0003 ddbb ffee ddbb ffee
|
||||
000fe60 00dc 2000 92c4 2000 0005 0000 929c 2000
|
||||
000fe70 007f 0000 feb0 2000 92c4 2000 feb8 2000
|
||||
000fe80 ddbb ffee 0005 0000 929c 2000 0000 0000
|
||||
000fe90 aca0 2000 0000 0000 0028 0000 418b 0005
|
||||
000fea0 02f4 2000 001f 0000 0000 0000 0013 0000
|
||||
000feb0 b5a8 2000 2199 0005 b5a8 2000 2201 0005
|
||||
000fec0 b5a8 2000 001e 0000 0000 0000 0013 0000
|
||||
000fed0 b5b0 2000 0fe0 0006 b5a8 2000 0000 0000
|
||||
000fee0 0013 0000 2319 0005 0013 0000 0000 0000
|
||||
000fef0 0000 0000 3b1c 2000 3b1c 2000 d0e3 0000
|
||||
000ff00 4b70 2000 54ac 2000 4b70 2000 ffff ffff
|
||||
000ff10 0000 0000 1379 0003 6578 2000 0d75 0003
|
||||
000ff20 6578 2000 ffff ffff 0000 0000 1379 0003
|
||||
000ff30 000c 0000 cfeb 0002 39a1 2000 a824 2000
|
||||
000ff40 0015 0000 cfeb 0002 39a1 2000 a824 2000
|
||||
000ff50 39a1 2000 0015 0000 001b 0000 b4b9 0002
|
||||
000ff60 0000 0000 a9f4 2000 4b70 2000 0d75 0003
|
||||
000ff70 4b70 2000 ffff ffff 0000 0000 1379 0003
|
||||
000ff80 ed00 e000 a820 2000 1000 4001 7fc0 2000
|
||||
000ff90 7f64 2000 75a7 0001 a884 2000 7b04 2000
|
||||
000ffa0 a8c0 2000 0000 0000 0000 0000 0000 0000
|
||||
000ffb0 7fc0 2000 7f64 2000 8024 2000 a5a5 a5a5
|
||||
000ffc0 ed00 e000 3fd5 0001 0000 0000 72c0 2000
|
||||
000ffd0 0000 0000 72e4 2000 3f65 0001 7f64 2000
|
||||
000ffe0 0000 2001 0000 0000 ef30 e000 0010 0000
|
||||
000fff0 7fc0 2000 4217 0001 3f0a 0001 0000 6100
|
||||
```
|
||||
|
||||
#### Analysis
|
||||
According to my experimentations, we don't use the stack that much, and 8192 bytes is probably way too big for InfiniTime!
|
||||
|
||||
#### Links
|
||||
- https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-851035070
|
||||
|
||||
### Heap
|
||||
The heap is declared in the [linker script](https://github.com/InfiniTimeOrg/InfiniTime/blob/develop/nrf_common.ld#L136) and its current size is 8192 bytes. The heap is used for dynamic memory allocation(`malloc()`, `new`...).
|
||||
|
||||
Heap monitoring is not easy, but it seems that we can use the following code to know the current usage of the heap:
|
||||
|
||||
```
|
||||
auto m = mallinfo();
|
||||
NRF_LOG_INFO("heap : %d", m.uordblks);
|
||||
```
|
||||
|
||||
#### Analysis
|
||||
According to my experimentation, InfiniTime uses ~6000bytes of heap most of the time. Except when the Navigation app is launched, where the heap usage exceeds 9500 bytes (meaning that the heap overflows and could potentially corrupt the stack). This is a bug that should be fixed in #362.
|
||||
|
||||
To know exactly what's consuming heap memory, you can `wrap` functions like `malloc()` into your own functions. In this wrapper, you can add logging code or put breakpoints:
|
||||
|
||||
- Add ` -Wl,-wrap,malloc` to the cmake variable `LINK_FLAGS` of the target you want to debug (pinetime-app, most probably)
|
||||
- Add the following code in `main.cpp`
|
||||
|
||||
```
|
||||
extern "C" {
|
||||
void *__real_malloc (size_t);
|
||||
void* __wrap_malloc(size_t size) {
|
||||
return __real_malloc(size);
|
||||
}
|
||||
}
|
||||
```
|
||||
Now, your function `__wrap_malloc()` will be called instead of `malloc()`. You can call the actual malloc from the stdlib by calling `__real_malloc()`.
|
||||
|
||||
Using this technique, I was able to trace all malloc calls at boot (boot -> digital watchface):
|
||||
|
||||
- system task = 3464 bytes (SystemTask could potentially be declared as a global variable to avoid heap allocation here)
|
||||
- string music = 31 (maybe we should not use std::string when not needed, as it does heap allocation)
|
||||
- ble_att_svr_start = 1720
|
||||
- ble gatts start = 40 + 88
|
||||
- ble ll task = 24
|
||||
- display app = 104
|
||||
- digital clock = 96 + 152
|
||||
- hr task = 304
|
||||
|
||||
#### Links
|
||||
- https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-851035625
|
||||
- https://www.embedded.com/mastering-stack-and-heap-for-system-reliability-part-1-calculating-stack-size/
|
||||
- https://www.embedded.com/mastering-stack-and-heap-for-system-reliability-part-2-properly-allocating-stacks/
|
||||
- https://www.embedded.com/mastering-stack-and-heap-for-system-reliability-part-3-avoiding-heap-errors/
|
||||
|
||||
## LVGL
|
||||
I did a deep analysis of the usage of the buffer dedicated to lvgl (managed by lv_mem).
|
||||
This buffer is used by lvgl to allocated memory for drivers (display/touch), screens, themes, and all widgets created by the apps.
|
||||
|
||||
The usage of this buffer can be monitored using this code :
|
||||
|
||||
```
|
||||
lv_mem_monitor_t mon;
|
||||
lv_mem_monitor(&mon);
|
||||
NRF_LOG_INFO("\t Free %d / %d -- max %d", mon.free_size, mon.total_size, mon.max_used);
|
||||
```
|
||||
|
||||
The most interesting metric is `mon.max_used` which specifies the maximum number of bytes used from this buffer since the initialization of lvgl.
|
||||
According to my measurements, initializing the theme, display/touch driver and screens cost **4752** bytes!
|
||||
Then, initializing the digital clock face costs **1541 bytes**.
|
||||
For example a simple lv_label needs **~140 bytes** of memory.
|
||||
|
||||
I tried to monitor this max value while going through all the apps of InfiniTime 1.1 : the max value I've seen is **5660 bytes**. It means that we could probably **reduce the size of the buffer from 14KB to 6 - 10 KB** (we have to take the fragmentation of the memory into account).
|
||||
### Links
|
||||
- https://github.com/InfiniTimeOrg/InfiniTime/issues/313#issuecomment-850890064
|
||||
|
||||
|
||||
## FreeRTOS heap and task stack
|
||||
FreeRTOS statically allocate its own heap buffer in a global variable named `ucHeap`. This is an array of *uint8_t*. Its size is specified by the definition `configTOTAL_HEAP_SIZE` in *FreeRTOSConfig.h*
|
||||
FreeRTOS uses this buffer to allocate memory for tasks stack and all the RTOS object created during runtime (timers, mutexes,...).
|
||||
FreeRTOS uses this buffer to allocate memory for tasks stack and all the RTOS object created during runtime (timers, mutexes...).
|
||||
|
||||
The function `xPortGetFreeHeapSize()` returns the amount of memory available in this *ucHeap* buffer. If this value reaches 0, FreeRTOS runs out of memory.
|
||||
|
||||
@ -20,59 +287,3 @@ for (int i = 0; i < nb; i++) {
|
||||
```
|
||||
|
||||
|
||||
## Global heap
|
||||
Heap is used for **dynamic memory allocation (malloc() / new)**. NRF SDK defaults the heap size to 8KB. The size of the heap can be specified by defining `__HEAP_SIZE=8192` in *src/CMakeLists.txt*:
|
||||
|
||||
```
|
||||
add_definitions(-D__HEAP_SIZE=8192)
|
||||
```
|
||||
|
||||
You can trace the dynamic memory allocation by using the flag `--wrap` of the linker. When this flag is enabled, the linker will replace the calls to a specific function by a call to __wrap_the_function(). For example, if you specify `-Wl,-wrap,malloc` in the linker flags, the linker will replace all calls to `void* malloc(size_t)` by calls to `void* __wrap_malloc(size_t)`. This is a function you'll have to define in your code. In this function, you can call `__real_malloc()` to call the actual `malloc()' function.
|
||||
|
||||
This technic allows you to wrap all calls to malloc() with you own code.
|
||||
|
||||
In *src/CMakeLists.txt*:
|
||||
|
||||
```
|
||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
|
||||
...
|
||||
LINK_FLAGS "-Wl,-wrap,malloc ..."
|
||||
...
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
In *main.cpp*:
|
||||
|
||||
```
|
||||
uint32_t totalMalloc = 0;
|
||||
extern "C" {
|
||||
extern void* __real_malloc(size_t s);
|
||||
void *__wrap_malloc(size_t s) {
|
||||
totalMalloc += s;
|
||||
return __real_malloc(s);
|
||||
}
|
||||
}
|
||||
```
|
||||
This function sums all the memory that is allocated during the runtime. You can monitor or log this value. You can also place breakpoints in this function to determine where the dynamic memory allocation occurs in your code.
|
||||
|
||||
|
||||
# Global stack
|
||||
The stack is used to allocate memory used by functions : **parameters and local variables**. NRF SDK defaults the heap size to 8KB. The size of the heap can be specified by defining `__STACK_SIZE=8192` in *src/CMakeLists.txt*:
|
||||
|
||||
```
|
||||
add_definitions(-D__STACK_SIZE=8192)
|
||||
```
|
||||
|
||||
*NOTE*: FreeRTOS uses its own stack buffer. Thus, the global stack is only used for main() and IRQ handlers. It should be possible to reduce its size to a much lower value.
|
||||
|
||||
**NOTE**: [?] How to track the global stack usage?
|
||||
|
||||
#LittleVGL buffer
|
||||
*TODO*
|
||||
|
||||
#NimBLE buffers
|
||||
*TODO*
|
||||
|
||||
#Tools
|
||||
- https://github.com/eliotstock/memory : display the memory usage (FLASH/RAM) using the .map file from GCC.
|
||||
|
17
doc/MotionService.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Motion Service
|
||||
## Introduction
|
||||
The motion service exposes step count and raw X/Y/Z motion value as READ and NOTIFY characteristics.
|
||||
|
||||
## Service
|
||||
The service UUID is **00030000-78fc-48fe-8e23-433b3a1942d0**
|
||||
|
||||
## Characteristics
|
||||
### Step count (UUID 00030001-78fc-48fe-8e23-433b3a1942d0)
|
||||
The current number of steps represented as a single `uint32_t` (4 bytes) value.
|
||||
|
||||
### Raw motion values (UUID 00030002-78fc-48fe-8e23-433b3a1942d0)
|
||||
The current raw motion values. This is a 3 `int16_t` array:
|
||||
|
||||
- [0] : X
|
||||
- [1] : Y
|
||||
- [2] : Z
|
@ -1,6 +1,6 @@
|
||||
# Navigation Service
|
||||
## Introduction
|
||||
The navigation ble service provides 4 characteristics to allow the the watch to display navigation instructions from a companion application. The intended purpose is when performing some outdoor activities, for example running or cycling.
|
||||
The navigation ble service provides 4 characteristics to allow the watch to display navigation instructions from a companion application. This service is intended to be used when performing some outdoor activities, for example running or cycling.
|
||||
|
||||
The 4 characteristics are:
|
||||
flag (string) - Upcoming icon name
|
||||
@ -9,19 +9,19 @@ manDist (string) - Manouvre Distance, the distance to the upcoming change
|
||||
progress (uint8) - Percent complete of total route, value 0-100
|
||||
|
||||
## Service
|
||||
The service UUID is c7e60001-78fc-48fe-8e23-433b3a1942d0
|
||||
The service UUID is 00010000-78fc-48fe-8e23-433b3a1942d0
|
||||
|
||||
## Characteristics
|
||||
## Flags (UUID c7e60002-78fc-48fe-8e23-433b3a1942d0)
|
||||
All included icons are from pure-maps, which provides the actual routing from the client. The icon names ultimately come from the mapbox project "direction-icons", See https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation See the end of this document for the full lsit of supported icon names.
|
||||
## Flags (UUID 00010001-78fc-48fe-8e23-433b3a1942d0)
|
||||
All included icons are from pure-maps, which provides the actual routing from the client. The icon names ultimately come from the mapbox project "direction-icons", See https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation See the end of this document for the full list of supported icon names.
|
||||
|
||||
## Narrative (UUID c7e60003-78fc-48fe-8e23-433b3a1942d0)
|
||||
## Narrative (UUID 00010002-78fc-48fe-8e23-433b3a1942d0)
|
||||
This is a client supplied string describing the upcoming instruction such as "At the roundabout take the first exit".
|
||||
|
||||
## Man Dist (UUID c7e60004-78fc-48fe-8e23-433b3a1942d0)
|
||||
## Man Dist (UUID 00010003-78fc-48fe-8e23-433b3a1942d0)
|
||||
This is a short string describing the distance to the upcoming instruction such as "50 m".
|
||||
|
||||
## Progress (UUID c7e60001=5-78fc-48fe-8e23-433b3a1942d0)
|
||||
## Progress (UUID 00010004-78fc-48fe-8e23-433b3a1942d0)
|
||||
The percent complete in a uint8. The watch displays this as an overall progress in a progress bar.
|
||||
|
||||
## Full icon list
|
||||
|
@ -1,11 +1,11 @@
|
||||
# Build a stub for PineTime using NRF52-DK
|
||||
[NRF52-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52-DK) is the official developpment kit for NRF52832 SoC from Nordic Semiconductor.
|
||||
[NRF52-DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52-DK) is the official development kit for the NRF52832 SoC from Nordic Semiconductor used in the PineTime.
|
||||
|
||||
It can be very useful for PineTime developpment:
|
||||
* You can use it embedded JLink SWD programmer/debugger to program and debug you code on the PineTime
|
||||
* As it's based on the same SoC than the PineTime, you can program it to actually run the same code than the PineTime.
|
||||
This development kit can be very useful for PineTime development:
|
||||
* You can use its embedded JLink SWD programmer/debugger to program and debug your code on the PineTime
|
||||
* As it's based on the same SoC than the PineTime, you can program it to actually run the same code as the PineTime.
|
||||
|
||||
This page is about the 2nd point : we will build a stub that will allow us to run the same code than the one you could run on the PineTime. This will allow you to work more easily if you don't have a PineTime dev kit around, if you don't want to modify your dev kit for SWD programming, or if you want to use some feature from the DK (like power measurement).
|
||||
This page is about the 2nd point. We will build a stub that will allow us to run the same code you can run on the PineTime. This will allow you to work more easily if you don't have a PineTime dev kit around, if you don't want to modify your dev kit for SWD programming, or if you want to use some feature from the NRF52-DK (like power measurement).
|
||||
|
||||
This stub only implements the display, the button and the BLE radio. The other features from the pintime are missing:
|
||||
* heart rate sensor
|
||||
@ -41,10 +41,10 @@ You just need to make the following connections:
|
||||
| P0.13 | Button IN (D3 in my case) |
|
||||
| GND | GND |
|
||||
|
||||
You also need to enable the I/O expander to disconnect pins from buttons and led on the NRF52-DK and leave them available on the pin headers:
|
||||
You also need to enable the I/O expander to disconnect pins from the buttons and LED on the NRF52-DK and leave them available on the pin headers:
|
||||
|
||||
| NRF52 -DK | NRF52- DK |
|
||||
| --------- | --------- |
|
||||
| DETECT | GND |
|
||||
|
||||
Now, you should be able to program the SoC on the NRF52-DK board, and use it as if it was running on the pintime.
|
||||
Now, you should be able to program the SoC on the NRF52-DK board, and use it as if it was running on the PineTime.
|
@ -1,6 +1,6 @@
|
||||
# The SPI LCD driver
|
||||
## Introduction
|
||||
The LCD controller that drive the display of the Pinetime is the Sitronix ST7789V. This controller is easy to integrate with an MCU thanks to its SPI interface, and has some interesting features like:
|
||||
The LCD controller that drives the display of the Pinetime is the [Sitronix ST7789V](https://wiki.pine64.org/images/5/54/ST7789V_v1.6.pdf). This controller is easy to integrate with an MCU thanks to its SPI interface, and has some interesting features like:
|
||||
- an on-chip display data RAM that can store the whole framebuffer
|
||||
- partial screen update
|
||||
- hardware assisted vertical scrolling
|
||||
|
14
doc/SWD.md
Normal file
@ -0,0 +1,14 @@
|
||||
# How to flash InfiniTime using the SWD interface
|
||||
Download the files **bootloader.bin**, **image-x.y.z.bin** and **pinetime-graphics-x.y.z.bin** from the release page:
|
||||
|
||||
![Image file](gettingStarted/imageFile.png)
|
||||
|
||||
The bootloader reads a boot logo from the external SPI flash memory. The first step consists of flashing a tool in the MCU that will flash the boot logo into this SPI flash memory. This first step is optional but recommended (the bootloader will display garbage on screen for a few second if you don't do it).
|
||||
Using your SWD tool, flash **pinetime-graphics-x.y.z.bin** at offset **0x0000**. Reset the MCU and wait for a few seconds until the logo is completely drawn on the display.
|
||||
|
||||
Then, using your SWD tool, flash these file at the following offsets:
|
||||
|
||||
- bootloader.bin : **0x0000**
|
||||
- image-x.y.z.bin : **0x8000**
|
||||
|
||||
Reset and voilà, you're running InfiniTime on your PineTime!
|
269
doc/ble.md
@ -2,23 +2,67 @@
|
||||
## Introduction
|
||||
This page describes the BLE implementation and API built in this firmware.
|
||||
|
||||
**Note** : I'm a beginner in BLE related technologies and the information of this document reflect my current knowledge and understanding of the BLE stack. These informations might be erroneous or incomplete. Feel free to submit a PR if you think you can improve these.
|
||||
**Note**: I'm a beginner in BLE related technologies and the information in this document reflects my current knowledge and understanding of the BLE stack. This information might be erroneous or incomplete. Feel free to submit a PR if you think you can improve it.
|
||||
|
||||
---
|
||||
|
||||
### Table of Contents
|
||||
|
||||
- [BLE Connection](#ble-connection)
|
||||
- [BLE FS](#ble-fs)
|
||||
- [BLE UUIDs](#ble-uuids)
|
||||
- [BLE Services](#ble-services)
|
||||
- [CTS](#cts)
|
||||
- [ANS](#ans)
|
||||
- [Getting Information](#getting-information)
|
||||
- [Firmware Version](#firmware-version)
|
||||
- [Battery Level](#battery-level)
|
||||
- [Heart Rate](#heart-rate)
|
||||
- [Notifications](#notifications)
|
||||
- [New Alert](#new-alert)
|
||||
- [Notification Event](#notification-event)
|
||||
- [Firmware Upgrades](#firmware-upgrades)
|
||||
- [Step one](#step-one)
|
||||
- [Step two](#step-two)
|
||||
- [Step three](#step-three)
|
||||
- [Step four](#step-four)
|
||||
- [Step five](#step-five)
|
||||
- [Step six](#step-six)
|
||||
- [Step seven](#step-seven)
|
||||
- [Step eight](#step-eight)
|
||||
- [Step nine](#step-nine)
|
||||
- [Music Control](#music-control)
|
||||
- [Events](#events)
|
||||
- [Status](#status)
|
||||
- [Artist, Track, and Album](#artist-track-and-album)
|
||||
- [Time](#time)
|
||||
|
||||
---
|
||||
|
||||
## BLE Connection
|
||||
When starting the firmware start a BLE advertising : it send small messages that can be received by any *central* device in range. This allows the device to announce its presence to other devices.
|
||||
When starting, the firmware starts BLE advertising. It sends small messages that can be received by any *central* device in range. This allows the device to announce its presence to other devices.
|
||||
|
||||
A companion application (running on a PC, RasberryPi, smartphone) which received this avertising packet can request a connection to the device. This connection procedure allows the 2 devices to negociate communication parameters, security keys,...
|
||||
A companion application (running on a PC, Raspberry Pi, smartphone, etc.) which receives this advertising packet can request a connection to the device. This connection procedure allows the 2 devices to negotiate communication parameters, security keys, etc.
|
||||
|
||||
When the connection is established, the pinetime will try to discover services running on the companion application. For now **CTS** (**C**urrent **T**ime **S**ervice) and **ANS** (**A**lert **N**otification **S**ervice) are supported.
|
||||
When the connection is established, the PineTime will try to discover services running on the companion application. For now **CTS** (**C**urrent **T**ime **S**ervice) and **ANS** (**A**lert **N**otification **S**ervice) are supported.
|
||||
|
||||
If **CTS** is detected, it'll request the current time to the companion application. If **ANS** is detected, it will listen to new notifications coming from the companion application.
|
||||
|
||||
![BLE connection sequence diagram](ble/connection_sequence.png "BLE connection sequence diagram")
|
||||
|
||||
---
|
||||
|
||||
## BLE FS
|
||||
|
||||
The documentation for BLE FS can be found here:
|
||||
[BLEFS.md](./BLEFS.md)
|
||||
|
||||
---
|
||||
|
||||
## BLE UUIDs
|
||||
When possible, InfiniTime tries to implement BLE services defined by the BLE specification.
|
||||
|
||||
When the service does not exist in the BLE specification, InfiniTime implement custom services. As all BLE services, custom services are identified by a UUID. Here is how to define the UUID of custom services in InfiniTime:
|
||||
When the service does not exist in the BLE specification, InfiniTime implements custom services. Custom services are identified by a UUID, as are all BLE services. Here is how to define the UUID of custom services in InfiniTime:
|
||||
|
||||
```
|
||||
- Base UUID : xxxxxxxx-78fc-48fe-8e23-433b3a1942d0
|
||||
@ -29,14 +73,25 @@ When the service does not exist in the BLE specification, InfiniTime implement c
|
||||
The following custom services are implemented in InfiniTime:
|
||||
|
||||
- Since InfiniTime 0.8:
|
||||
```
|
||||
* Music Service : 00000000-78fc-48fe-8e23-433b3a1942d0
|
||||
```
|
||||
|
||||
|
||||
- Since InfiniTime 0.11:
|
||||
```
|
||||
* Navigation Service : 00010000-78fc-48fe-8e23-433b3a1942d0
|
||||
```
|
||||
* [Navigation Service](NavigationService.md) : 00010000-78fc-48fe-8e23-433b3a1942d0
|
||||
|
||||
|
||||
- Since InfiniTime 0.13
|
||||
* Call characteristic (extension to the Alert Notification Service): 00020001-78fc-48fe-8e23-433b3a1942d0
|
||||
|
||||
|
||||
- Since InfiniTime 1.7:
|
||||
* [Motion Service](MotionService.md): 00030000-78fc-48fe-8e23-433b3a1942d0
|
||||
|
||||
|
||||
- Since InfiniTime 1.8:
|
||||
* [Weather Service](/src/components/ble/weather/WeatherService.h): 00040000-78fc-48fe-8e23-433b3a1942d0
|
||||
|
||||
---
|
||||
|
||||
## BLE services
|
||||
[List of standard BLE services](https://www.bluetooth.com/specifications/gatt/services/)
|
||||
@ -49,3 +104,197 @@ The following custom services are implemented in InfiniTime:
|
||||
|
||||
![ANS sequence diagram](./ble/ans_sequence.png "ANS sequence diagram")
|
||||
|
||||
---
|
||||
|
||||
### Getting Information
|
||||
|
||||
The InfiniTime firmware exposes some information about itself through BLE. The BLE characteristic UUIDs for this information are as follows:
|
||||
|
||||
- Firmware Version: `00002a26-0000-1000-8000-00805f9b34fb`
|
||||
- Battery Level: `00002a19-0000-1000-8000-00805f9b34fb`
|
||||
- Heart Rate: `00002a37-0000-1000-8000-00805f9b34fb`
|
||||
|
||||
#### Firmware Version
|
||||
|
||||
Reading a value from the firmware version characteristic will yield a UTF-8 encoded string containing the version of InfiniTime being run on the device. Example: `1.6.0`.
|
||||
|
||||
#### Battery Level
|
||||
|
||||
Reading from the battery level characteristic yields a single byte of data. This byte can be converted to an unsigned 8-bit integer which will be the battery percentage. This characteristic allows notifications for updates as the value changes.
|
||||
|
||||
#### Heart Rate
|
||||
|
||||
Reading from the heart rate characteristic yields two bytes of data. I am not sure of the function of the first byte. It appears to always be zero. The second byte can be converted to an unsigned 8-bit integer which is the current heart rate. This characteristic also allows notifications for updates as the value changes.
|
||||
|
||||
---
|
||||
|
||||
### Notifications
|
||||
|
||||
InfiniTime uses the Alert Notification Service (ANS) for notifications. The relevant UUIDs are as follows:
|
||||
|
||||
- New Alert: `00002a46-0000-1000-8000-00805f9b34fb`
|
||||
- Notification Event: `00020001-78fc-48fe-8e23-433b3a1942d0`
|
||||
|
||||
#### New Alert
|
||||
|
||||
The new alert characteristic allows sending new notifications to InfiniTime. It requires the following format:
|
||||
|
||||
```
|
||||
<category><amount>\x00<\x00-separated data>
|
||||
```
|
||||
|
||||
For example, here is what a normal notification looks like in Golang (language of `itd`):
|
||||
|
||||
```go
|
||||
// \x00 is the category for simple alert, and there is one new notification, hence \x01.
|
||||
"\x00\x01\x00Test Title\x00Test Body"
|
||||
```
|
||||
|
||||
A call notification looks like so:
|
||||
|
||||
```go
|
||||
// \x03 is the category for calls, and there is one new call notification, hence \x01.
|
||||
"\x03\x01\x00Mary"
|
||||
```
|
||||
|
||||
The `\x00` stands for hexadecimal `00` which means null.
|
||||
|
||||
Here is the list of categories and commands:
|
||||
|
||||
- Simple Alert: `0`
|
||||
- Email: `1`
|
||||
- News: `2`
|
||||
- Call Notification: `3`
|
||||
- Missed Call: `4`
|
||||
- SMS/MMS: `5`
|
||||
- Voicemail: `6`
|
||||
- Schedule: `7`
|
||||
- High Prioritized Alert: `8`
|
||||
- Instant Message: `9`
|
||||
- All Alerts: `0xFF`
|
||||
|
||||
These lists and information were retrieved from the following pages in the Nordic docs:
|
||||
|
||||
- [Alert Notification Service Client](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v12.2.0%2Fgroup__ble__ans__c.html)
|
||||
- [Alert Notification Application](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v13.0.0%2Fble_sdk_app_alert_notification.html)
|
||||
|
||||
#### Notification Event
|
||||
|
||||
A call notification in InfiniTime contains three buttons. Decline, Accept, and Mute. The notification event characteristic contains the button tapped by the user on a call notification. This characteristic only allows notify, **not** read.
|
||||
|
||||
Enabling notifications from this characteristic, you get a single byte whenever the user taps a button on the call notification. This byte is an unsigned 8-bit integer that signifies one of the buttons. The numbers are as follows:
|
||||
|
||||
- 0: Declined
|
||||
- 1: Accepted
|
||||
- 2: Muted
|
||||
|
||||
---
|
||||
|
||||
### Firmware Upgrades
|
||||
|
||||
Firmware upgrades in InfiniTime are probably the most complex of the BLE operations. It is a nine step process requiring multiple commands be sent to multiple characteristics. The relevant UUIDs are as follows:
|
||||
|
||||
- Control Point: `00001531-1212-efde-1523-785feabcd123`
|
||||
- Packet: `00001532-1212-efde-1523-785feabcd123`
|
||||
|
||||
A DFU upgrade archive for InfiniTime consists of multiple files. The most important being the .bin and .dat files. The first is the actual firmware, while the second is a packet that initializes DFU. Both are needed for a DFU upgrade.
|
||||
|
||||
The first thing to do is to enable notifications on the control point characteristic. This will be needed for verifying that the proper responses are being sent back from InfiniTime.
|
||||
|
||||
#### Step one
|
||||
|
||||
For the first step, write `0x01`, `0x04` to the control point characteristic. This will signal InfiniTime that a DFU upgrade is to be started.
|
||||
|
||||
#### Step two
|
||||
|
||||
In step two, send the total size in bytes of the firmware file to the packet characteristic. This value should be an unsigned 32-bit integer encoded as little-endian. In front of this integer should be 8 null bytes. This is because there are three items that can be updated and each 4 bytes is for one of those. The last four are for the InfiniTime application, so those are the ones that need to be set.
|
||||
|
||||
#### Step three
|
||||
|
||||
Before running step three, wait for a response from the control point. This response should be `0x10`, `0x01`, `0x01` which indicates a successful DFU start. In step three, send `0x02`, `0x00` to the control point. This will signal InfiniTime to expect the init packet on the packet characteristic.
|
||||
|
||||
#### Step four
|
||||
|
||||
The previous step prepared InfiniTime for this one. In this step, send the contents of the .dat init packet file to the packet characteristic. After this, send `0x02`, `0x01` indicating that the packet has been sent.
|
||||
|
||||
#### Step five
|
||||
|
||||
Before running this step, wait to receive `0x10`, `0x02`, `0x01` which indicates that the packet has been received. During this step, send the packet receipt interval to the control point. The firmware file will be sent in segments of 20 bytes each. The packet receipt interval indicates how many segments should be received before sending a receipt containing the amount of bytes received so that it can be confirmed to be the same as the amount sent. This is very useful for detecting packet loss. `itd` uses `0x08`, `0x0A` which indicates 10 segments.
|
||||
|
||||
#### Step six
|
||||
|
||||
In step six, write `0x03` to the control point, indicating that the firmware will be sent next on the packet characteristic.
|
||||
|
||||
#### Step seven
|
||||
|
||||
This step is the most difficult. Here, the actual firmware is sent to InfiniTime.
|
||||
|
||||
As mentioned before, the firmware file must be split up into segments of 20 bytes each and sent to the packet characteristic one by one. Every 10 segments (or whatever you have set the interval to), check for a response starting with `0x11`. The rest of the response will be the amount of bytes received encoded as a little-endian unsigned 32-bit integer. Confirm that this matches the amount of bytes sent, and then continue sending more segments.
|
||||
|
||||
#### Step eight
|
||||
|
||||
Before running this step, wait to receive `0x10`, `0x03`, `0x01` which indicates a successful receipt of the firmware image. In this step, write `0x04` to the control point to signal InfiniTime to validate the image it has received.
|
||||
|
||||
#### Step nine
|
||||
|
||||
Before running this step, wait to receive `0x10`, `0x04`, `0x01` which indicates that the image has been validated. In this step, send `0x05` to the control point as a command with no response. This signals InfiniTime to activate the new firmware and reboot.
|
||||
|
||||
Once all of these steps are complete, the DFU is complete. Don't forget to validate the firmware in the settings.
|
||||
|
||||
---
|
||||
|
||||
### Music Control
|
||||
|
||||
InfiniTime contains a music controller app which is meant to control the music playback and volume through the companion.
|
||||
|
||||
The following UUIDs are relevant to this:
|
||||
|
||||
- Events: `00000001-78fc-48fe-8e23-433b3a1942d0`
|
||||
- Status: `00000002-78fc-48fe-8e23-433b3a1942d0`
|
||||
- Artist: `00000003-78fc-48fe-8e23-433b3a1942d0`
|
||||
- Track: `00000004-78fc-48fe-8e23-433b3a1942d0`
|
||||
- Album: `00000005-78fc-48fe-8e23-433b3a1942d0`
|
||||
|
||||
#### Events
|
||||
|
||||
The events characteristic is meant to respond to user input in the music controller app.
|
||||
|
||||
Enabling notifications on this characteristic gives you a single byte upon any event. This byte can be converted to an unsigned 8-bit integer which corresponds to each possible event. Here are the events:
|
||||
|
||||
- App Opened: `0xe0`
|
||||
- Play: `0x00`
|
||||
- Pause: `0x01`
|
||||
- Next: `0x03`
|
||||
- Previous: `0x04`
|
||||
- Volume up: `0x05`
|
||||
- Volume down: `0x06`
|
||||
|
||||
#### Status
|
||||
|
||||
The status characteristic allows setting the playing status of music. Send `0x01` to the status characteristic for playing, and `0x00` for paused.
|
||||
|
||||
#### Artist, Track, and Album
|
||||
|
||||
These characteristics all work the same way. Simply send a UTF-8 encoded string to the relevant characteristic in order to set the value in the app.
|
||||
|
||||
---
|
||||
|
||||
### Time
|
||||
|
||||
InfiniTime allows setting its time via the Current Time Service (CTS)
|
||||
|
||||
The UUID for the current time characteristic is: `00002a2b-0000-1000-8000-00805f9b34fb`
|
||||
|
||||
This characteristic expects a particular format:
|
||||
|
||||
- Year (`uint16`)
|
||||
- Month (`uint8`)
|
||||
- Day (`uint8`)
|
||||
- Hour (`uint8`)
|
||||
- Minute (`uint8`)
|
||||
- Second (`uint8`)
|
||||
- Weekday (`uint8`)
|
||||
- Microsecond divided by `1e6*256` (`uint8`)
|
||||
- Binary 0001 (`uint8`)
|
||||
|
||||
Write all of these together, encoded as little-endian, to the current time characteristic.
|
||||
|
@ -3,7 +3,7 @@ Pinetime --> CompanionApp: Start advertising
|
||||
|
||||
group BLE Connection
|
||||
CompanionApp -> Pinetime: Connection request
|
||||
CompanionApp <-> Pinetime: Connection parameters negociation, security procedure,...
|
||||
CompanionApp <-> Pinetime: Connection parameters negotiation, security procedure,...
|
||||
end
|
||||
|
||||
group Service Discovery
|
||||
|
Before Width: | Height: | Size: 187 KiB After Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 208 KiB |
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 176 KiB |
@ -1,12 +1,12 @@
|
||||
# Branches
|
||||
The branching model of this project is based on the workflow named [Git flow](https://nvie.com/posts/a-successful-git-branching-model/).
|
||||
|
||||
It is based on 2 main branches:
|
||||
- **master** : this branch is always ready to be reployed. It means that at any time, we should be able to build the branch and release a new version of the application.
|
||||
The project is based on 2 main branches:
|
||||
- **master** : this branch is always ready to be deployed. It means that at any time, we should be able to build the branch and release a new version of the application.
|
||||
- **develop** : this branch contains the latest development that will be integrated in the next release once it's considered as stable.
|
||||
|
||||
New features should be implemented in **feature branches** created from **develop**. When the feature is ready, a pull-request is created and it'll be merge into **develop** when it is succesfully reviewed and accepted.
|
||||
New features should be implemented in **feature branches** created from **develop**. When the feature is ready, a pull-request is created and it'll be merge into **develop** when it is successfully reviewed and accepted.
|
||||
|
||||
To release a new version of the application, when develop is considered stable, a **release** branch is created from **develop**. This can be considered as a *release candidate* branch. When everything is OK, this release branch is merged into **master** and the release is generated (a tag is applied to git, the release note is finalized, binaries are built,...) from **master**.
|
||||
|
||||
Git flow also supports the creation of **hotfix** branches when a bug is discovered in a released version. The **hotfix** branch is created from **master** and will be used only to implement a fix to this bug. Multiple hotfix branches can be created for the same release if more than one bugs are discovered.
|
||||
Git flow also supports the creation of **hotfix** branches when a bug is discovered in a released version. The **hotfix** branch is created from **master** and will be used only to implement a fix to this bug. Multiple hotfix branches can be created for the same release if multiple bugs are discovered.
|
@ -1,15 +1,26 @@
|
||||
# Build
|
||||
## Dependencies
|
||||
To build this project, you'll need:
|
||||
- A cross-compiler : [ARM-GCC (9-2020-q2-update)](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/9-2020-q2-update)
|
||||
- A cross-compiler : [ARM-GCC (arm-none-eabi 11.2-2022.02)](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads)
|
||||
- The NRF52 SDK 15.3.0 : [nRF-SDK v15.3.0](https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip)
|
||||
- The `cbor` and `intelhex` modules for Python 3
|
||||
- The Python 3 modules `cbor`, `intelhex`, `click` and `cryptography` modules for the `mcuboot` tool (see [requirements.txt](../tools/mcuboot/requirements.txt))
|
||||
- To keep the system clean, you can install python modules into a python virtual environment (`venv`)
|
||||
```sh
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python -m pip install wheel
|
||||
python -m pip install -r tools/mcuboot/requirements.txt
|
||||
```
|
||||
- A reasonably recent version of CMake (I use 3.16.5)
|
||||
- lv_font_conv, to generate the font .c files
|
||||
- see [lv_font_conv](https://github.com/lvgl/lv_font_conv#install-the-script)
|
||||
- install npm (commonly done via the package manager, ensure node's version is at least 12)
|
||||
- install lv_font_conv: `npm install lv_font_conv`
|
||||
|
||||
## Build steps
|
||||
### Clone the repo
|
||||
```
|
||||
git clone https://github.com/JF002/InfiniTime.git
|
||||
git clone https://github.com/InfiniTimeOrg/InfiniTime.git
|
||||
cd InfiniTime
|
||||
git submodule update --init
|
||||
mkdir build
|
||||
@ -20,22 +31,23 @@ CMake configures the project according to variables you specify the command line
|
||||
|
||||
Variable | Description | Example|
|
||||
----------|-------------|--------|
|
||||
**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`-DARM_NONE_EABI_TOOLCHAIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2020-q2-update/`|
|
||||
**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`-DARM_NONE_EABI_TOOLCHAIN_PATH=/home/jf/nrf52/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/`|
|
||||
**NRF5_SDK_PATH**|path to the NRF52 SDK|`-DNRF5_SDK_PATH=/home/jf/nrf52/Pinetime/sdk`|
|
||||
**USE_JLINK, USE_GDB_CLIENT and USE_OPENOCD**|Enable *JLink* mode, *GDB Client* (Black Magic Probe) mode or *OpenOCD* mode (set the one you want to use to `1`)|`-DUSE_JLINK=1`
|
||||
**CMAKE_BUILD_TYPE (\*)**| Build type (Release or Debug). Release is applied by default if this variable is not specified.|`-DCMAKE_BUILD_TYPE=Debug`
|
||||
**NRFJPROG**|Path to the NRFJProg executable. Used only if `USE_JLINK` is 1.|`-DNRFJPROG=/opt/nrfjprog/nrfjprog`
|
||||
**GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb`
|
||||
**GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0`
|
||||
**BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-BUILD_DFU=1`
|
||||
**BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1`
|
||||
**WATCH_COLMI_P8**|Use pin configuration for Colmi P8 watch|`-DWATCH_COLMI_P8=1`
|
||||
|
||||
####(**) Note about **CMAKE_BUILD_TYPE**:
|
||||
By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime.
|
||||
By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/InfiniTimeOrg/InfiniTime/releases) new versions of InfiniTime.
|
||||
|
||||
The *Debug* mode disables all optimizations, which makes the code easier to debug. However, the binary size will likely be too big to fit in the internal flash memory. If you want to build and debug a *Debug* binary, you'll need to disable some parts of the code. For example, the icons for the **Navigation** app use a lot of memory space. You can comment the content of `m_iconMap` in the [Navigation](https://github.com/JF002/InfiniTime/blob/develop/src/displayapp/screens/Navigation.h#L148) application to free some memory.
|
||||
The *Debug* mode disables all optimizations, which makes the code easier to debug. However, the binary size will likely be too big to fit in the internal flash memory. If you want to build and debug a *Debug* binary, you'll need to disable some parts of the code. For example, the icons for the **Navigation** app use a lot of memory space. You can comment the content of `m_iconMap` in the [Navigation](https://github.com/InfiniTimeOrg/InfiniTime/blob/develop/src/displayapp/screens/Navigation.h#L148) application to free some memory.
|
||||
|
||||
####(**) Note about **BUILD_DFU**:
|
||||
DFU files are the files you'll need to install your build of InfiniTime using OTA (over-the-air) mecanism. To generate the DFU file, the Python tool [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) is needed on your system. Check that this tool is properly installed before enabling this option.
|
||||
DFU files are the files you'll need to install your build of InfiniTime using OTA (over-the-air) mechanism. To generate the DFU file, the Python tool [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) is needed on your system. Check that this tool is properly installed before enabling this option.
|
||||
|
||||
#### CMake command line for JLink
|
||||
```
|
||||
@ -163,7 +175,7 @@ J-Link>g
|
||||
```
|
||||
|
||||
#### JLink RTT
|
||||
RTT is a feature from Segger's JLink devices that allows bidirectionnal communication between the debugger and the target. This feature can be used to get the logs from the embedded software on the development computer.
|
||||
RTT is a feature from Segger's JLink devices that allows bidirectional communication between the debugger and the target. This feature can be used to get the logs from the embedded software on the development computer.
|
||||
|
||||
- Program the MCU with the code (see above)
|
||||
- Start JLinkExe
|
||||
@ -223,3 +235,33 @@ Loading section .sec7, size 0xdf08 lma 0x40000
|
||||
Start address 0x0, load size 314200
|
||||
Transfer rate: 45 KB/sec, 969 bytes/write.
|
||||
```
|
||||
|
||||
### How to generate files needed by the factory
|
||||
These files are needed by the Pine64 factory to flash InfiniTime as the default firmware on the PineTimes.
|
||||
|
||||
Two files are needed: an **HEX (.hex)** file that contains the content of the internal flash memory (bootloader + InfiniTime) and a **binary (.bin)** file that contains the content of the external flash memory (recovery firmware).
|
||||
|
||||
#### merged-internal.hex
|
||||
First, convert the bootloader to hex:
|
||||
```
|
||||
<ARM TOOLCHAIN>/bin/arm-none-eabi-objcopy -I binary -O ihex ./bootloader.bin ./bootloader.hex
|
||||
```
|
||||
where `bootloader.bin` is the [last stable version](https://github.com/JF002/pinetime-mcuboot-bootloader/releases) of the [bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader).
|
||||
|
||||
Then, convert the MCUBoot image of InfiniTime:
|
||||
```
|
||||
<ARM TOOLCHAIN>/bin/arm-none-eabi-objcopy -I binary -O ihex --change-addresses 0x8000 ./pinetime-mcuboot-app-image-1.6.0.bin ./pinetime-mcuboot-app-image-1.6.0.hex
|
||||
```
|
||||
where `pinetime-mcuboot-app-image-1.6.0.bin` is [the bin of the last MCUBoot image](https://github.com/InfiniTimeOrg/InfiniTime/releases) of [InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime).
|
||||
|
||||
Pay attention to the parameter `--change-addresses 0x8000`. It's needed to ensure the image will be flashed at the offset expected by the bootloader (0x8000).
|
||||
|
||||
Finally, merge them together with **mergehex**:
|
||||
```
|
||||
/opt/mergehex/mergehex -m ./bootloader.hex ./pinetime-mcuboot-app-image-1.6.0.hex -o merged-internal.hex
|
||||
```
|
||||
|
||||
This file must be flashed at offset **0x00** of the internal memory of the NRF52832.
|
||||
|
||||
#### spinor.bin
|
||||
This file is the MCUBoot image of the last stable version of the recovery firmware. It must be flashed at offset **0x00** of the external SPINOR flash memory.
|
||||
|
@ -1,60 +1,58 @@
|
||||
# Build the project using Docker
|
||||
|
||||
A [Docker image (Dockerfile)](../docker) containing all the build environment is available for X86_64 and AMD64 architectures. These images make the build of the firmware and the generation of the DFU file for OTA quite easy, as well as preventing clashes with any other toolchains or development environments you may have installed.
|
||||
A [Docker image (Dockerfile)](../docker) containing all the build environment is available for X86_64 and AMD64 architectures.
|
||||
These images make the build of the firmware and the generation of the DFU file for OTA quite easy, as well as preventing clashes with any other toolchains or development environments you may have installed.
|
||||
|
||||
Based on Ubuntu 18.04 with the following build dependencies:
|
||||
Based on Ubuntu 22.04 with the following build dependencies:
|
||||
|
||||
* ARM GCC Toolchain
|
||||
* nRF SDK
|
||||
* MCUBoot
|
||||
* adafruit-nrfutil
|
||||
* lv_font_conv
|
||||
|
||||
## Run a container to build the project
|
||||
|
||||
The `infinitime-build` image contains all the dependencies you need. The default `CMD` will compile sources found in `/sources`, so you need only mount your code.
|
||||
The `infinitime-build` image contains all the dependencies you need.
|
||||
The default `CMD` will compile sources found in `/sources`, so you need only mount your code.
|
||||
|
||||
This example will build the firmware, generate the MCUBoot image and generate the DFU file. Outputs will be written to **<project_root>/build/output**:
|
||||
Before continuing, make sure you first build the image as indicated in the [Build the image](#build-the-image) section, or check the [Using the image from Docker Hub](#using-the-image-from-docker-hub) section if you prefer to use a pre-made image.
|
||||
|
||||
This example will build the firmware, generate the MCUBoot image and generate the DFU file.
|
||||
For cloning the repo, see [these instructions](../doc/buildAndProgram.md#clone-the-repo). Outputs will be written to **<project_root>/build/output**:
|
||||
|
||||
```bash
|
||||
cd <project_root> # e.g. cd ./work/Pinetime
|
||||
docker run --rm -it -v $(pwd):/sources infinitime-build
|
||||
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime-build
|
||||
```
|
||||
|
||||
If you only want to build a single CMake target, you can pass it in as the first parameter to the build script. This means calling the script explicitly as it will override the `CMD`. Here's an example For `pinetime-app`:
|
||||
By default, the container runs as `root`, which is not convenient as all the files generated by the build will also belong to `root`.
|
||||
The parameter `--user` overrides that default behavior.
|
||||
The command above will run as your current user.
|
||||
|
||||
If you only want to build a single CMake target, you can pass it in as the first parameter to the build script.
|
||||
This means calling the script explicitly as it will override the `CMD`.
|
||||
Here's an example for `pinetime-app`:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $(pwd):/sources infinitime-build /opt/build.sh pinetime-app
|
||||
```
|
||||
|
||||
The image is built using 1000:1000 for the user id and group id. If this is different to your user or group ids (run `id -u` and `id -g` to find out what your id values are if you are unsure), you will need to override them via the `--user` parameter in order to prevent permission errors with the output files (and the cmake build cache).
|
||||
|
||||
Running with this image is the same as above, you just specify the ids to `docker run`
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $(pwd):/sources --user $(id -u):$(id -g) pfeerick/infinitime-build
|
||||
```
|
||||
|
||||
Or you can specify your user id and group id (by number, not by name) directly:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $(pwd):/sources --user 1234:1234 infinitime-build
|
||||
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime-build /opt/build.sh pinetime-app
|
||||
```
|
||||
|
||||
## Using the image from Docker Hub
|
||||
|
||||
The image is avaiable via Docker Hub for both the amd64 and arm64v8 architectures at [pfeerick/infinitime-build](https://hub.docker.com/repository/docker/pfeerick/infinitime-build).
|
||||
The image is available via Docker Hub for both the amd64 and arm64v8 architectures at [infinitime/infinitime-build](https://hub.docker.com/repository/docker/infinitime/infinitime-build).
|
||||
|
||||
It can be pulled (downloaded) using the following command:
|
||||
You can run it using the following command:
|
||||
|
||||
```bash
|
||||
docker pull pfeerick/infinitime-build
|
||||
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime/infinitime-build
|
||||
```
|
||||
|
||||
The default `latest` tag *should* automatically identify the correct image architecture, but if for some reason Docker does not, you can specify it manually:
|
||||
|
||||
* For AMD64 (x86_64) systems: `docker pull pfeerick/infinitime-build:amd64`
|
||||
* For AMD64 (x86_64) systems: `docker pull --platform linux/amd64 infinitime/infinitime-build`
|
||||
|
||||
* For ARM64v8 (ARM64/aarch64) systems: `docker pull pfeerick/infinitime-build:arm64v8`
|
||||
* For ARM64v8 (ARM64/aarch64) systems: `docker pull --platform linux/arm64 infinitime/infinitime-build`
|
||||
|
||||
## Build the image
|
||||
|
||||
@ -63,11 +61,5 @@ You can build the image yourself if you like!
|
||||
The following commands must be run from the root of the project. This operation will take some time but, when done, a new image named *infinitime-build* is available.
|
||||
|
||||
```bash
|
||||
docker image build -t infinitime-build ./docker
|
||||
```
|
||||
|
||||
The `PUID` and `PGID` build arguments are used to set the user and group ids used in the container, meaning you will not need to specify it later unless they change for some reason. Specifying them is not mandatory, as this can be over-ridden at build time via the `--user` flag, but doing so will make the command you need to run later a bit shorter. In the below examples, they are set to your current user id and group id automatically. You can specify them manually, but they must be specified by number, not by name.
|
||||
|
||||
```bash
|
||||
docker image build -t infinitime-build --build-arg PUID=$(id -u) --build-arg PGID=$(id -g) ./docker
|
||||
docker build -t infinitime-build ./docker
|
||||
```
|
52
doc/buildWithVScode.md
Normal file
@ -0,0 +1,52 @@
|
||||
# Build and Develop the project using VS Code
|
||||
|
||||
The .VS Code folder contains configuration files for developing InfiniTime with VS Code. Effort was made to have these rely on Environment variables instead of hardcoded paths.
|
||||
|
||||
## Environment Setup
|
||||
|
||||
To support as many setups as possible the VS Code configuration files expect there to be certain environment variables to be set.
|
||||
|
||||
Variable | Description | Example
|
||||
----------|-------------|--------
|
||||
**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`export ARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi`
|
||||
**NRF5_SDK_PATH**|path to the NRF52 SDK|`export NRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345`
|
||||
|
||||
## VS Code Extensions
|
||||
|
||||
We leverage a few VS Code extensions for ease of development.
|
||||
|
||||
#### Required Extensions
|
||||
|
||||
- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) - C/C++ IntelliSense, debugging, and code browsing.
|
||||
- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) - Extended CMake support in Visual Studio Code
|
||||
|
||||
#### Optional Extensions
|
||||
|
||||
[Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) - ARM Cortex-M GDB Debugger support for VS Code
|
||||
|
||||
Cortex-Debug is only required for interactive debugging using VS Codes built in GDB support.
|
||||
|
||||
|
||||
|
||||
## VS Code/Docker DevContainer
|
||||
|
||||
The .devcontainer folder contains the configuration and scripts for using a Docker dev container for building InfiniTime
|
||||
|
||||
Using the [Remote-Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension is recommended. It will handle configuring the Docker virtual machine and setting everything up.
|
||||
|
||||
More documentation is available in the [readme in .devcontainer](.devcontainer/readme.md)
|
||||
|
||||
### DevContainer on Ubuntu
|
||||
To use the DevContainer configuration on Ubuntu based systems two changes need to be made:
|
||||
|
||||
1. Modify the file ``.devcontainer/devcontainer.json`` and add the argument ``"--net=host"`` to the ``"runArgs"`` parameter making the line look like this:
|
||||
`` "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--net=host"],
|
||||
``
|
||||
2. Modify the file ``.vscode/launch.json`` and change the argument of ``"gdbTarget"`` to ``"127.0.0.1:3333"``, making the line look like:
|
||||
``"gdbTarget": "127.0.0.1:3333",``
|
||||
3. To start debugging launch openocd on your host system with the appropriate configuration, for example with a stlink-v2 the command is:
|
||||
``openocd -f interface/stlink.cfg -f target/nrf52.cfg``. This launches openocd with the default ports ``3333``, ``4444`` and ``6666``.
|
||||
4. In VsCode go to the Debug pane on the left of the screen and select the configuration ``Debug - Openocd docker Remote`` and hit the play button on the left.
|
||||
|
||||
|
||||
|
99
doc/code/Apps.md
Normal file
@ -0,0 +1,99 @@
|
||||
# Apps
|
||||
This page will teach you:
|
||||
- what screens and apps are in InfiniTime
|
||||
- how to implement your own app
|
||||
|
||||
## Theory
|
||||
|
||||
The user interface of InfiniTime is made up of **screens**.
|
||||
Screens that are opened from the app launcher are considered **apps**.
|
||||
Every app in InfiniTime is it's own class.
|
||||
An instance of the class is created when the app is launched, and destroyed when the user exits the app.
|
||||
Apps run inside the "displayapp" task (briefly discussed [here](./Intro.md)).
|
||||
Apps are responsible for everything drawn on the screen when they are running.
|
||||
By default, apps only do something (as in a function is executed) when they are created or when a touch event is detected.
|
||||
|
||||
## Interface
|
||||
Every app class has to be inside the namespace `Pinetime::Applications::Screens` and inherit from `Screen`.
|
||||
The constructor should have at least one parameter `DisplayApp* app`, which it needs for the constructor of its parent class Screen.
|
||||
Other parameters should be references to controllers that the app needs.
|
||||
A destructor is needed to clean up LVGL and restore any changes (for example re-enable sleeping).
|
||||
App classes can override `bool OnButtonPushed()`, `bool OnTouchEvent(TouchEvents event)` and `bool OnTouchEvent(uint16_t x, uint16_t y)` to implement their own functionality for those events.
|
||||
If an app only needs to display some text and do something upon a touch screen button press,
|
||||
it does not need to override any of these functions, as LVGL can also handle touch events for you.
|
||||
If you have any doubts, you can always look at how the other apps function for reference.
|
||||
|
||||
### Continuous updating
|
||||
If your app needs to be updated continuously, you can do so by overriding the `Refresh()` function in your class
|
||||
and calling `lv_task_create` inside the constructor.
|
||||
|
||||
An example call could look like this:
|
||||
```cpp
|
||||
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
||||
```
|
||||
|
||||
With `taskRefresh` being a member variable of your class and of type `lv_task_t*`.
|
||||
Remember to delete the task again using `lv_task_del`.
|
||||
The function `RefreshTaskCallback` is inherited from `Screen` and just calls your `Refresh` function.
|
||||
|
||||
## Creating your own app
|
||||
A minimal app could look like this:
|
||||
|
||||
MyApp.h:
|
||||
```cpp
|
||||
#pragma once
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
class MyApp : public Screen {
|
||||
public:
|
||||
MyApp(DisplayApp* app);
|
||||
~MyApp() override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
MyApp.cpp:
|
||||
```cpp
|
||||
#include "displayapp/screens/MyApp.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
MyApp::MyApp(DisplayApp* app) : Screen(app) {
|
||||
lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(title, "My test application");
|
||||
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(title, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
|
||||
}
|
||||
|
||||
MyApp::~MyApp() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
```
|
||||
Both of these files should be in [displayapp/screens/](/src/displayapp/screens/)
|
||||
or [displayapp/screens/settings/](/src/displayapp/screens/settings/) if it's a setting app.
|
||||
|
||||
Now we have our very own app, but InfiniTime does not know about it yet.
|
||||
The first step is to include your MyApp.cpp (or any new cpp files for that matter)
|
||||
in the compilation by adding it to [CMakeLists.txt](/CMakeLists.txt).
|
||||
The next step to making it launchable is to give your app an id.
|
||||
To do this, add an entry in the enum class `Pinetime::Applications::Apps` ([displayapp/Apps.h](/src/displayapp/Apps.h)).
|
||||
Name this entry after your app. Add `#include "displayapp/screens/MyApp.h"` to the file [displayapp/DisplayApp.cpp](/src/displayapp/DisplayApp.cpp).
|
||||
Now, go to the function `DisplayApp::LoadApp` and add another case to the switch statement.
|
||||
The case will be the id you gave your app earlier.
|
||||
If your app needs any additional arguments, this is the place to pass them.
|
||||
|
||||
If you want to add your app in the app launcher, add your app in [displayapp/screens/ApplicationList.cpp](/src/displayapp/screens/ApplicationList.cpp) to one of the `CreateScreen` functions, or add another `CreateScreen` function if there are no empty spaces for your app. If your app is a setting, do the same procedure in [displayapp/screens/settings/Settings.cpp](/src/displayapp/screens/settings/Settings.cpp).
|
||||
|
||||
You should now be able to [build](../buildAndProgram.md) the firmware
|
||||
and flash it to your PineTime. Yay!
|
||||
|
||||
Please remember to pay attention to the [UI guidelines](../ui_guidelines.md)
|
||||
when designing an app that you want to be included in InfiniTime.
|
43
doc/code/Intro.md
Normal file
@ -0,0 +1,43 @@
|
||||
# Introduction to the code
|
||||
This page is meant to guide you through the source code, so you can find the relevant files for what you're working on.
|
||||
|
||||
## FreeRTOS
|
||||
Infinitime is based on FreeRTOS, a real-time operating system.
|
||||
FreeRTOS provides several quality of life abstractions (for example easy software timers)
|
||||
and most importantly supports multiple tasks.
|
||||
If you want to read up on real-time operating systems, you can look [here](https://www.freertos.org/implementation/a00002.html) and [here](https://www.freertos.org/features.html).
|
||||
The main "process" creates at least one task and then starts the FreeRTOS task scheduler.
|
||||
This main "process" is the standard main() function inside [main.cpp](/src/main.cpp).
|
||||
The task scheduler is responsible for giving every task enough cpu time.
|
||||
As there is only one core on the SoC of the PineTime, real concurrency is impossible and the scheduler has to swap tasks in and out to emulate it.
|
||||
|
||||
### Tasks
|
||||
Tasks are created by calling `xTaskCreate` and passing a function with the signature `void functionName(void*)`.
|
||||
For more info on task creation see the [FreeRTOS Documentation](https://www.freertos.org/a00125.html).
|
||||
In our case, main calls `systemTask.Start()`, which creates the **"MAIN" task**.
|
||||
The function running inside that task is `SystemTask::Work()`.
|
||||
You may also see this task being referred to as the **work task**.
|
||||
Both functions are located inside [systemtask/SystemTask.cpp](/src/systemtask/SystemTask.cpp). `SystemTask::Work()` initializes all the driver and controller objects.
|
||||
It also starts the **task "displayapp"**, which is responsible for launching and running apps, controlling the screen and handling touch events (or forwarding them to the active app).
|
||||
You can find the "displayapp" task inside [displayapp/DisplayApp.cpp](/src/displayapp/DisplayApp.cpp).
|
||||
There are also other tasks that are responsible for Bluetooth ("ll" and "ble" inside [libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c](/src/libs/mynewt-nimble/porting/npl/freertos/src/nimble_port_freertos.c))
|
||||
and periodic tasks like heartrate measurements ([heartratetask/HeartRateTask.cpp](/src/heartratetask/HeartRateTask.cpp)).
|
||||
|
||||
While it is possible for you to create your own task when you need it, it is recommended to just add functionality to `SystemTask::Work()` if possible.
|
||||
If you absolutely need to create another task, try to estimate how much [stack space](https://www.freertos.org/FAQMem.html#StackSize) (in words/4-byte packets)
|
||||
it will need instead of just typing in a large-ish number.
|
||||
You can use `configMINIMAL_STACK_SIZE` which is currently set to 120 words.
|
||||
|
||||
## Controllers
|
||||
Controllers in InfiniTime are singleton objects that can provide access to certain resources to apps.
|
||||
Some of them interface with drivers, others are the driver for the resource.
|
||||
The resources provided don't have to be hardware-based.
|
||||
They are declared in main.cpp and initialized in [systemtask/SystemTask.cpp](/src/systemtask/SystemTask.cpp).
|
||||
Some controllers can be passed by reference to apps that need access to the resource (for example vibration motor).
|
||||
They reside in [components/](/src/components/) inside their own subfolder.
|
||||
|
||||
## Apps
|
||||
For more detail see the [Apps page](./Apps.md)
|
||||
|
||||
## Bluetooth
|
||||
Header files with short documentation for the functions are inside [libs/mynewt-nimble/nimble/host/include/host/](/src/libs/mynewt-nimble/nimble/host/include/host/).
|
41
doc/coding-convention.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Coding convention
|
||||
|
||||
## Language
|
||||
|
||||
The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction.
|
||||
|
||||
C code is accepted if it comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK.
|
||||
|
||||
## Coding style
|
||||
|
||||
The most important rule to follow is to try to keep the code as easy to read and maintain as possible.
|
||||
|
||||
Using an autoformatter is highly recommended, but make sure it's configured properly.
|
||||
|
||||
There are preconfigured autoformatter rules for:
|
||||
|
||||
* CLion (IntelliJ) in [.idea/codeStyles/Project.xml](/.idea/codeStyles/Project.xml)
|
||||
* `clang-format`
|
||||
|
||||
Also use `clang-tidy` to check the code for other issues.
|
||||
|
||||
If there are no preconfigured rules for your IDE, you can use one of the existing ones to configure your IDE.
|
||||
|
||||
- **Indentation** : 2 spaces, no tabulation
|
||||
- **Opening brace** at the end of the line
|
||||
- **Naming** : Choose self-describing variable name
|
||||
- **class** : PascalCase
|
||||
- **namespace** : PascalCase
|
||||
- **variable** : camelCase, **no** prefix/suffix ('_', 'm_',...) for class members
|
||||
- **Include guard** : `#pragma once` (no `#ifdef __MODULE__ / #define __MODULE__ / #endif`)
|
||||
- **Includes** :
|
||||
- files from the project : `#include "relative/path/to/the/file.h"`
|
||||
- external files and std : `#include <file.h>`
|
||||
- use includes relative to included directories like `src`, not relative to the current file. Don't do: `#include "../file.h"`
|
||||
- Only use [primary spellings for operators and tokens](https://en.cppreference.com/w/cpp/language/operator_alternative)
|
||||
- Use auto sparingly. Don't use auto for [fundamental/built-in types](https://en.cppreference.com/w/cpp/language/types) and [fixed width integer types](https://en.cppreference.com/w/cpp/types/integer), except when initializing with a cast to avoid duplicating the type name.
|
||||
- Examples:
|
||||
- `auto* app = static_cast<DisplayApp*>(instance);`
|
||||
- `auto number = static_cast<uint8_t>(variable);`
|
||||
- `uint8_t returnValue = MyFunction();`
|
||||
- Use nullptr instead of NULL
|
@ -1,15 +0,0 @@
|
||||
# Amazfish
|
||||
[Amazfish](https://openrepos.net/content/piggz/amazfish) is a companion app that supports many smartwatches and activity trackers running on [SailfishOS](https://sailfishos.org/).
|
||||
|
||||
## Features
|
||||
The following features are implemented:
|
||||
- Scanning & detection of Pinetime-JF / InfiniTime
|
||||
- Connection / disconnection
|
||||
- Time synchronization
|
||||
- Notifications
|
||||
- Music control
|
||||
|
||||
## Demo
|
||||
[This video](https://seafile.codingfield.com/f/21c5d023452740279e36/) shows how to connect to the Pinetime and control the playback of the music on the phone.
|
||||
Amazfish and Sailfish OS are running on the [Pinephone](https://www.pine64.org/pinephone/), another awesome device from Pine64.
|
||||
|
@ -1,13 +0,0 @@
|
||||
# Integration with Gadgetbridge
|
||||
[Gadgetbridge](https://gadgetbridge.org/) is an Android application that supports many smartwatches and fitness trackers.
|
||||
|
||||
The integration of InfiniTime (previously Pinetime-JF) is now merged into the master branch (https://codeberg.org/Freeyourgadget/Gadgetbridge/).
|
||||
|
||||
## Features
|
||||
The following features are implemented:
|
||||
- Scanning & detection of Pinetime-JF / InfiniTime
|
||||
- Connection / disconnection
|
||||
- Notifications
|
||||
|
||||
## Demo
|
||||
[This video](https://seafile.codingfield.com/f/0a2920b9d765462385e4/) shows how to scan, connect, send notification (using the debug screen) and disconnect from the Pinetime.
|
@ -1,12 +0,0 @@
|
||||
# OTA using NRFConnect
|
||||
[NRFConnect](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Connect-for-mobile) is a powerful application (running on Android and iOS) which allows to scan and connect to BLE devices.
|
||||
|
||||
## Features
|
||||
- Scanning, connect, disconnect
|
||||
- Time synchronization
|
||||
- OTA
|
||||
|
||||
InfiniTime implements the Nordic DFU protocol for the OTA functionality. NRFConnect also supports this protocol.
|
||||
|
||||
# Demo
|
||||
[This video](https://seafile.codingfield.com/f/a52b69683a05472a90c7/) shows how to use NRFConnect to update the firmware running on the Pinetime.
|
@ -1,75 +1,61 @@
|
||||
# How to contribute?
|
||||
|
||||
## Report bugs
|
||||
You use your Pinetime and find a bug in the firmware? [Create an issue on Github](https://github.com/JF002/InfiniTime/issues) explaining the bug, how to reproduce it, the version of the firmware you use...
|
||||
|
||||
Have you found a bug in the firmware? [Create an issue on Github](https://github.com/InfiniTimeOrg/InfiniTime/issues) explaining the bug, how to reproduce it, the version of the firmware you use...
|
||||
|
||||
## Write and improve documentation
|
||||
|
||||
Documentation might be incomplete, or not clear enough, and it is always possible to improve it with better wording, pictures, photo, video,...
|
||||
|
||||
As the documentation is part of the source code, you can submit your improvements to the documentation by submitting a pull request (see below).
|
||||
## Fix bugs, add functionalities and improve the code
|
||||
You want to fix a bug, add a cool new functionality or improve the code? See *How to submit a pull request below*.
|
||||
## Spread the word
|
||||
The Pinetime is a cool open source project that deserves to be known. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open-source firmware for a smartwatch!
|
||||
|
||||
# How to submit a pull request ?
|
||||
## Fix bugs, add functionalities and improve the code
|
||||
|
||||
You want to fix a bug, add a cool new functionality or improve the code? See *How to submit a pull request below*.
|
||||
|
||||
# How to submit a pull request?
|
||||
|
||||
## TL;DR
|
||||
- Create a branch from develop;
|
||||
- Work on a single subject in this branch. Create multiple branches/pulls-requests if you want to work on multiple subjects (bugs, features,...);
|
||||
- Test your modifications on the actual hardware;
|
||||
- Check the code formatting against our coding conventions and [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy);
|
||||
- Clean your code and remove files that are not needed;
|
||||
- Write documentation related to your new feature is applicable;
|
||||
- Create the pull-request and write a great description about it : what does your PR do, why, how,... Add pictures and video if possible;
|
||||
- Wait for someone to review your PR and take part in the review process;
|
||||
|
||||
- Create a branch from develop
|
||||
- Work on a single subject in this branch. Create multiple branches/pulls-requests if you want to work on multiple subjects (bugs, features,...)
|
||||
- Test your modifications on the actual hardware
|
||||
- Check your code against the [coding conventions](/doc/coding-convention.md) and [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy)
|
||||
- Clean your code and remove files that are not needed
|
||||
- Write documentation related to your new feature if applicable
|
||||
- Create a pull request and write a great description about it: what does your PR do, why, how,... Add pictures and video if possible
|
||||
- Wait for someone to review your PR and take part in the review process
|
||||
- Your PR will eventually be merged :)
|
||||
|
||||
Your contribution is more than welcome!
|
||||
Your contributions are more than welcome!
|
||||
|
||||
If you want to fix a bug, add a functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, **focus on only one topic, bug or feature**. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch per topic.
|
||||
If you want to fix a bug, add functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, **focus on only one topic, bug or feature**. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch for each topic.
|
||||
|
||||
When your feature branch is ready, **make sure it actually works** and **do not forget to write documentation** about it if it's relevant.
|
||||
|
||||
I **strongly discourage to create a PR containing modifications that haven't been tested**. If, for any reason, you cannot test your modifications but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedback about your code.
|
||||
**Creating a pull request containing modifications that haven't been tested is strongly discouraged.** If for any reason you cannot test your modifications, but want to publish them anyway, **please mention it in the description**. This way, other contributors might be willing to test it and provide feedback about your code.
|
||||
|
||||
Also, before submitting your PR, check the coding style of your code against the **coding conventions** detailed below. This project also provides [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy) configuration files. You can use them to ensure correct formatting of your code.
|
||||
Before submitting a PR, check your code against the [coding conventions](/doc/coding-convention.md). This project also provides [clang-format](../.clang-format) and [clang-tidy](../.clang-tidy) configuration files. You should use them to ensure correct formatting of your code.
|
||||
|
||||
Do not forget to check the files you are going to commit and remove those who are not necessary (config files from your IDE, for example). Remove old comments, commented code,...
|
||||
Don't forget to check the files you are going to commit and remove those which aren't necessary (config files from your IDE, for example). Remove old comments, commented code,...
|
||||
|
||||
Then, you can submit a pull-request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how is it designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of your work.
|
||||
Then, you can submit a pull request for review. Try to **describe your pull request as much as possible**: what did you do in this branch, how does it work, how it is designed, are there any limitations,... This will help the contributors to understand and review your code easily. You can add pictures and video to the description so that contributors will have a quick overview of your work.
|
||||
|
||||
Other contributors can post comments about the pull request, maybe ask for more info or adjustments in the code.
|
||||
|
||||
Once the pull request is reviewed and accepted, it'll be merge in **develop** and will be released in the next release version of the firmware.
|
||||
Once the pull request is reviewed and accepted, it'll be merged into **develop** and will be released in the next version of the firmware.
|
||||
|
||||
## Why all these rules?
|
||||
Reviewing pull-requests is a **very time consuming task** for the creator of this project ([JF002](https://github.com/JF002)) and for other contributors who take the time to review them. Every little thing you do to make their lives easier will **increase the chances your PR will be merge quickly**.
|
||||
|
||||
When reviewing PR, the author and contributors will first look at the **description**. If it's easy to understand what the PR does, why the modification is needed or interesting and how it's done, a good part of the work is already done : we understand the PR and its context.
|
||||
Reviewing pull requests is a **very time consuming task**. Everything you do to make reviewing easier will **get your PR merged faster**.
|
||||
|
||||
Then, reviewing **a few files that were modified for a single purpose** is a lot more easier than to review 30 files modified for many reasons (bug fix, UI improvements, typos in doc,...), even if all these changes make sense. Also, it's possible that we agree on some modification but not on some other, and we won't be able to merge the PR because of the changes that are not accepted.
|
||||
Reviewers will first look at the **description**. If it's easy to understand what the PR does, why the modification is needed or interesting and how it's done, a good part of the work is already done : we understand the PR and its context.
|
||||
|
||||
We do our best to keep the code as consistent as possible, and that mean we pay attention to the **formatting** of the code. If the code formatting is not consistent with our code base, we'll ask you to review it, which will take more time.
|
||||
Reviewing **a few files that were modified for a single purpose** is a lot easier than reviewing 30 files modified for many reasons (bug fix, UI improvements, typos in doc,...), even if all the changes make sense. Also, it's possible that we agree on some modification but not on another, so we won't be able to merge the PR because of the changes that are not accepted.
|
||||
|
||||
The last step of the review consists in **testing** the modification. If it doesn't work out of the box, we'll ask your to review your code and to ensure that it works as expected.
|
||||
The code base should be kept as consistent as possible. If the formatting of your code is not consistent with the rest of the code base, we'll ask you to review it.
|
||||
|
||||
It's totally normal for a PR to need some more work even after it was created, that's why we review them. But every round trip takes time, and it's good practice to try to reduce them as much as possible by following those simple rules.
|
||||
Lastly the changes are tested. If it doesn't work out of the box, we'll ask you to review your code and to ensure that it works as expected.
|
||||
|
||||
# Coding convention
|
||||
## Language
|
||||
The language of this project is **C++**, and all new code must be written in C++. (Modern) C++ provides a lot of useful tools and functionalities that are beneficial for embedded software development like `constexpr`, `template` and anything that provides zero-cost abstraction.
|
||||
|
||||
It's OK to include C code if this code comes from another library like FreeRTOS, NimBLE, LVGL or the NRF-SDK.
|
||||
|
||||
## Coding style
|
||||
The most important rule to follow is to try to keep the code as easy to read and maintain as possible.
|
||||
|
||||
- **Indentation** : 2 spaces, no tabulation
|
||||
- **Opening brace** at the end of the line
|
||||
- **Naming** : Choose self-describing variable name
|
||||
- **class** : PascalCase
|
||||
- **namespace** : PascalCase
|
||||
- **variable** : camelCase, **no** prefix/suffix ('_', 'm_',...) for class members
|
||||
- **Include guard** : `#pragma once` (no `#ifdef __MODULE__ / #define __MODULE__ / #endif`)
|
||||
- **Includes** :
|
||||
- files from the project : `#include "relative/path/to/the/file.h"`
|
||||
- external files and std : `#include <file.h>`
|
||||
It's totally normal for a PR to need some more work even after it was created, that's why we review them. But every round trip takes time, so it's good practice to try to reduce them as much as possible by following those simple rules.
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Using the releases
|
||||
For each new *stable* version of Pinetime, a [release note](https://github.com/JF002/InfiniTime/releases) is created. It contains a description of the main changes in the release and some files you can use to flash the firmware in your Pinetime.
|
||||
For each new *stable* version of IniniTime, a [release note](https://github.com/InfiniTimeOrg/InfiniTime/releases) is created. It contains a description of the main changes in the release and some files you can use to flash the firmware to your Pinetime.
|
||||
|
||||
This page describes the files from the release notes and how to use them.
|
||||
|
||||
**NOTE :** the files included in different could be different. This page describes the release note of [version 0.7.1](https://github.com/JF002/InfiniTime/releases/tag/0.7.1), which is the version that'll probably be pre-programmed at the factory for the next batch of Pinetime devkits.
|
||||
**NOTE :** the files included in different Releases could be different. This page describes the release notes of [version 0.7.1](https://github.com/InfiniTimeOrg/InfiniTime/releases/tag/0.7.1), which is the version that is pre-programmed for the last batches of pinetimes but will be replaced with [1.0.0](https://github.com/jF002/infiniTime/releases/tag/1.0.0) around june 2021.
|
||||
|
||||
## Files included in the release note
|
||||
## Files included in the release notes
|
||||
|
||||
### Standalone firmware
|
||||
This firmware is standalone, meaning that it does not need a bootloader to actually run. It is intended to be flash at offset 0, meaning it will erase any bootloader that might be present in memory.
|
||||
This firmware is standalone, meaning that it does not need a bootloader to actually run. It is intended to be flashed at offset 0, meaning it will erase any bootloader that might be present in memory.
|
||||
|
||||
- **pinetime-app.out** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
|
||||
- **pinetime-app.out** : Output file of GCC containing debug symbols, useful if you want to debug the firmware using GDB.
|
||||
- **pinetime-app.hex** : Firmware in Intel HEX file format. Easier to use because it contains the offset in memory where it must be flashed, you don't need to specify it.
|
||||
- **pintime-app.bin** : Firmware in binary format. When programming it, you have to specify the offset (0x00) in memory where it must be flashed.
|
||||
- **pinetime-app.map** : Map file containing all the symbols, addresses in memory,...
|
||||
@ -38,7 +38,7 @@ This firmware is a small utility firmware that writes the boot graphic in the ex
|
||||
### Firmware with bootloader
|
||||
This firmware is intended to be used with our [MCUBoot-based bootloader](../bootloader/README.md).
|
||||
|
||||
- **pinetime-mcuboot-app-image.hex** : Firmware wrapped into an MCUBoot image. This is **the** file that must be flashed **@ 0x8000** into flash memory. If the [bootloader](../bootloader/README.md) has been successfully programmed, it should run this firmware after the next reset.
|
||||
- **pinetime-mcuboot-app-image.hex**: Firmware wrapped into an MCUBoot image. This is **the** file that must be flashed at **0x8000** into the flash memory. If the [bootloader](../bootloader/README.md) has been successfully programmed, it should run this firmware after the next reset.
|
||||
|
||||
The following files are not directly usable by the bootloader:
|
||||
|
||||
|
26
doc/gettingStarted/about-software.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Firmware, InfiniTime, Bootloader, Recovery firmware, OTA, DFU... What is it?
|
||||
|
||||
You may have already encountered these words by reading the announcement, release notes, or [the wiki guide](https://wiki.pine64.org/wiki/Upgrade_PineTime_to_InfiniTime_1.0.0) and you may find them confusing if you're not familiar with the project.
|
||||
|
||||
A **firmware** is software running on the embedded hardware of a device.
|
||||
|
||||
InfiniTime has three distinct firmwares:
|
||||
|
||||
- **[InfiniTime](https://github.com/InfiniTimeOrg/InfiniTime)** is the operating system.
|
||||
- **[The bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader)** is responsible for safely applying firmware updates and runs before booting into InfiniTime.
|
||||
- **The recovery firmware** is a special *application firmware* than can be loaded by the bootloader on user request. This firmware can be useful in case of serious issue, when the main application firmware cannot perform an OTA update correctly.
|
||||
|
||||
**OTA** (**O**ver **T**he **A**ir) refers to updating of the firmware over BLE (**B**luetooth **L**ow **E**nergy). This is a functionality that allows the user to update the firmware on their device wirelessly.
|
||||
|
||||
**DFU** (**D**evice **F**irmware **U**pdate) is the file format and protocol used to send the update of the firmware to the watch over-the-air. InfiniTime implements the (legacy) DFU protocol from Nordic Semiconductor (NRF).
|
||||
|
||||
## Bootloader
|
||||
|
||||
Most of the time, the bootloader just runs without your intervention (updating and loading the firmware).
|
||||
|
||||
However, you can use the bootloader to rollback to the previous firmware, or load the recovery firmware using the push button:
|
||||
|
||||
- Press and hold the button until the pine cone is drawn in **blue** to force the rollback of the previous version of the firmware, even if you've already validated the current one.
|
||||
- Press and hold the button until the pine cone is drawn in **red** to load the recovery firmware. This recovery firmware only provides BLE connectivity and OTA functionality.
|
||||
|
||||
More info about the bootloader in [its project page](https://github.com/JF002/pinetime-mcuboot-bootloader/blob/master/README.md).
|
Before Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 72 KiB |
@ -1,112 +1,57 @@
|
||||
# Getting started with InfiniTime 1.0
|
||||
On April 22 2021, InfiniTime and Pine64 [announced the release of InfiniTime 1.0](https://www.pine64.org/2021/04/22/its-time-infinitime-1-0/) and the availability of PineTime smartwatches as *enthusiast grade end-user product*. This page aims to guide you with your first step with your new PineTime.
|
||||
# Getting started with InfiniTime
|
||||
|
||||
## Firmware, InfiniTime, Bootloader, Recovery firmware, OTA, DFU... What is it?
|
||||
You might have already seen these words by reading the announcement, release notes, or [the wiki guide](https://wiki.pine64.org/wiki/Upgrade_PineTime_to_InfiniTime_1.0.0) and, you may find them misleading if you're not familiar with the project.
|
||||
On April 22 2021, InfiniTime and Pine64 [announced the release of InfiniTime 1.0.0](https://www.pine64.org/2021/04/22/its-time-infinitime-1-0/) and the availability of PineTime smartwatches as an *enthusiast grade end-user product*. This page aims to guide you with your first step with your new PineTime.
|
||||
|
||||
Basically, a **firmware** is just a software running on the embedded hardware of a device, the PineTime in this case.
|
||||
**InfiniTime** is based on 3 distinct **firmwares**:
|
||||
- **[InfiniTime](https://github.com/JF002/InfiniTime)** itself, this is the *application firmware* running on the PineTime. This is the main firmware which provides most of the functionalities you'll use on a daily basis : bluetooth low-energy (BLE) connectivity, applications, watchfaces,...
|
||||
- **[The bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader)** is responsible for safely applying **updates** of the *application firmware*, reverting them in case of issues and load the recovery firmware when requested.
|
||||
- **The recovery firmware** is a specific *application firmware* than can be loaded by the bootloader on user request. This firmware can be useful in case of serious issue, when the main application firmware cannot perform an OTA update correctly. Currently, this recovery firmware is based on [InfiniTime 0.14.1](https://github.com/JF002/InfiniTime/releases/tag/0.14.1).
|
||||
It is highly recommended to update the firmware to the latest version when you receive your watch and when a new InfiniTime version is released. More information on updating the firmware [here](/doc/gettingStarted/updating-software.md).
|
||||
|
||||
**OTA** and **DFU** refer to the update of the firmware over BLE (**B**luetooth **L**ow **E**nergy). **OTA** means **O**ver **T**he **A**ir, this is a functionality that allows the user to update the firmware how their device using a wireless communication like BLE. When we talk about **DFU** (**D**igital **F**irmware **U**pdate), we refer to the file format and protocol used to send the update of the firmware to the watch over-the-air. InfiniTime implement the (legacy) DFU protocol from Nordic Semiconductor (NRF).
|
||||
## InfiniTime quick user guide
|
||||
|
||||
## How to check the version of InfiniTime and the bootloader?
|
||||
Since September 2020, all PineTimes (devkits or sealed) are flashed using the **[first iteration of the bootloader](https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.7)** and **[InfiniTime 0.7.1](https://github.com/JF002/InfiniTime/releases/tag/0.7.1)**. There was no recovery firmware at that time.
|
||||
|
||||
The bootloader only runs when the watch starts (from an empty battery, for example) or after a reset (after a succesful OTA or a manual reset - long push on the button).
|
||||
|
||||
You can recognize this first iteration of the bootloader with it greenish **PINETIME** logo.
|
||||
|
||||
![Old bootloader logo](oldbootloaderlogo.jpg)
|
||||
|
||||
You can check the version of InfiniTime by opening the app *SystemInfo*. For version < 1.0:
|
||||
|
||||
![InfiniTime 0.7.1 Application menu](appmenu-071.jpg)
|
||||
![InfiniTime 0.7.1 version](version-071.jpg)
|
||||
|
||||
And for version >= 1.0 :
|
||||
|
||||
![InfiniTime 1.0 version](version-1.0.jpg)
|
||||
|
||||
|
||||
PineTime shipped from June 2020 (to be confirmed) will be flashed with the [new version of the bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader/releases/tag/1.0.0), the [recovery firmware](https://github.com/JF002/InfiniTime/releases/tag/0.14.1) and [InfiniTime 1.0](https://github.com/JF002/InfiniTime/releases/tag/1.0.0).
|
||||
|
||||
The bootloader is easily recognizable with it white pine cone that is progressively drawn in green. It also displays its own version on the bottom (1.0.0 as of now).
|
||||
|
||||
![Bootloader 1.0](bootloader-1.0.jpg)
|
||||
|
||||
## How to update your PineTime?
|
||||
To update your PineTime, you can use one of the compatible companion applications. Here are the main ones:
|
||||
|
||||
- **[Amazfish](https://github.com/piggz/harbour-amazfish)** (Desktop Linux, mobile Linux, SailfishOS, runs on the PinebookPro and the Pinephone)
|
||||
- **[Gadgetbridge](https://www.gadgetbridge.org/)** (Android)
|
||||
- **[Siglo](https://github.com/alexr4535/siglo)** (Linux, GTK based)
|
||||
- **NRFConnect** (closed source, Android & iOS).
|
||||
|
||||
See [this page](ota-gadgetbridge-nrfconnect.md) for more info about the OTA procedure using Gadgetbrige and NRFCOnnect.
|
||||
|
||||
### From InfiniTime 0.7.1 / old bootloader
|
||||
If your PineTime is currently running InfiniTime 0.7.1 and the old bootloader, we strongly recommend you update them to more recent version (Bootloader 1.0.0 and InfiniTime 1.0.0 as of now). We also recommend you install the recovery firmware once the bootloader is up-do-date.
|
||||
|
||||
Using the companion app of your choice, you'll need to apply the OTA procedure for these 3 firmwares in this sequence (failing to follow this specific order might temporarily or permanently brick your device):
|
||||
|
||||
1. Flash the latest version of InfiniTime. The file to upload is named **pinetime-mcuboot-app-dfu-x.y.z.zip**. Here is the link to [InfiniTime 1.0](https://github.com/JF002/InfiniTime/releases/download/1.0.0/pinetime-mcuboot-app-dfu-1.0.0.zip).
|
||||
2. Update the bootloader by applying the OTA procedure with the file named [**reloader-mcuboot.zip** from the repo of the bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader/releases/download/1.0.0/reloader-mcuboot.zip).
|
||||
3. Install the recovery firmware by applying the OTA procedure with the file named [**pinetime-mcuboot-recovery-loader-dfu-0.14.1.zip** from the version 0.14.1 of InfiniTime](https://github.com/JF002/InfiniTime/releases/download/0.14.1/pinetime-mcuboot-recovery-loader-dfu-0.14.1.zip).
|
||||
|
||||
You'll find more info about this process in [this wiki page](https://wiki.pine64.org/wiki/Upgrade_PineTime_to_InfiniTime_1.0.0). You can also see the procedure in video [here](https://video.codingfield.com/videos/watch/831077c5-16f3-47b4-9b2b-c4bbfecc6529) and [here (from Amazfish)](https://video.codingfield.com/videos/watch/f7bffb3d-a6a1-43c4-8f01-f4aeff4adf9e)
|
||||
|
||||
### From version > 1.0
|
||||
If you are already running the new "1.0.0" bootloader, all you have to do is update your version of InfiniTime when it'll be available. We'll write specific instructions when (if) we release a new version of the bootloader.
|
||||
|
||||
### Firmware validation
|
||||
The bootloader requires a (manual) validation of the firmware. If the watch reset with an updated firmware that was not validated, the bootloader will consider it as non-functionning and will revert to the previous version of the firmware. This is a safety feature to prevent bricking your device with a faulty firmware.
|
||||
|
||||
You can validate your updated firmware on InfiniTime >= 1.0 by following this simple procedure:
|
||||
|
||||
- From the watchface, swipe **right** to display the *Quick Actions menu*
|
||||
- Open the **Settings** app by tapping the *gear* icon on the bottom right
|
||||
- Swipe down and tap on the entry named **Firmware**
|
||||
- This app shows the version that is currently running. If it's not validated yet, it displays 2 buttons:
|
||||
- **Validate** to validate your firmware
|
||||
- **Reset** to reset the watch and revert to the previously running version of the firmware
|
||||
|
||||
## InfiniTime 1.0 quick user guide
|
||||
### Setting the time
|
||||
By default, InfiniTime starts on the digital watchface. It'll probably display the epoch time (1 Jan 1970, 00:00). The time will be automatically synchronized once you connect on of the companion app to your PineTime using BLE connectivity. InfiniTime does not provide any way to manually set the time for now.
|
||||
|
||||
By default, InfiniTime starts on the digital watchface. It'll probably display the epoch time (1 Jan 1970, 00:00).
|
||||
|
||||
You can sync the time using companion apps.
|
||||
|
||||
- Gadgetbridge automatically synchronizes the time when you connect it to your watch. More information on Gadgetbridge [here](/doc/gettingStarted/ota-gadgetbridge.md)
|
||||
- [Sync the time with NRFConnect](/doc/gettingStarted/time-nrfconnect.md)
|
||||
- Sync the time with your browser https://hubmartin.github.io/WebBLEWatch/
|
||||
|
||||
You can also set the time in the settings without a companion app. (version >1.7.0)
|
||||
|
||||
InfiniTime doesn't handle daylight savings automatically, so make sure to set the correct time or sync it with a companion app.
|
||||
|
||||
### Digital watch face
|
||||
|
||||
![Digital watch face](ui/watchface.jpg)
|
||||
|
||||
This is what the default digital watch face looks like. You can change watch faces in the settings.
|
||||
|
||||
The indicator on the top left is visible if you have unread notifications
|
||||
|
||||
On the top right there are status icons
|
||||
|
||||
- The battery icon shows roughly how much charge is remaining
|
||||
- The Bluetooth icon is visible when the watch is connected to a companion app
|
||||
- A plug icon is shown when the watch is plugged into a charger.
|
||||
|
||||
On the bottom left you can see your heart rate if you have the measurement enabled in the heart rate app.
|
||||
|
||||
On the bottom right you can see how many steps you have taken today.
|
||||
|
||||
### Navigation in the menu
|
||||
|
||||
![Quick actions](quickactions.jpg)
|
||||
![Settings](settings.jpg)
|
||||
![Application menu](appmenu.jpg)
|
||||
![Application menu](ui/applist.jpg)
|
||||
![Notifications](ui/notifications.jpg)
|
||||
![Quick actions](ui/quicksettings.jpg)
|
||||
![Settings](ui/settings.jpg)
|
||||
|
||||
- Swipe **down** to display the notification panel. Notification sent by your companion app will be displayed in this panel.
|
||||
- Swipe **up** to display the application menus. Apps (stopwatch, music, step, games,...) can be started from this menu.
|
||||
- Swipe **down** to display the notification panel. Notification sent by your companion app will be displayed here.
|
||||
- Swipe **right** to display the Quick Actions menu. This menu allows you to
|
||||
- Set the brightness of the display
|
||||
- Start the **flashlight** app
|
||||
- Enable/disable vibrations on notifications (Do Not Disturb mode)
|
||||
- Enable/disable notifications (Do Not Disturb mode)
|
||||
- Enter the **settings** menu
|
||||
- Settings
|
||||
- Display timeout
|
||||
- Wake up event (Tap, wrist rotation)
|
||||
- Time format (12/24H)
|
||||
- Default watchface (digital / analog)
|
||||
- Battery info
|
||||
- Firmware validation
|
||||
- About (system info, firmware version,...)
|
||||
|
||||
### Bootloader
|
||||
|
||||
Most of the time, the bootloader just runs without your intervention (update and load the firmware).
|
||||
|
||||
However, you can enable 2 functionalities using the push button:
|
||||
|
||||
- Push the button until the pine cone is drawn in **blue** to force the rollback of the previous version of the firmware, even if you've already validated the updated one
|
||||
- Push the button until the pine cone is drawn in **red** to load the recovery firmware. This recovery firmware only provides BLE connectivity and OTA functionality.
|
||||
|
||||
More info about the bootloader in [its project page](https://github.com/JF002/pinetime-mcuboot-bootloader/blob/master/README.md).
|
||||
|
||||
- Swipe up and down to see all options
|
||||
- Click the button to go back a screen.
|
||||
- You can hold the button for a short time to return to the watch face. (version >1.7.0)
|
||||
|
Before Width: | Height: | Size: 114 KiB |
@ -1,101 +0,0 @@
|
||||
# Flash and upgrade InfiniTime
|
||||
If you just want to flash or upgrade InfiniTime on your PineTime, this page is for you!
|
||||
|
||||
- [InfiniTime releases and versions](#infinitime-releases-and-versions)
|
||||
- [How to upgrade Over-The-Air (OTA)](#how-to-upgrade-over-the-air-ota)
|
||||
- [Using Gadgetbridge](#using-gadgetbridge)
|
||||
- [Using NRFConnect](#Using-nrfconnect)
|
||||
- [How to flash InfiniTime using the SWD interface](#how-to-flash-infinitime-using-the-swd-interface)
|
||||
|
||||
## InfiniTime releases and versions
|
||||
All releases of InfiniTime are available on the [release page of the GitHub repo](https://github.com/JF002/InfiniTime/releases).
|
||||
|
||||
Versions that are tagged as **RELEASE CANDIDATE** are pre-release versions, that are available for testing before actually releasing a new stable version. If you want to help us debug the project and provide stable versions to other user, you can use them. If you want stable and tested version, you should not flash these release candidate version.
|
||||
|
||||
Release files are available under the *Assets* button.
|
||||
|
||||
## How to upgrade Over-The-Air (OTA)
|
||||
OTA is the easiest method to upgrade InfiniTime. Note that it's only possible is your PineTime is already running InfiniTime (>= 0.7.1).
|
||||
|
||||
2 companion apps provide support for OTA :
|
||||
- [Gadgetbridge](https://gadgetbridge.org/) (open source, runs on Android, [available on F-Droid](https://f-droid.org/packages/nodomain.freeyourgadget.gadgetbridge/)).
|
||||
- [NRFConnect](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Connect-for-mobile) (close source, runs on Android and iOS).
|
||||
|
||||
Both applications need you to download the **DFU file** of InfiniTime. This file contains the new version of InfiniTime that will be flashed into your device. It's called **dfu-x.y.z.zip** (ex: dfu-0.9.0.zip) in the release note.
|
||||
![Dfu file](dfuFile.png )
|
||||
|
||||
### Using Gadgetbridge
|
||||
Launch Gadgetbridge and tap on the **"+"** button on the bottom right to add a new device:
|
||||
|
||||
![Gadgetbridge 0](gadgetbridge0.jpg)
|
||||
|
||||
Wait for the scan to complete, your PineTime should be detected:
|
||||
|
||||
![Gadgetbridge 1](gadgetbridge1.jpg)
|
||||
|
||||
Tap on it. Gadgdetbridge will pair and connect to your device:
|
||||
|
||||
![Gadgetbridge 2](gadgetbridge2.jpg)
|
||||
|
||||
Now that Gadgetbridge is connected to your PineTime, use a file browser application (I'm using Seafile to browse my NAS) and browse to the DFU file (image-xxx.zip) you downloaded previously. Tap on it and open it using the Gadgetbridge application/firmware installer:
|
||||
|
||||
![Gadgetbridge 3](gadgetbridge3.jpg)
|
||||
|
||||
Read carefully the warning and tap **Install**:
|
||||
|
||||
![Gadgetbridge 4](gadgetbridge4.jpg)
|
||||
|
||||
Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime!
|
||||
|
||||
![Gadgetbridge 5](gadgetbridge5.jpg)
|
||||
|
||||
### Using NRFConnect
|
||||
Open NRFConnect. Swipe down in the *Scanner* tab and wait for your device to appear:
|
||||
|
||||
![NRFConnect 0](nrfconnect0.jpg)
|
||||
|
||||
Tap on the *Connect* button on the right of your device. NRFConnect will connect to your PineTime and discover its characteristics. Tap on the **DFU** button on the top right:
|
||||
|
||||
![NRFConnect 1](nrfconnect1.jpg)
|
||||
|
||||
Select **Distribution packet (ZIP)**:
|
||||
|
||||
![NRFConnect 2](nrfconnect2.jpg)
|
||||
|
||||
Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime!
|
||||
|
||||
![NRFConnect 3](nrfconnect3.jpg)
|
||||
|
||||
## How to flash InfiniTime using the SWD interface
|
||||
Download the files **bootloader.bin**, **image-x.y.z.bin** and **pinetime-graphics-x.y.z.bin** from the release page:
|
||||
|
||||
![Image file](imageFile.png )
|
||||
|
||||
The bootloader reads a boot logo from the external SPI flash memory. The first step consists in flashing a tool in the MCU that will flash the boot logo into this SPI flash memory. This first step is optional but recommanded (the bootloader will display garbage on screen for a few second if you don't do it).
|
||||
Using your SWD tool, flash **pinetime-graphics-x.y.z.bin** at offset **0x0000**. Reset the MCU and wait for a few second, until the logo is completely drawn on the display.
|
||||
|
||||
Then, using your SWD tool, flash those file at specific offset:
|
||||
|
||||
- bootloader.bin : **0x0000**
|
||||
- image-x.y.z.bin : **0x8000**
|
||||
|
||||
Reset and voilà, you're running InfiniTime on your PineTime!
|
||||
|
||||
If you are using OpenOCD with a STLinkV2, you can find more info [on this page](../openOCD.md).
|
||||
|
||||
## How to synchronize the time
|
||||
|
||||
### Using Gadgetbridge
|
||||
Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime!
|
||||
|
||||
### Using NRFConnect
|
||||
You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone.
|
||||
|
||||
Launch NRFConnect, tap the sandwich button on the top left and select *Configure GATT server*:
|
||||
|
||||
![NRFConnect CTS 0](nrfconnectcts0.jpg)
|
||||
|
||||
|
||||
Tap *Add service* and select the server configuration *Current Time service*. Tap OK and connect to your PineTime, it should automcatically sync the time once the connection is established!
|
||||
|
||||
![NRFConnect CTS 1](nrfconnectcts1.jpg)
|
29
doc/gettingStarted/ota-gadgetbridge.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Connecting to Gadgetbridge
|
||||
|
||||
Launch Gadgetbridge and tap on the **"+"** button on the bottom right to add a new device:
|
||||
|
||||
![Gadgetbridge 0](gadgetbridge0.jpg)
|
||||
|
||||
Wait for the scan to complete, your PineTime should be detected:
|
||||
|
||||
![Gadgetbridge 1](gadgetbridge1.jpg)
|
||||
|
||||
Tap on it. Gadgdetbridge will pair and connect to your device:
|
||||
|
||||
![Gadgetbridge 2](gadgetbridge2.jpg)
|
||||
|
||||
# Updating with Gadgetbridge
|
||||
|
||||
Now that Gadgetbridge is connected to your PineTime, use a file browser application and find the DFU file (`pinetime-mcuboot-app-dfu-x.x.x.zip`) you downloaded previously. Tap on it and open it using the Gadgetbridge application/firmware installer:
|
||||
|
||||
![Gadgetbridge 3](gadgetbridge3.jpg)
|
||||
|
||||
Read the warning carefully and tap **Install**:
|
||||
|
||||
![Gadgetbridge 4](gadgetbridge4.jpg)
|
||||
|
||||
Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime!
|
||||
|
||||
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used.
|
||||
|
||||
![Gadgetbridge 5](gadgetbridge5.jpg)
|
22
doc/gettingStarted/ota-nrfconnect.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Updating with NRFConnect
|
||||
|
||||
Open NRFConnect. Swipe down in the *Scanner* tab and wait for your device to appear:
|
||||
|
||||
![NRFConnect 0](nrfconnect0.jpg)
|
||||
|
||||
Tap on the *Connect* button on the right of your device. NRFConnect will connect to your PineTime and discover its characteristics. Tap on the **DFU** button on the top right:
|
||||
|
||||
![NRFConnect 1](nrfconnect1.jpg)
|
||||
|
||||
Select **Distribution packet (ZIP)**:
|
||||
|
||||
![NRFConnect 2](nrfconnect2.jpg)
|
||||
|
||||
Find the DFU file (`pinetime-mcuboot-app-dfu-x.x.x.zip`) you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime!
|
||||
|
||||
Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used.
|
||||
|
||||
![NRFConnect 3](nrfconnect3.jpg)
|
||||
|
||||
# Demo
|
||||
[This video](https://seafile.codingfield.com/f/a52b69683a05472a90c7/) shows how to use NRFConnect to update the firmware running on the Pinetime.
|
Before Width: | Height: | Size: 112 KiB |
Before Width: | Height: | Size: 127 KiB |
11
doc/gettingStarted/time-nrfconnect.md
Normal file
@ -0,0 +1,11 @@
|
||||
### Syncing time
|
||||
|
||||
You must enable the **CTS** *GATT server* in NRFConnect so that InfiniTime can synchronize the time with your smartphone.
|
||||
|
||||
Launch NRFConnect, tap the sandwich button on the top left and select *Configure GATT server*:
|
||||
|
||||
![NRFConnect CTS 0](nrfconnectcts0.jpg)
|
||||
|
||||
Tap *Add service* and select the server configuration *Current Time service*. Tap OK and connect to your PineTime, it should automcatically sync the time once the connection is established!
|
||||
|
||||
![NRFConnect CTS 1](nrfconnectcts1.jpg)
|
BIN
doc/gettingStarted/ui/applist.jpg
Normal file
After Width: | Height: | Size: 130 KiB |
BIN
doc/gettingStarted/ui/notifications.jpg
Normal file
After Width: | Height: | Size: 182 KiB |
BIN
doc/gettingStarted/ui/quicksettings.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
doc/gettingStarted/ui/settings.jpg
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
doc/gettingStarted/ui/watchface.jpg
Normal file
After Width: | Height: | Size: 101 KiB |
41
doc/gettingStarted/updating-software.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Updating InfiniTime
|
||||
|
||||
If you just want to flash or upgrade InfiniTime on your PineTime, this page is for you! If you want more information about the software and the update procedure, check out [this](/doc/gettingStarted/about-software.md) page.
|
||||
|
||||
## Checking the version of InfiniTime
|
||||
|
||||
You can check the InfiniTime version by first swiping right on the watchface to open quick settings, tapping the cogwheel to open settings, swipe up until you find an entry named "About" and tap on it.
|
||||
|
||||
![InfiniTime 1.0 version](version-1.0.jpg)
|
||||
|
||||
PineTimes shipped after June 2021 will ship with the latest version of [the bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader/releases/tag/1.0.0) and [recovery firmware](https://github.com/InfiniTimeOrg/InfiniTime/releases/tag/0.14.1)
|
||||
|
||||
The bootloader is run right before booting into InfiniTime. It is easily recognizable with its white pine cone that is progressively drawn in green. It also displays its own version on the bottom (1.0.0 as of now).
|
||||
|
||||
![Bootloader 1.0](bootloader-1.0.jpg)
|
||||
|
||||
## Updating with companion apps
|
||||
|
||||
To update your PineTime, you can use one of the [compatible companion applications](/README.md#companion-apps).
|
||||
|
||||
The updating process differs slightly on every companion app, so you'll need to familiarize yourself with the companion app of your choice.
|
||||
|
||||
All releases of InfiniTime are available on the [release page of the GitHub repo](https://github.com/InfiniTimeOrg/InfiniTime/releases) under assets.
|
||||
|
||||
To update the firmware, you need to download the DFU of the firmware version that you'd like to install, for example `pinetime-mcuboot-app-dfu-1.6.0.zip`, and flash it with your companion app.
|
||||
|
||||
We have prepared instructions for flashing InfiniTime with Gadgetbridge and NRFConnect.
|
||||
|
||||
- [Updating with Gadgetbridge](/doc/gettingStarted/ota-gadgetbridge.md)
|
||||
- [Updating with NRFConnect](/doc/gettingStarted/ota-nrfconnect.md)
|
||||
|
||||
## Firmware validation
|
||||
|
||||
Firmware updates must be manually validated. If the firmware isn't validated and the watch resets, the watch will revert to the previous firmware. This is a safety feature to prevent bricking your device with faulty firmware.
|
||||
|
||||
You can validate your updated firmware on InfiniTime >= 1.0 by following this simple procedure:
|
||||
|
||||
- From the watchface, swipe **right** to display the *quick settings menu*
|
||||
- Open settings by tapping the cogwheel on the bottom right
|
||||
- Swipe up until you find an entry named **Firmware** and tap on it
|
||||
- If the firmware is not validated yet, you can either validate the running firmware, or reset and revert to the previous firmware version
|
Before Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 55 KiB |
BIN
doc/memoryAnalysis/linkermapviz.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
doc/memoryAnalysis/mapfile.png
Normal file
After Width: | Height: | Size: 109 KiB |
BIN
doc/memoryAnalysis/puncover-all-symbols.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
doc/memoryAnalysis/puncover.png
Normal file
After Width: | Height: | Size: 212 KiB |
@ -1,12 +1,12 @@
|
||||
# OpenOCD and STLink
|
||||
OpenOCD (**Open O**n **C**hip **D**ebugger) is an open source tool that interfaces with many SWD/JTAG debugger to provide debugging and *in-system* programming for embedded target devices.
|
||||
|
||||
It supports the **NRF52** (the CPU of the PineTime) and the **STLinkV2**, a cheap SWD debugger.
|
||||
OpenOCD supports the **NRF52** (the CPU of the PineTime) and the **STLinkV2**, a cheap SWD debugger.
|
||||
|
||||
It works on X86 computers, as well as ARM/ARM64 computers and SBC (like the RaspberryPi and Pine64 Pinebook Pro) !
|
||||
OpenOCD works on X86 computers, ARM/ARM64 computers, and SBCs (like the RaspberryPi and Pine64 Pinebook Pro)!
|
||||
|
||||
## Installation
|
||||
We will build OpenOCD from sources, as packages from Linux distributions are most of the time outdated and do not support the NRF52 correctly.
|
||||
We will build OpenOCD from sources, as packages from Linux distributions are most of the time outdated and do not support the NRF52 properly.
|
||||
|
||||
- Fetch the sources from GIT, and build and install it:
|
||||
|
||||
@ -27,7 +27,7 @@ sudo cp contrib/60-openocd.rules /etc/udev/rules.d/
|
||||
sudo udevadm control --reload-rules
|
||||
```
|
||||
|
||||
- You can now plug your STLinkV2 in a USB port and run OpenOCD to see if it's working correctly:
|
||||
- You can now plug your STLinkV2 into a USB port and run OpenOCD to see if it's working correctly:
|
||||
|
||||
```
|
||||
$ openocd -f interface/stlink.cfg -f target/nrf52.cfg
|
||||
@ -63,7 +63,7 @@ gdb_breakpoint_override hard
|
||||
|
||||
source [find target/nrf52.cfg]
|
||||
```
|
||||
This file specifies to OpenOCD which debugger and target it will be connected to..
|
||||
This file specifies to OpenOCD which debugger and target it will be connected to.
|
||||
|
||||
Then, we use various *user files* to use OpenOCD to flash InfiniTime binary files.
|
||||
|
||||
|
BIN
doc/ui/example.png
Normal file
After Width: | Height: | Size: 10 KiB |
14
doc/ui_guidelines.md
Normal file
@ -0,0 +1,14 @@
|
||||
# UI design guidelines
|
||||
|
||||
- Align objects all the way to the edge or corner
|
||||
- Buttons should generally be at least 50px high
|
||||
- Buttons should generally be on the bottom edge
|
||||
- Make interactable objects **big**
|
||||
- When using a page indicator, leave 8px for it on the right side
|
||||
- It is acceptable to leave 8px on the left side as well to center the content
|
||||
- Top bar takes at least 20px + padding
|
||||
- Top bar right icons move 8px to the left when using a page indicator
|
||||
- A black background helps to hide the screen border, allowing the UI to look less cramped when utilizing the entire display area.
|
||||
- A switch should be twice as wide as it is tall.
|
||||
|
||||
![example layouts](./ui/example.png)
|
@ -1,6 +1,6 @@
|
||||
# Versioning
|
||||
The versioning of this project is based on [Semantic versionning](https://semver.org/) :
|
||||
The versioning of this project is based on [Semantic versioning](https://semver.org/):
|
||||
|
||||
- The **patch** is incremented when we fix a bug on a **released** version (most of the time using a **hotfix** branch).
|
||||
- The **minor** is incremented when we release a new version with new features. It corresponds to a merge of **develop** into **master**.
|
||||
- The **major** should be incremented when a breaking change is made to the application. We still have to define what is a breaking change in the context of this project. For now, I suggest that it stays **0** until we have a fully functionning firmware suited for the final user.
|
||||
- The **patch** is incremented when a bug is fixed on a **released** version (most of the time using a **hotfix** branch).
|
||||
- The **minor** is incremented when a new version with new features is released. It corresponds to a merge of **develop** into **master**.
|
||||
- The **major** should be incremented when a breaking change is made to the application. We still have to define what is a breaking change in the context of this project.
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:18.04
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update -qq \
|
||||
@ -11,21 +11,27 @@ RUN apt-get update -qq \
|
||||
make \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python-is-python3 \
|
||||
tar \
|
||||
unzip \
|
||||
wget \
|
||||
# aarch64 packages
|
||||
curl \
|
||||
# aarch64 packages
|
||||
libffi-dev \
|
||||
libssl-dev \
|
||||
python3-dev \
|
||||
python \
|
||||
git \
|
||||
apt-utils \
|
||||
&& curl -sL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/*;
|
||||
|
||||
# Git needed for PROJECT_GIT_COMMIT_HASH variable setting
|
||||
|
||||
RUN pip3 install adafruit-nrfutil
|
||||
RUN pip3 install -Iv cryptography==3.3
|
||||
RUN pip3 install cbor
|
||||
RUN npm i lv_font_conv@1.5.2 -g
|
||||
|
||||
# build.sh knows how to compile
|
||||
COPY build.sh /opt/
|
||||
@ -38,10 +44,5 @@ RUN bash -c "source /opt/build.sh; GetNrfSdk;"
|
||||
# McuBoot
|
||||
RUN bash -c "source /opt/build.sh; GetMcuBoot;"
|
||||
|
||||
ARG PUID=1000
|
||||
ARG PGID=1000
|
||||
RUN groupadd --system --gid $PGID infinitime && useradd --system --uid $PUID --gid $PGID infinitime
|
||||
|
||||
USER infinitime:infinitime
|
||||
ENV SOURCES_DIR /sources
|
||||
CMD ["/opt/build.sh"]
|
||||
|
@ -9,21 +9,23 @@ set -e
|
||||
export TOOLS_DIR="${TOOLS_DIR:=/opt}"
|
||||
export SOURCES_DIR="${SOURCES_DIR:=/sources}"
|
||||
export BUILD_DIR="${BUILD_DIR:=$SOURCES_DIR/build}"
|
||||
export OUTPUT_DIR="${OUTPUT_DIR:=$BUILD_DIR/output}"
|
||||
export OUTPUT_DIR="${OUTPUT_DIR:=$SOURCES_DIR/build/output}"
|
||||
|
||||
export BUILD_TYPE=${BUILD_TYPE:=Release}
|
||||
export GCC_ARM_VER=${GCC_ARM_VER:="gcc-arm-none-eabi-9-2020-q2-update"}
|
||||
export GCC_ARM_VER=${GCC_ARM_VER:="11.2-2022.02"}
|
||||
export NRF_SDK_VER=${NRF_SDK_VER:="nRF5_SDK_15.3.0_59ac345"}
|
||||
|
||||
MACHINE="$(uname -m)"
|
||||
[[ "$MACHINE" == "arm64" ]] && MACHINE="aarch64"
|
||||
|
||||
export GCC_ARM_PATH="gcc-arm-$GCC_ARM_VER-$MACHINE-arm-none-eabi"
|
||||
|
||||
main() {
|
||||
local target="$1"
|
||||
|
||||
mkdir -p "$TOOLS_DIR"
|
||||
|
||||
[[ ! -d "$TOOLS_DIR/$GCC_ARM_VER" ]] && GetGcc
|
||||
[[ ! -d "$TOOLS_DIR/$GCC_ARM_PATH" ]] && GetGcc
|
||||
[[ ! -d "$TOOLS_DIR/$NRF_SDK_VER" ]] && GetNrfSdk
|
||||
[[ ! -d "$TOOLS_DIR/mcuboot" ]] && GetMcuBoot
|
||||
|
||||
@ -38,12 +40,11 @@ main() {
|
||||
}
|
||||
|
||||
GetGcc() {
|
||||
GCC_SRC="$GCC_ARM_VER-$MACHINE-linux.tar.bz"
|
||||
wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/$GCC_SRC -O - | tar -xj -C $TOOLS_DIR/
|
||||
wget -q https://developer.arm.com/-/media/Files/downloads/gnu/$GCC_ARM_VER/binrel/$GCC_ARM_PATH.tar.xz -O - | tar -xJ -C $TOOLS_DIR/
|
||||
}
|
||||
|
||||
GetMcuBoot() {
|
||||
git clone https://github.com/JuulLabs-OSS/mcuboot.git "$TOOLS_DIR/mcuboot"
|
||||
git clone https://github.com/mcu-tools/mcuboot.git "$TOOLS_DIR/mcuboot"
|
||||
pip3 install -r "$TOOLS_DIR/mcuboot/scripts/requirements.txt"
|
||||
}
|
||||
|
||||
@ -54,18 +55,14 @@ GetNrfSdk() {
|
||||
}
|
||||
|
||||
CmakeGenerate() {
|
||||
# We can swap the CD and trailing SOURCES_DIR for -B and -S respectively
|
||||
# once we go to newer CMake (Ubuntu 18.10 gives us CMake 3.10)
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
cmake -G "Unix Makefiles" \
|
||||
-S "$SOURCES_DIR" \
|
||||
-B "$BUILD_DIR" \
|
||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
||||
-DUSE_OPENOCD=1 \
|
||||
-DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_VER" \
|
||||
-DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_PATH" \
|
||||
-DNRF5_SDK_PATH="$TOOLS_DIR/$NRF_SDK_VER" \
|
||||
-DBUILD_DFU=1 \
|
||||
"$SOURCES_DIR"
|
||||
cmake -L -N .
|
||||
-DBUILD_DFU=1
|
||||
}
|
||||
|
||||
CmakeBuild() {
|
||||
|
@ -15,12 +15,10 @@ cp "$BUILD_DIR/src/pinetime-mcuboot-app-dfu-$PROJECT_VERSION.zip" "$OUTPUT_DIR/p
|
||||
cp "$BUILD_DIR/src/pinetime-mcuboot-recovery-loader-image-$PROJECT_VERSION.bin" "$OUTPUT_DIR/pinetime-mcuboot-recovery-loader-image-$PROJECT_VERSION.bin"
|
||||
cp "$BUILD_DIR/src/pinetime-mcuboot-recovery-loader-dfu-$PROJECT_VERSION.zip" "$OUTPUT_DIR/pinetime-mcuboot-recovery-loader-dfu-$PROJECT_VERSION.zip"
|
||||
|
||||
|
||||
mkdir -p "$OUTPUT_DIR/src"
|
||||
cd "$BUILD_DIR"
|
||||
cp src/*.bin "$OUTPUT_DIR/src"
|
||||
cp src/*.hex "$OUTPUT_DIR/src"
|
||||
cp src/*.out "$OUTPUT_DIR/src"
|
||||
cp src/*.map "$OUTPUT_DIR/src"
|
||||
cp $BUILD_DIR/src/*.bin "$OUTPUT_DIR/src/"
|
||||
cp $BUILD_DIR/src/*.hex "$OUTPUT_DIR/src/"
|
||||
cp $BUILD_DIR/src/*.out "$OUTPUT_DIR/src/"
|
||||
cp $BUILD_DIR/src/*.map "$OUTPUT_DIR/src/"
|
||||
|
||||
ls -RUv1 "$OUTPUT_DIR" | sed 's;^\([^/]\); \1;g'
|
@ -6,12 +6,18 @@ GROUP(-lgcc -lc -lnosys)
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08020, LENGTH = 0x78000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
}
|
||||
.noinit(NOLOAD):
|
||||
{
|
||||
PROVIDE(__start_noinit_data = .);
|
||||
*(.noinit)
|
||||
PROVIDE(__stop_noinit_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .bss
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
11
gcc_nrf52.ld
@ -6,12 +6,18 @@ GROUP(-lgcc -lc -lnosys)
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000, LENGTH = 0x78000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
}
|
||||
.noinit(NOLOAD):
|
||||
{
|
||||
PROVIDE(__start_noinit_data = .);
|
||||
*(.noinit)
|
||||
PROVIDE(__stop_noinit_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .bss
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
@ -44,6 +50,7 @@ SECTIONS
|
||||
PROVIDE(__stop_log_filter_data = .);
|
||||
} > RAM
|
||||
|
||||
|
||||
} INSERT AFTER .data;
|
||||
|
||||
SECTIONS
|
||||
|
5
hooks/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Git hooks
|
||||
|
||||
This directory contains Git hooks that simplify contributing to this repository.
|
||||
|
||||
You can install them by copying the files into `.git/hooks` in the repository folder or by running `git config --local core.hooksPath hooks`
|
25
hooks/pre-commit
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
if clang-format --version | grep -q 'version 11\.'; then
|
||||
CLANG_FORMAT_EXECUTABLE="clang-format"
|
||||
else
|
||||
CLANG_FORMAT_EXECUTABLE="clang-format-11"
|
||||
fi
|
||||
|
||||
if ! command -v $CLANG_FORMAT_EXECUTABLE &> /dev/null
|
||||
then
|
||||
echo $CLANG_FORMAT_EXECUTABLE does not exist, make sure to install it
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for FILE in $(git diff --cached --name-only)
|
||||
do
|
||||
if [[ "$FILE" =~ src/[A-Za-z0-9\ \-]+*\.(c|h|cpp|cc)$ ]]; then
|
||||
echo Autoformatting $FILE with $CLANG_FORMAT_EXECUTABLE
|
||||
$CLANG_FORMAT_EXECUTABLE -style=file -i -- $FILE
|
||||
git add -- $FILE
|
||||
elif [[ "$FILE" =~ src/(components|displayapp|drivers|heartratetask|logging|systemtask)/.*\.(c|h|cpp|cc)$ ]]; then
|
||||
echo Autoformatting $FILE with $CLANG_FORMAT_EXECUTABLE
|
||||
$CLANG_FORMAT_EXECUTABLE -style=file -i -- $FILE
|
||||
git add -- $FILE
|
||||
fi
|
||||
done
|
Before Width: | Height: | Size: 37 KiB |
BIN
images/infinitime-logo-small.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
@ -13659,12 +13659,12 @@ POSSIBILITY OF SUCH DAMAGE.\n
|
||||
<usage>read</usage>
|
||||
<enumeratedValue>
|
||||
<name>NotPresent</name>
|
||||
<description>Read: no overrun occured</description>
|
||||
<description>Read: no overrun occurred</description>
|
||||
<value>0</value>
|
||||
</enumeratedValue>
|
||||
<enumeratedValue>
|
||||
<name>Present</name>
|
||||
<description>Read: overrun occured</description>
|
||||
<description>Read: overrun occurred</description>
|
||||
<value>1</value>
|
||||
</enumeratedValue>
|
||||
</enumeratedValues>
|
||||
|
10
src/BootErrors.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace Pinetime {
|
||||
namespace System {
|
||||
enum class BootErrors {
|
||||
None,
|
||||
TouchController,
|
||||
};
|
||||
}
|
||||
}
|
@ -1,26 +1,40 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include "BootloaderVersion.h"
|
||||
|
||||
using namespace Pinetime;
|
||||
|
||||
// NOTE : current bootloader does not export its version to the application firmware.
|
||||
// NOTE : version < 1.0.0 of bootloader does not export its version to the application firmware.
|
||||
|
||||
uint32_t BootloaderVersion::Major() {
|
||||
return 0;
|
||||
uint32_t BootloaderVersion::version = 0;
|
||||
char BootloaderVersion::versionString[BootloaderVersion::VERSION_STR_LEN] = "0.0.0";
|
||||
|
||||
const uint32_t BootloaderVersion::Major() {
|
||||
return (BootloaderVersion::version >> 16u) & 0xff;
|
||||
}
|
||||
|
||||
uint32_t BootloaderVersion::Minor() {
|
||||
return 0;
|
||||
const uint32_t BootloaderVersion::Minor() {
|
||||
return (BootloaderVersion::version >> 8u) & 0xff;
|
||||
}
|
||||
|
||||
uint32_t BootloaderVersion::Patch() {
|
||||
return 0;
|
||||
const uint32_t BootloaderVersion::Patch() {
|
||||
return BootloaderVersion::version & 0xff;
|
||||
}
|
||||
|
||||
const char* BootloaderVersion::VersionString() {
|
||||
return "0.0.0";
|
||||
return BootloaderVersion::versionString;
|
||||
}
|
||||
|
||||
bool BootloaderVersion::IsValid() {
|
||||
return false;
|
||||
const bool BootloaderVersion::IsValid() {
|
||||
return BootloaderVersion::version >= 0x00010000;
|
||||
}
|
||||
|
||||
void BootloaderVersion::SetVersion(uint32_t v) {
|
||||
BootloaderVersion::version = v;
|
||||
snprintf(BootloaderVersion::versionString,
|
||||
BootloaderVersion::VERSION_STR_LEN,
|
||||
"%ld.%ld.%ld",
|
||||
BootloaderVersion::Major(),
|
||||
BootloaderVersion::Minor(),
|
||||
BootloaderVersion::Patch());
|
||||
}
|
||||
|
@ -1,12 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Pinetime {
|
||||
class BootloaderVersion {
|
||||
public:
|
||||
static uint32_t Major();
|
||||
static uint32_t Minor();
|
||||
static uint32_t Patch();
|
||||
static const uint32_t Major();
|
||||
static const uint32_t Minor();
|
||||
static const uint32_t Patch();
|
||||
static const char* VersionString();
|
||||
static bool IsValid();
|
||||
static const bool IsValid();
|
||||
static void SetVersion(uint32_t v);
|
||||
|
||||
private:
|
||||
static uint32_t version;
|
||||
static constexpr size_t VERSION_STR_LEN = 12;
|
||||
static char versionString[VERSION_STR_LEN];
|
||||
};
|
||||
}
|
@ -42,7 +42,6 @@ set(SDK_SOURCE_FILES
|
||||
"${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_gpiote.c"
|
||||
"${NRF5_SDK_PATH}/modules/nrfx/soc/nrfx_atomic.c"
|
||||
"${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_saadc.c"
|
||||
"${NRF5_SDK_PATH}/components/libraries/timer/app_timer.h"
|
||||
|
||||
# FreeRTOS
|
||||
${NRF5_SDK_PATH}/external/freertos/source/croutine.c
|
||||
@ -53,7 +52,6 @@ set(SDK_SOURCE_FILES
|
||||
${NRF5_SDK_PATH}/external/freertos/source/stream_buffer.c
|
||||
${NRF5_SDK_PATH}/external/freertos/source/tasks.c
|
||||
${NRF5_SDK_PATH}/external/freertos/source/timers.c
|
||||
${NRF5_SDK_PATH}/components/libraries/timer/app_timer_freertos.c
|
||||
|
||||
# Libs
|
||||
"${NRF5_SDK_PATH}/components/libraries/atomic/nrf_atomic.c"
|
||||
@ -92,6 +90,9 @@ set(SDK_SOURCE_FILES
|
||||
set(TINYCRYPT_SRC
|
||||
libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c
|
||||
libs/mynewt-nimble/ext/tinycrypt/src/utils.c
|
||||
libs/mynewt-nimble/ext/tinycrypt/src/cmac_mode.c
|
||||
libs/mynewt-nimble/ext/tinycrypt/src/ecc.c
|
||||
libs/mynewt-nimble/ext/tinycrypt/src/ecc_dh.c
|
||||
)
|
||||
|
||||
set(NIMBLE_SRC
|
||||
@ -104,6 +105,10 @@ set(NIMBLE_SRC
|
||||
libs/mynewt-nimble/nimble/host/src/ble_l2cap.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_sc.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_gap.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_gatts.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_gattc.c
|
||||
@ -127,10 +132,6 @@ set(NIMBLE_SRC
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c
|
||||
libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c
|
||||
@ -151,6 +152,7 @@ set(NIMBLE_SRC
|
||||
libs/mynewt-nimble/nimble/controller/src/ble_ll_supp_cmd.c
|
||||
libs/mynewt-nimble/nimble/controller/src/ble_ll_hci_ev.c
|
||||
libs/mynewt-nimble/nimble/controller/src/ble_ll_rfmgmt.c
|
||||
libs/mynewt-nimble/nimble/controller/src/ble_ll_resolv.c
|
||||
libs/mynewt-nimble/porting/nimble/src/os_cputime.c
|
||||
libs/mynewt-nimble/porting/nimble/src/os_cputime_pwr2.c
|
||||
libs/mynewt-nimble/porting/nimble/src/os_mbuf.c
|
||||
@ -166,6 +168,13 @@ set(NIMBLE_SRC
|
||||
libs/mynewt-nimble/nimble/host/util/src/addr.c
|
||||
)
|
||||
|
||||
set(LITTLEFS_SRC
|
||||
libs/littlefs/lfs_util.h
|
||||
libs/littlefs/lfs.h
|
||||
libs/littlefs/lfs_util.c
|
||||
libs/littlefs/lfs.c
|
||||
)
|
||||
|
||||
set(LVGL_SRC
|
||||
libs/lv_conf.h
|
||||
libs/lvgl/lvgl.h
|
||||
@ -235,6 +244,7 @@ set(LVGL_SRC
|
||||
libs/lvgl/src/lv_widgets/lv_cont.h
|
||||
libs/lvgl/src/lv_widgets/lv_cpicker.h
|
||||
libs/lvgl/src/lv_widgets/lv_dropdown.h
|
||||
libs/lvgl/src/lv_widgets/lv_gauge.h
|
||||
libs/lvgl/src/lv_widgets/lv_img.h
|
||||
libs/lvgl/src/lv_widgets/lv_imgbtn.h
|
||||
libs/lvgl/src/lv_widgets/lv_keyboard.h
|
||||
@ -321,6 +331,7 @@ set(LVGL_SRC
|
||||
libs/lvgl/src/lv_widgets/lv_cont.c
|
||||
libs/lvgl/src/lv_widgets/lv_cpicker.c
|
||||
libs/lvgl/src/lv_widgets/lv_dropdown.c
|
||||
libs/lvgl/src/lv_widgets/lv_gauge.c
|
||||
libs/lvgl/src/lv_widgets/lv_img.c
|
||||
libs/lvgl/src/lv_widgets/lv_imgbtn.c
|
||||
libs/lvgl/src/lv_widgets/lv_keyboard.c
|
||||
@ -345,37 +356,17 @@ set(LVGL_SRC
|
||||
libs/lvgl/src/lv_widgets/lv_win.c
|
||||
)
|
||||
|
||||
list(APPEND IMAGE_FILES
|
||||
displayapp/icons/battery/os_battery_error.c
|
||||
displayapp/icons/battery/os_battery_100.c
|
||||
displayapp/icons/battery/os_battery_090.c
|
||||
displayapp/icons/battery/os_battery_080.c
|
||||
displayapp/icons/battery/os_battery_070.c
|
||||
displayapp/icons/battery/os_battery_060.c
|
||||
displayapp/icons/battery/os_battery_050.c
|
||||
displayapp/icons/battery/os_battery_040.c
|
||||
displayapp/icons/battery/os_battery_030.c
|
||||
displayapp/icons/battery/os_battery_020.c
|
||||
displayapp/icons/battery/os_battery_010.c
|
||||
displayapp/icons/battery/os_battery_005.c
|
||||
|
||||
displayapp/icons/battery/os_batterycharging_100.c
|
||||
displayapp/icons/battery/os_batterycharging_090.c
|
||||
displayapp/icons/battery/os_batterycharging_080.c
|
||||
displayapp/icons/battery/os_batterycharging_070.c
|
||||
displayapp/icons/battery/os_batterycharging_060.c
|
||||
displayapp/icons/battery/os_batterycharging_050.c
|
||||
displayapp/icons/battery/os_batterycharging_040.c
|
||||
displayapp/icons/battery/os_batterycharging_030.c
|
||||
displayapp/icons/battery/os_batterycharging_020.c
|
||||
displayapp/icons/battery/os_batterycharging_010.c
|
||||
displayapp/icons/battery/os_batterycharging_005.c
|
||||
|
||||
displayapp/icons/bluetooth/os_bt_connected.c
|
||||
displayapp/icons/bluetooth/os_bt_disconnected.c
|
||||
|
||||
set(QCBOR_SRC
|
||||
libs/QCBOR/src/ieee754.c
|
||||
libs/QCBOR/src/qcbor_decode.c
|
||||
libs/QCBOR/src/qcbor_encode.c
|
||||
libs/QCBOR/src/qcbor_err_to_str.c
|
||||
libs/QCBOR/src/UsefulBuf.c
|
||||
)
|
||||
|
||||
list(APPEND IMAGE_FILES
|
||||
displayapp/icons/battery/batteryicon.c
|
||||
)
|
||||
list(APPEND SOURCE_FILES
|
||||
BootloaderVersion.cpp
|
||||
logging/NrfLogger.cpp
|
||||
@ -383,19 +374,19 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/screens/Screen.cpp
|
||||
displayapp/screens/Clock.cpp
|
||||
displayapp/screens/Tile.cpp
|
||||
displayapp/screens/Meter.cpp
|
||||
displayapp/screens/InfiniPaint.cpp
|
||||
displayapp/screens/Paddle.cpp
|
||||
displayapp/screens/StopWatch.cpp
|
||||
displayapp/screens/BatteryIcon.cpp
|
||||
displayapp/screens/BleIcon.cpp
|
||||
displayapp/screens/NotificationIcon.cpp
|
||||
displayapp/screens/Brightness.cpp
|
||||
displayapp/screens/SystemInfo.cpp
|
||||
displayapp/screens/Label.cpp
|
||||
displayapp/screens/FirmwareUpdate.cpp
|
||||
displayapp/screens/Music.cpp
|
||||
displayapp/screens/Weather.cpp
|
||||
displayapp/screens/Navigation.cpp
|
||||
displayapp/screens/Metronome.cpp
|
||||
displayapp/screens/Motion.cpp
|
||||
displayapp/screens/FirmwareValidation.cpp
|
||||
displayapp/screens/ApplicationList.cpp
|
||||
@ -408,6 +399,13 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/screens/BatteryInfo.cpp
|
||||
displayapp/screens/Steps.cpp
|
||||
displayapp/screens/Timer.cpp
|
||||
displayapp/screens/PassKey.cpp
|
||||
displayapp/screens/Error.cpp
|
||||
displayapp/screens/Alarm.cpp
|
||||
displayapp/screens/Styles.cpp
|
||||
displayapp/screens/Agenda.cpp
|
||||
displayapp/Colors.cpp
|
||||
displayapp/widgets/Counter.cpp
|
||||
|
||||
## Settings
|
||||
displayapp/screens/settings/QuickSettings.cpp
|
||||
@ -417,11 +415,18 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/screens/settings/SettingWakeUp.cpp
|
||||
displayapp/screens/settings/SettingDisplay.cpp
|
||||
displayapp/screens/settings/SettingSteps.cpp
|
||||
displayapp/screens/settings/SettingSetDate.cpp
|
||||
displayapp/screens/settings/SettingSetTime.cpp
|
||||
displayapp/screens/settings/SettingChimes.cpp
|
||||
displayapp/screens/settings/SettingShakeThreshold.cpp
|
||||
displayapp/screens/settings/SettingBluetooth.cpp
|
||||
|
||||
## Watch faces
|
||||
displayapp/icons/bg_clock.c
|
||||
displayapp/screens/WatchFaceAnalog.cpp
|
||||
displayapp/screens/WatchFaceDigital.cpp
|
||||
displayapp/screens/WatchFaceTerminal.cpp
|
||||
displayapp/screens/WatchFacePineTimeStyle.cpp
|
||||
|
||||
##
|
||||
|
||||
@ -451,30 +456,31 @@ list(APPEND SOURCE_FILES
|
||||
components/ble/CurrentTimeService.cpp
|
||||
components/ble/AlertNotificationService.cpp
|
||||
components/ble/MusicService.cpp
|
||||
components/ble/weather/WeatherService.cpp
|
||||
components/ble/NavigationService.cpp
|
||||
displayapp/fonts/lv_font_navi_80.c
|
||||
components/ble/AgendaService.cpp
|
||||
components/ble/BatteryInformationService.cpp
|
||||
components/ble/FSService.cpp
|
||||
components/ble/ImmediateAlertService.cpp
|
||||
components/ble/ServiceDiscovery.cpp
|
||||
components/ble/HeartRateService.cpp
|
||||
components/ble/MotionService.cpp
|
||||
components/firmwarevalidator/FirmwareValidator.cpp
|
||||
components/motor/MotorController.cpp
|
||||
components/settings/Settings.cpp
|
||||
components/timer/TimerController.cpp
|
||||
components/alarm/AlarmController.cpp
|
||||
components/fs/FS.cpp
|
||||
drivers/Cst816s.cpp
|
||||
FreeRTOS/port.c
|
||||
FreeRTOS/port_cmsis_systick.c
|
||||
FreeRTOS/port_cmsis.c
|
||||
|
||||
displayapp/LittleVgl.cpp
|
||||
displayapp/fonts/jetbrains_mono_extrabold_compressed.c
|
||||
displayapp/fonts/jetbrains_mono_bold_20.c
|
||||
displayapp/fonts/jetbrains_mono_76.c
|
||||
displayapp/fonts/jetbrains_mono_42.c
|
||||
displayapp/fonts/lv_font_sys_48.c
|
||||
displayapp/lv_pinetime_theme.c
|
||||
|
||||
systemtask/SystemTask.cpp
|
||||
systemtask/SystemMonitor.cpp
|
||||
drivers/TwiMaster.cpp
|
||||
|
||||
heartratetask/HeartRateTask.cpp
|
||||
@ -482,6 +488,9 @@ list(APPEND SOURCE_FILES
|
||||
components/heartrate/Biquad.cpp
|
||||
components/heartrate/Ptagc.cpp
|
||||
components/heartrate/HeartRateController.cpp
|
||||
|
||||
buttonhandler/ButtonHandler.cpp
|
||||
touchhandler/TouchHandler.cpp
|
||||
)
|
||||
|
||||
list(APPEND RECOVERY_SOURCE_FILES
|
||||
@ -515,23 +524,28 @@ list(APPEND RECOVERY_SOURCE_FILES
|
||||
components/ble/CurrentTimeService.cpp
|
||||
components/ble/AlertNotificationService.cpp
|
||||
components/ble/MusicService.cpp
|
||||
components/ble/weather/WeatherService.cpp
|
||||
components/ble/BatteryInformationService.cpp
|
||||
components/ble/FSService.cpp
|
||||
components/ble/ImmediateAlertService.cpp
|
||||
components/ble/ServiceDiscovery.cpp
|
||||
components/ble/NavigationService.cpp
|
||||
components/ble/AgendaService.cpp
|
||||
components/ble/HeartRateService.cpp
|
||||
components/ble/MotionService.cpp
|
||||
components/firmwarevalidator/FirmwareValidator.cpp
|
||||
components/settings/Settings.cpp
|
||||
components/timer/TimerController.cpp
|
||||
components/alarm/AlarmController.cpp
|
||||
drivers/Cst816s.cpp
|
||||
FreeRTOS/port.c
|
||||
FreeRTOS/port_cmsis_systick.c
|
||||
FreeRTOS/port_cmsis.c
|
||||
|
||||
systemtask/SystemTask.cpp
|
||||
systemtask/SystemMonitor.cpp
|
||||
drivers/TwiMaster.cpp
|
||||
components/gfx/Gfx.cpp
|
||||
displayapp/icons/infinitime/infinitime-nb.c
|
||||
components/rle/RleDecoder.cpp
|
||||
components/heartrate/HeartRateController.cpp
|
||||
heartratetask/HeartRateTask.cpp
|
||||
@ -539,6 +553,9 @@ list(APPEND RECOVERY_SOURCE_FILES
|
||||
components/heartrate/Biquad.cpp
|
||||
components/heartrate/Ptagc.cpp
|
||||
components/motor/MotorController.cpp
|
||||
components/fs/FS.cpp
|
||||
buttonhandler/ButtonHandler.cpp
|
||||
touchhandler/TouchHandler.cpp
|
||||
)
|
||||
|
||||
list(APPEND RECOVERYLOADER_SOURCE_FILES
|
||||
@ -558,13 +575,13 @@ list(APPEND RECOVERYLOADER_SOURCE_FILES
|
||||
drivers/St7789.cpp
|
||||
components/brightness/BrightnessController.cpp
|
||||
|
||||
displayapp/icons/infinitime/infinitime-nb.c
|
||||
recoveryLoader.cpp
|
||||
)
|
||||
|
||||
|
||||
set(INCLUDE_FILES
|
||||
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/Version.h
|
||||
BootloaderVersion.h
|
||||
logging/Logger.h
|
||||
logging/NrfLogger.h
|
||||
@ -574,15 +591,12 @@ set(INCLUDE_FILES
|
||||
displayapp/screens/Screen.h
|
||||
displayapp/screens/Clock.h
|
||||
displayapp/screens/Tile.h
|
||||
displayapp/screens/Meter.h
|
||||
displayapp/screens/InfiniPaint.h
|
||||
displayapp/screens/StopWatch.h
|
||||
displayapp/screens/Paddle.h
|
||||
displayapp/screens/DropDownDemo.h
|
||||
displayapp/screens/BatteryIcon.h
|
||||
displayapp/screens/BleIcon.h
|
||||
displayapp/screens/NotificationIcon.h
|
||||
displayapp/screens/Brightness.h
|
||||
displayapp/screens/SystemInfo.h
|
||||
displayapp/screens/ScreenList.h
|
||||
displayapp/screens/Label.h
|
||||
@ -592,8 +606,12 @@ set(INCLUDE_FILES
|
||||
displayapp/Apps.h
|
||||
displayapp/screens/Notifications.h
|
||||
displayapp/screens/HeartRate.h
|
||||
displayapp/screens/Metronome.h
|
||||
displayapp/screens/Motion.h
|
||||
displayapp/screens/Timer.h
|
||||
displayapp/screens/Alarm.h
|
||||
displayapp/Colors.h
|
||||
displayapp/widgets/Counter.h
|
||||
drivers/St7789.h
|
||||
drivers/SpiNorFlash.h
|
||||
drivers/SpiMaster.h
|
||||
@ -602,6 +620,7 @@ set(INCLUDE_FILES
|
||||
drivers/DebugPins.h
|
||||
drivers/InternalFlash.h
|
||||
drivers/Hrs3300.h
|
||||
drivers/PinMap.h
|
||||
drivers/Bma421.h
|
||||
drivers/Bma421_C/bma4.c
|
||||
drivers/Bma421_C/bma423.c
|
||||
@ -611,6 +630,9 @@ set(INCLUDE_FILES
|
||||
components/datetime/DateTimeController.h
|
||||
components/brightness/BrightnessController.h
|
||||
components/motion/MotionController.h
|
||||
components/firmwarevalidator/FirmwareValidator.h
|
||||
components/ble/BleController.h
|
||||
components/ble/NotificationManager.h
|
||||
components/ble/NimbleController.h
|
||||
components/ble/DeviceInformationService.h
|
||||
components/ble/CurrentTimeClient.h
|
||||
@ -618,12 +640,16 @@ set(INCLUDE_FILES
|
||||
components/ble/DfuService.h
|
||||
components/firmwarevalidator/FirmwareValidator.h
|
||||
components/ble/BatteryInformationService.h
|
||||
components/ble/FSService.h
|
||||
components/ble/ImmediateAlertService.h
|
||||
components/ble/ServiceDiscovery.h
|
||||
components/ble/BleClient.h
|
||||
components/ble/HeartRateService.h
|
||||
components/ble/MotionService.h
|
||||
components/ble/weather/WeatherService.h
|
||||
components/settings/Settings.h
|
||||
components/timer/TimerController.h
|
||||
components/alarm/AlarmController.h
|
||||
drivers/Cst816s.h
|
||||
FreeRTOS/portmacro.h
|
||||
FreeRTOS/portmacro_cmsis.h
|
||||
@ -647,9 +673,12 @@ set(INCLUDE_FILES
|
||||
components/heartrate/Ptagc.h
|
||||
components/heartrate/HeartRateController.h
|
||||
components/motor/MotorController.h
|
||||
buttonhandler/ButtonHandler.h
|
||||
touchhandler/TouchHandler.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}/src # include generated files like Version.h
|
||||
.
|
||||
../
|
||||
libs/
|
||||
@ -744,30 +773,41 @@ link_directories(
|
||||
)
|
||||
|
||||
|
||||
set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -Wno-unknown-pragmas -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type -fstack-usage -fno-exceptions -fno-non-call-exceptions)
|
||||
set(COMMON_FLAGS -MP -MD -mthumb -mabi=aapcs -Wall -Wextra -Warray-bounds=2 -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 -Wformat-nonliteral -ftree-vrp -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unknown-pragmas -Wno-expansion-to-defined -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wreturn-type -Werror=return-type -fstack-usage -fno-exceptions -fno-non-call-exceptions)
|
||||
add_definitions(-DCONFIG_GPIO_AS_PINRESET)
|
||||
add_definitions(-DDEBUG)
|
||||
add_definitions(-DNIMBLE_CFG_CONTROLLER)
|
||||
add_definitions(-DOS_CPUTIME_FREQ)
|
||||
add_definitions(-DNRF52 -DNRF52832 -DNRF52832_XXAA -DNRF52_PAN_74 -DNRF52_PAN_64 -DNRF52_PAN_12 -DNRF52_PAN_58 -DNRF52_PAN_54 -DNRF52_PAN_31 -DNRF52_PAN_51 -DNRF52_PAN_36 -DNRF52_PAN_15 -DNRF52_PAN_20 -DNRF52_PAN_55 -DBOARD_PCA10040)
|
||||
add_definitions(-DFREERTOS)
|
||||
add_definitions(-DDEBUG_NRF_USER)
|
||||
add_definitions(-D__STACK_SIZE=8192)
|
||||
add_definitions(-D__HEAP_SIZE=8192)
|
||||
add_definitions(-D__STACK_SIZE=1024)
|
||||
add_definitions(-D__HEAP_SIZE=4096)
|
||||
|
||||
# NOTE : Add the following defines to enable debug mode of the NRF SDK:
|
||||
#add_definitions(-DDEBUG)
|
||||
#add_definitions(-DDEBUG_NRF_USER)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif ()
|
||||
|
||||
add_subdirectory(displayapp/fonts)
|
||||
target_compile_options(infinitime_fonts PUBLIC
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3 -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os -fno-rtti>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
# NRF SDK
|
||||
add_library(nrf-sdk STATIC ${SDK_SOURCE_FILES})
|
||||
target_include_directories(nrf-sdk SYSTEM PUBLIC . ../)
|
||||
target_include_directories(nrf-sdk SYSTEM PUBLIC ${INCLUDES_FROM_LIBS})
|
||||
target_compile_options(nrf-sdk PRIVATE
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-expansion-to-defined -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-expansion-to-defined -O3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-expansion-to-defined -Og -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-expansion-to-defined -O3 -fno-rtti>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
@ -795,24 +835,55 @@ target_compile_options(lvgl PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
# QCBOR
|
||||
add_library(QCBOR STATIC ${QCBOR_SRC})
|
||||
target_include_directories(QCBOR SYSTEM PUBLIC libs/QCBOR/inc)
|
||||
# This is required with the current configuration
|
||||
target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_FLOAT_HW_USE)
|
||||
# These are for space-saving
|
||||
target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_PREFERRED_FLOAT)
|
||||
target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_EXP_AND_MANTISSA)
|
||||
target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS)
|
||||
#target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS)
|
||||
target_compile_definitions(QCBOR PUBLIC QCBOR_DISABLE_UNCOMMON_TAGS)
|
||||
target_compile_definitions(QCBOR PUBLIC USEFULBUF_CONFIG_LITTLE_ENDIAN)
|
||||
set_target_properties(QCBOR PROPERTIES LINKER_LANGUAGE C)
|
||||
target_compile_options(QCBOR PRIVATE
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
# LITTLEFS_SRC
|
||||
add_library(littlefs STATIC ${LITTLEFS_SRC})
|
||||
target_include_directories(littlefs SYSTEM PUBLIC . ../)
|
||||
target_include_directories(littlefs SYSTEM PUBLIC ${INCLUDES_FROM_LIBS})
|
||||
target_compile_options(littlefs PRIVATE
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-unused-function -Os>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3 -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-unused-function -Os -fno-rtti>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
# Build autonomous binary (without support for bootloader)
|
||||
set(EXECUTABLE_NAME "pinetime-app")
|
||||
set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld")
|
||||
add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES})
|
||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME})
|
||||
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl)
|
||||
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs QCBOR infinitime_fonts)
|
||||
target_compile_options(${EXECUTABLE_NAME} PUBLIC
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3 -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3 -fno-rtti>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os -fno-rtti>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||
)
|
||||
|
||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_NAME}
|
||||
@ -822,15 +893,14 @@ add_custom_command(TARGET ${EXECUTABLE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_FILE_NAME}.out "${EXECUTABLE_FILE_NAME}.hex"
|
||||
COMMENT "post build steps for ${EXECUTABLE_FILE_NAME}")
|
||||
|
||||
|
||||
# Build binary intended to be used by bootloader
|
||||
set(EXECUTABLE_MCUBOOT_NAME "pinetime-mcuboot-app")
|
||||
set(EXECUTABLE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
||||
set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld")
|
||||
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl)
|
||||
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs QCBOR infinitime_fonts)
|
||||
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME})
|
||||
target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
@ -842,7 +912,7 @@ target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
|
||||
|
||||
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
|
||||
@ -850,7 +920,7 @@ add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.bin ${IMAGE_MCUBOOT_FILE_NAME}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.hex ${IMAGE_MCUBOOT_FILE_NAME}
|
||||
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
|
||||
@ -866,7 +936,7 @@ endif()
|
||||
set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery")
|
||||
set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk)
|
||||
target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk littlefs QCBOR infinitime_fonts)
|
||||
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME})
|
||||
target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
||||
target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
|
||||
@ -879,7 +949,7 @@ target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
|
||||
|
||||
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERY_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
|
||||
@ -893,10 +963,10 @@ add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
|
||||
# InfiniTime recovery firmware (mcuboot)
|
||||
set(EXECUTABLE_RECOVERY_MCUBOOT_NAME "pinetime-mcuboot-recovery")
|
||||
set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk)
|
||||
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk littlefs QCBOR infinitime_fonts)
|
||||
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME})
|
||||
target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
||||
target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
|
||||
@ -909,16 +979,17 @@ target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
|
||||
|
||||
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_GRAPHICS_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERYY_MCUBOOT_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.bin ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} recoveryImage > recoveryImage.h
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.hex ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} "${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.bin recoveryImage > recoveryImage.h
|
||||
COMMENT "post build steps for ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
|
||||
@ -934,7 +1005,7 @@ endif()
|
||||
set(EXECUTABLE_RECOVERYLOADER_NAME "pinetime-recovery-loader")
|
||||
set(EXECUTABLE_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_RECOVERYLOADER_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
add_executable(${EXECUTABLE_RECOVERYLOADER_NAME} ${RECOVERYLOADER_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_RECOVERYLOADER_NAME} nrf-sdk)
|
||||
target_link_libraries(${EXECUTABLE_RECOVERYLOADER_NAME} nrf-sdk QCBOR infinitime_fonts)
|
||||
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERYLOADER_FILE_NAME})
|
||||
target_compile_options(${EXECUTABLE_RECOVERYLOADER_NAME} PUBLIC
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
@ -950,7 +1021,7 @@ add_dependencies(${EXECUTABLE_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY_MCUBOOT
|
||||
|
||||
set_target_properties(${EXECUTABLE_RECOVERYLOADER_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_RECOVERYLOADER_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
|
||||
@ -964,10 +1035,10 @@ add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
|
||||
# Build binary that writes the recovery image (MCUBoot version)
|
||||
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME "pinetime-mcuboot-recovery-loader")
|
||||
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
||||
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
add_executable(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${RECOVERYLOADER_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} nrf-sdk)
|
||||
target_link_libraries(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} nrf-sdk QCBOR infinitime_fonts)
|
||||
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME})
|
||||
target_compile_options(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PUBLIC
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||
@ -983,7 +1054,7 @@ add_dependencies(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${EXECUTABLE_RECOVERY
|
||||
|
||||
set_target_properties(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} PROPERTIES
|
||||
SUFFIX ".out"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map"
|
||||
LINK_FLAGS "-mthumb -mabi=aapcs -std=gnu++98 -std=c99 -L ${NRF5_SDK_PATH}/modules/nrfx/mdk -T${NRF5_LINKER_SCRIPT_MCUBOOT} -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Wl,--gc-sections -Wl,--print-memory-usage --specs=nano.specs -lc -lnosys -lm -Wl,-Map=${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.map"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
|
||||
@ -991,8 +1062,9 @@ add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} recoveryLoaderImage > recoveryLoaderImage.h
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} "${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin recoveryLoaderImage > recoveryLoaderImage.h
|
||||
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}"
|
||||
)
|
||||
|
||||
|
@ -294,6 +294,25 @@ static void vPortEnableVFP( void )
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void )
|
||||
{
|
||||
__asm volatile (
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
||||
{
|
||||
__asm volatile (
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
@ -354,24 +373,4 @@ static void vPortEnableVFP( void )
|
||||
configASSERT( NVIC_GetPriorityGrouping() <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
uint32_t ulSetInterruptMaskFromISR( void )
|
||||
{
|
||||
__asm volatile (
|
||||
" mrs r0, PRIMASK \n"
|
||||
" cpsid i \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vClearInterruptMaskFromISR( __attribute__( ( unused ) ) uint32_t ulMask )
|
||||
{
|
||||
__asm volatile (
|
||||
" msr PRIMASK, r0 \n"
|
||||
" bx lr "
|
||||
::: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|