mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-15 15:22:34 +00:00
Compare commits
766 Commits
v1.2.45.b6
...
v1.2.61.d5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d551c17546 | ||
|
|
af4027e8c8 | ||
|
|
3df0fdd239 | ||
|
|
8510ef3ad0 | ||
|
|
ee419f8b9b | ||
|
|
ab959ded0e | ||
|
|
2a76a5527a | ||
|
|
58d91f0a4b | ||
|
|
e09aafa13f | ||
|
|
aca95248ee | ||
|
|
d81c1c08ee | ||
|
|
317ce2c9cd | ||
|
|
b2827597fd | ||
|
|
6af182228c | ||
|
|
1246c7bb1e | ||
|
|
e6731e28c1 | ||
|
|
d57ac39b02 | ||
|
|
67bc6b1419 | ||
|
|
d328823c03 | ||
|
|
7178d3a2fd | ||
|
|
a0f60f1d07 | ||
|
|
b177313e2d | ||
|
|
53d47146b2 | ||
|
|
f7c6955736 | ||
|
|
9a87e1b53e | ||
|
|
f1478a7c93 | ||
|
|
8fd5d83980 | ||
|
|
5895aaa259 | ||
|
|
1787712a5a | ||
|
|
596a73c0a0 | ||
|
|
d56f8c631b | ||
|
|
682f988c2a | ||
|
|
ce20a2b566 | ||
|
|
d0fc836f0b | ||
|
|
d542267e4a | ||
|
|
756317e7e0 | ||
|
|
ab96579904 | ||
|
|
3f83acdbef | ||
|
|
9db7c62a49 | ||
|
|
d79dc631f1 | ||
|
|
7ea6babb7f | ||
|
|
0b4b901504 | ||
|
|
cc7b5cf136 | ||
|
|
e3df4fe4b4 | ||
|
|
288f2be8ea | ||
|
|
c867af8522 | ||
|
|
856f2f9589 | ||
|
|
e649bc84e1 | ||
|
|
bbcd59ec7b | ||
|
|
e11fd593ae | ||
|
|
868af9dd6b | ||
|
|
10800a6914 | ||
|
|
e567fe7322 | ||
|
|
365120e9c2 | ||
|
|
b21b7de04b | ||
|
|
dd31a829fb | ||
|
|
9a505c27fa | ||
|
|
ed9cd7b03d | ||
|
|
66413d8b7f | ||
|
|
e4fe2c159a | ||
|
|
f5e0718052 | ||
|
|
64ff48c4a5 | ||
|
|
50969c4e42 | ||
|
|
5288f1846a | ||
|
|
c545155b03 | ||
|
|
a4e9fca80c | ||
|
|
3611293a98 | ||
|
|
dc7f376778 | ||
|
|
ff2cad9cac | ||
|
|
b781fb613c | ||
|
|
0a1125d7e4 | ||
|
|
ed2de3b885 | ||
|
|
19c1f9fa59 | ||
|
|
266d6ad205 | ||
|
|
66cd824437 | ||
|
|
e2db4f6927 | ||
|
|
56fb141ed0 | ||
|
|
e8e209be25 | ||
|
|
c278a0e299 | ||
|
|
fbc25c3a13 | ||
|
|
b7f04f4c91 | ||
|
|
d5377a0f19 | ||
|
|
dafc1092aa | ||
|
|
477b666998 | ||
|
|
dbcd720391 | ||
|
|
59c2bcd978 | ||
|
|
aea6675e64 | ||
|
|
8bff696bef | ||
|
|
da0ec09bf4 | ||
|
|
2c99020037 | ||
|
|
14419cbd02 | ||
|
|
1bfa6839e2 | ||
|
|
a61676504f | ||
|
|
f4d3de086a | ||
|
|
af249da1a3 | ||
|
|
7613c7bf83 | ||
|
|
e4608e0a10 | ||
|
|
d26549c7c2 | ||
|
|
697d52b9bd | ||
|
|
7a9450b250 | ||
|
|
6d372743f5 | ||
|
|
c2b309195d | ||
|
|
3c7670186a | ||
|
|
b51be320dd | ||
|
|
409ad9c2c3 | ||
|
|
eaa5252cdb | ||
|
|
3d718f45d5 | ||
|
|
a8dab94087 | ||
|
|
5a348da0e9 | ||
|
|
115b835b83 | ||
|
|
9df42799ff | ||
|
|
e1d3c01199 | ||
|
|
bdcc0f252b | ||
|
|
437aa1e9af | ||
|
|
6883bc7afc | ||
|
|
a2eef895bd | ||
|
|
64671c8ce7 | ||
|
|
252a27174e | ||
|
|
7c362af3de | ||
|
|
c6b851a2e6 | ||
|
|
ec4346aba3 | ||
|
|
791186a264 | ||
|
|
ab947f06aa | ||
|
|
cfa0ceb604 | ||
|
|
c7686ad57e | ||
|
|
8732b7cb4d | ||
|
|
fe9dcbb316 | ||
|
|
38d1a381e6 | ||
|
|
0b2f1d5675 | ||
|
|
caaa235c5d | ||
|
|
9a0126cde1 | ||
|
|
39d0c0fd8f | ||
|
|
be0b9979bc | ||
|
|
b3210f6c2c | ||
|
|
2357240d84 | ||
|
|
c2f0048931 | ||
|
|
d1ba314065 | ||
|
|
8a79ede285 | ||
|
|
c8ecd6ac8e | ||
|
|
13226adb2a | ||
|
|
e706aae41d | ||
|
|
91ad0df11c | ||
|
|
976627d974 | ||
|
|
6830f9861a | ||
|
|
2db307fc8d | ||
|
|
7fae43e1a5 | ||
|
|
8b60226497 | ||
|
|
ab8083dec4 | ||
|
|
a561713a48 | ||
|
|
00f3996cee | ||
|
|
9e4e79c5d7 | ||
|
|
61e1b8d859 | ||
|
|
165e8e8cba | ||
|
|
635fbcf0d5 | ||
|
|
815222ad80 | ||
|
|
64a9f15b1c | ||
|
|
abcdf39b20 | ||
|
|
16ee75313a | ||
|
|
bfd9938507 | ||
|
|
01f5f1b5ba | ||
|
|
b6706c7ac1 | ||
|
|
7723b30951 | ||
|
|
6d34151590 | ||
|
|
2230cbbe2a | ||
|
|
b49ba55658 | ||
|
|
0864154157 | ||
|
|
c4f64b1592 | ||
|
|
001d054924 | ||
|
|
5e590a4a5e | ||
|
|
22a2fe2cb4 | ||
|
|
f047ae6792 | ||
|
|
e1ef495071 | ||
|
|
209c6253a6 | ||
|
|
1acabb9d35 | ||
|
|
420495cb2d | ||
|
|
9309824874 | ||
|
|
4fc443e760 | ||
|
|
53399f06e5 | ||
|
|
4e3fda87a1 | ||
|
|
1ff3b3326c | ||
|
|
9f0ddda6ca | ||
|
|
8e3d30bd7f | ||
|
|
6ca3186bff | ||
|
|
68fadfe26c | ||
|
|
92bcdb5e53 | ||
|
|
04b1948ee9 | ||
|
|
6fdc16017a | ||
|
|
7f759d6bb5 | ||
|
|
1f227797c1 | ||
|
|
ab87c0a9ee | ||
|
|
6d960918e2 | ||
|
|
5797e32461 | ||
|
|
41da6c3b99 | ||
|
|
fe3a352511 | ||
|
|
b53f4214bc | ||
|
|
b6b1bcc5ad | ||
|
|
91117ca7c6 | ||
|
|
2d8e55a34e | ||
|
|
3a7292d3d0 | ||
|
|
3fea1c4e5f | ||
|
|
c2435470c1 | ||
|
|
1c993c10a1 | ||
|
|
0a62ce23af | ||
|
|
38efb8b3ad | ||
|
|
9ee7f5e0bd | ||
|
|
c798e1a2da | ||
|
|
7eb4713422 | ||
|
|
a9ed26fdbc | ||
|
|
a7451b6abe | ||
|
|
e61db642bc | ||
|
|
25a540c28b | ||
|
|
1993b8f8a6 | ||
|
|
38dd5612fd | ||
|
|
8a63c6f3a3 | ||
|
|
778d13dee7 | ||
|
|
2fd0d2baff | ||
|
|
399792803a | ||
|
|
8a6bbcb985 | ||
|
|
419349e13e | ||
|
|
6b0770fdd5 | ||
|
|
ee2b05da78 | ||
|
|
d900847bab | ||
|
|
8b56ebd566 | ||
|
|
b63802cef3 | ||
|
|
a1f80f024e | ||
|
|
41de8a1309 | ||
|
|
33f08364e4 | ||
|
|
c5b95ed3c0 | ||
|
|
f7c8cabdfe | ||
|
|
0f1c424731 | ||
|
|
3fa00f603b | ||
|
|
f5004a66a1 | ||
|
|
b832b82ec6 | ||
|
|
fbd5b8b721 | ||
|
|
772dfe39dc | ||
|
|
c7e62142e9 | ||
|
|
6eb2b33124 | ||
|
|
b3ddf16d64 | ||
|
|
4a29aef19e | ||
|
|
7b8849493f | ||
|
|
2b588f1567 | ||
|
|
975f7c0332 | ||
|
|
f9ff06b296 | ||
|
|
ad038b07b6 | ||
|
|
2e4b777625 | ||
|
|
a8f1115c05 | ||
|
|
f26bb6467e | ||
|
|
c1ee1265ab | ||
|
|
ad31d558a1 | ||
|
|
1b81b155d6 | ||
|
|
4a036db612 | ||
|
|
2e0cd7ce4a | ||
|
|
4ddc113ed6 | ||
|
|
47935aab98 | ||
|
|
0a43be6f8c | ||
|
|
053a00ec6c | ||
|
|
5392a83e33 | ||
|
|
1adca4e992 | ||
|
|
1e247f154e | ||
|
|
f302166832 | ||
|
|
51743f751a | ||
|
|
b22cc1a964 | ||
|
|
bd3688d21d | ||
|
|
465ff3dd25 | ||
|
|
2ee1155c78 | ||
|
|
6506d54859 | ||
|
|
6843ffe452 | ||
|
|
1fe4b95fe5 | ||
|
|
398a5baa90 | ||
|
|
fcd3170a0f | ||
|
|
95f2d0c933 | ||
|
|
e2d1cce1bb | ||
|
|
01f1b33eec | ||
|
|
94246a1fbc | ||
|
|
abae99f577 | ||
|
|
f221bc6275 | ||
|
|
706d6e2671 | ||
|
|
2857fafa81 | ||
|
|
17dfb7d152 | ||
|
|
dff219a037 | ||
|
|
1c63d2d334 | ||
|
|
b6eb927ad2 | ||
|
|
9d8a1b3522 | ||
|
|
9bc9d37596 | ||
|
|
76d0ad2907 | ||
|
|
3a17822893 | ||
|
|
da7ca98f44 | ||
|
|
841bc97a47 | ||
|
|
dbdbe75e9f | ||
|
|
d5fc905402 | ||
|
|
c366d81510 | ||
|
|
e9f01de051 | ||
|
|
f9905ea416 | ||
|
|
a8d10329f8 | ||
|
|
1157419e05 | ||
|
|
12f1fda934 | ||
|
|
cb0073f6fa | ||
|
|
da5bc9d9d9 | ||
|
|
38baebe48f | ||
|
|
97ad7a1825 | ||
|
|
1f9b1e2828 | ||
|
|
796d05e89e | ||
|
|
063d7a7d81 | ||
|
|
6d0368b13d | ||
|
|
b2011a1889 | ||
|
|
893472e36a | ||
|
|
4d82a0146b | ||
|
|
8569595249 | ||
|
|
88281dbbf1 | ||
|
|
dd3e8af4c0 | ||
|
|
a0d3d1dc89 | ||
|
|
9a87ec7353 | ||
|
|
3857dd7e52 | ||
|
|
690cb0c77a | ||
|
|
5d4f039b3e | ||
|
|
676e840b5b | ||
|
|
c00c2744bf | ||
|
|
83293a5f4d | ||
|
|
0812094f35 | ||
|
|
7dfe596bcb | ||
|
|
749d127281 | ||
|
|
dd464896ae | ||
|
|
00ff013799 | ||
|
|
415ded1f4d | ||
|
|
924069f9ad | ||
|
|
ad784532b7 | ||
|
|
de1d5d61ff | ||
|
|
af8f70e9ae | ||
|
|
c135a59787 | ||
|
|
333b195804 | ||
|
|
40f1a7bcaf | ||
|
|
432854ce31 | ||
|
|
6e706e0585 | ||
|
|
4ca8846c2f | ||
|
|
69e1985eda | ||
|
|
475348489e | ||
|
|
c8aec324f5 | ||
|
|
90f5fade84 | ||
|
|
df75182bcf | ||
|
|
6cb4900e0c | ||
|
|
8bbdfe4538 | ||
|
|
f53fdf1628 | ||
|
|
a16dcbe9d0 | ||
|
|
20497335c2 | ||
|
|
e24a2116d8 | ||
|
|
9c7121df3e | ||
|
|
c531ea8601 | ||
|
|
0a4659b605 | ||
|
|
41dcfdd7cb | ||
|
|
fbcbc791de | ||
|
|
7c6d53f297 | ||
|
|
68c52a8d36 | ||
|
|
759bdfd6a4 | ||
|
|
94aff87706 | ||
|
|
3fdb374dce | ||
|
|
6f3ffc6ef0 | ||
|
|
07adfd7543 | ||
|
|
bdacd97fea | ||
|
|
7eb00dd5f6 | ||
|
|
37dec91ed9 | ||
|
|
80d872448d | ||
|
|
cea35acfa0 | ||
|
|
672ea5b494 | ||
|
|
79e75a47f6 | ||
|
|
10dc8233ea | ||
|
|
f1c029d6da | ||
|
|
a2883789d1 | ||
|
|
654558abcd | ||
|
|
c1abe84abc | ||
|
|
f3427084c2 | ||
|
|
638d43a341 | ||
|
|
1063415292 | ||
|
|
a70b849039 | ||
|
|
33769b8657 | ||
|
|
a534eae43c | ||
|
|
5a22b49a24 | ||
|
|
06a6f75f00 | ||
|
|
bea9dfff38 | ||
|
|
2818dfc948 | ||
|
|
f521878308 | ||
|
|
648e8bb5e1 | ||
|
|
6907cb192e | ||
|
|
988f8c4d23 | ||
|
|
4a3bdb284d | ||
|
|
efdd2ad490 | ||
|
|
228be41ba6 | ||
|
|
5432d3d44b | ||
|
|
e77cbd0588 | ||
|
|
072707c77e | ||
|
|
366a028502 | ||
|
|
ea7bceb85b | ||
|
|
caa4f3cd71 | ||
|
|
521c55595a | ||
|
|
a0c9d18e0d | ||
|
|
0938cded58 | ||
|
|
0ea12436b6 | ||
|
|
8e50e25eec | ||
|
|
2d8bf4d684 | ||
|
|
0aa4ea86a0 | ||
|
|
d09754fbcf | ||
|
|
a192da5cd0 | ||
|
|
73985c47d6 | ||
|
|
476c6f25ce | ||
|
|
836113ef8b | ||
|
|
3e31d561ea | ||
|
|
192feeaf0e | ||
|
|
9f63a8c330 | ||
|
|
b6d72d3248 | ||
|
|
756528180e | ||
|
|
8d8fece89d | ||
|
|
7af4a31329 | ||
|
|
2ace1f48b8 | ||
|
|
d1d096d52a | ||
|
|
3adb79bd18 | ||
|
|
34908a8f79 | ||
|
|
9b15bb51b3 | ||
|
|
d7a1b9fd62 | ||
|
|
727dcbc809 | ||
|
|
94e9345354 | ||
|
|
4fcd82d6f5 | ||
|
|
4cd25bc755 | ||
|
|
252820c58c | ||
|
|
0e5a783c5a | ||
|
|
4a053801ce | ||
|
|
e68ca88c9c | ||
|
|
40d61543e4 | ||
|
|
f3fc88ac5d | ||
|
|
d1370071da | ||
|
|
b71051a227 | ||
|
|
a27260a605 | ||
|
|
5354c49c50 | ||
|
|
3dbc31e8f3 | ||
|
|
5ff6b919c6 | ||
|
|
62602b54f4 | ||
|
|
ee70b5996f | ||
|
|
1f4a3085ef | ||
|
|
f119555c12 | ||
|
|
2f16b3f345 | ||
|
|
1d0221e02d | ||
|
|
446fb857cc | ||
|
|
c6292679f5 | ||
|
|
65cc938c72 | ||
|
|
a1f97aea77 | ||
|
|
ce42707fc7 | ||
|
|
1ed3195194 | ||
|
|
4de89fab0d | ||
|
|
4fb5107298 | ||
|
|
686057a0b1 | ||
|
|
04683580ff | ||
|
|
66085d7447 | ||
|
|
033e0e99ec | ||
|
|
98d2499074 | ||
|
|
3d4e4bfa50 | ||
|
|
9e771f14d8 | ||
|
|
1156a3406e | ||
|
|
0475cc93ab | ||
|
|
8b508576ea | ||
|
|
a96dee5beb | ||
|
|
84332c60f0 | ||
|
|
61bc0e09e7 | ||
|
|
55da39823b | ||
|
|
fb15898ed6 | ||
|
|
9fd8df3872 | ||
|
|
2ad37e2126 | ||
|
|
148b62c02f | ||
|
|
098eee0062 | ||
|
|
b6d63059bf | ||
|
|
6cfdd99fd1 | ||
|
|
c8bea4f091 | ||
|
|
084ef821b7 | ||
|
|
8785f2848f | ||
|
|
f86e0d46b6 | ||
|
|
41493c9e1f | ||
|
|
67766b817c | ||
|
|
feb1f4fb9f | ||
|
|
d3dc51d102 | ||
|
|
e53a6615ad | ||
|
|
a904bb8cc5 | ||
|
|
d0715f85a0 | ||
|
|
df88feba0f | ||
|
|
b0a6c8929c | ||
|
|
9c8c419939 | ||
|
|
c83ca7bfdd | ||
|
|
f01952bd0d | ||
|
|
7cb0821886 | ||
|
|
bd11b7464e | ||
|
|
f6c3ae132a | ||
|
|
5fc9f3bfb1 | ||
|
|
3384c1ed1f | ||
|
|
b2e7507cd8 | ||
|
|
1cb5ba38f6 | ||
|
|
e9653dae03 | ||
|
|
5b34e3e1ab | ||
|
|
6b184ed448 | ||
|
|
9ec3085cd5 | ||
|
|
02e3d06bcb | ||
|
|
eefef1dceb | ||
|
|
465f7a6935 | ||
|
|
3da9c7b081 | ||
|
|
05835fd1bb | ||
|
|
92ebf1bd69 | ||
|
|
86d712ff4d | ||
|
|
068a6c0309 | ||
|
|
e5ff49d5aa | ||
|
|
aaefd2c2e7 | ||
|
|
e73f79a344 | ||
|
|
53efb9c0f6 | ||
|
|
9f6522a756 | ||
|
|
09b467ce7c | ||
|
|
105c026297 | ||
|
|
83c6d8b07e | ||
|
|
e19a7c73bc | ||
|
|
23e16bfb1a | ||
|
|
47e7b00000 | ||
|
|
9adbe28319 | ||
|
|
d1eb314047 | ||
|
|
371335e6ab | ||
|
|
8bc4b581d1 | ||
|
|
2311653ca8 | ||
|
|
040e3234fc | ||
|
|
62cf2adaec | ||
|
|
063499ef46 | ||
|
|
b7eaeb8c31 | ||
|
|
6bd495a491 | ||
|
|
f09aa9bec0 | ||
|
|
a7b3b4386f | ||
|
|
6a426d5d71 | ||
|
|
0ca061a457 | ||
|
|
f1ef1eeaff | ||
|
|
1175c981c0 | ||
|
|
1d3387466f | ||
|
|
fcccddc4ad | ||
|
|
be44fa11b1 | ||
|
|
de104a2707 | ||
|
|
9d019c1a99 | ||
|
|
11d954422b | ||
|
|
f4d348173c | ||
|
|
79eb5546a1 | ||
|
|
4f10ab8d04 | ||
|
|
ab0a06e536 | ||
|
|
59ef28dfa7 | ||
|
|
d87106900b | ||
|
|
241325d245 | ||
|
|
0118f3991a | ||
|
|
2a617ba7b2 | ||
|
|
bbf3091889 | ||
|
|
5199b4d3c7 | ||
|
|
99d35b175c | ||
|
|
98d0907f4d | ||
|
|
5f6d97151c | ||
|
|
8cefa82ff1 | ||
|
|
623b846713 | ||
|
|
e791a5aa2f | ||
|
|
82332c9cd0 | ||
|
|
d5506bb33c | ||
|
|
937f67c4ec | ||
|
|
3ed4a1e3e1 | ||
|
|
757de54a4f | ||
|
|
5cf0b6b3b1 | ||
|
|
809179ce0e | ||
|
|
d7315778d6 | ||
|
|
69a2029ade | ||
|
|
7a649e3fc3 | ||
|
|
f019151e3f | ||
|
|
88fd671880 | ||
|
|
d72c091ead | ||
|
|
3ec508169a | ||
|
|
1775770e54 | ||
|
|
f6fde55363 | ||
|
|
e548de3c88 | ||
|
|
f75aac8ebf | ||
|
|
bc311ac9f6 | ||
|
|
d4c6007047 | ||
|
|
c5f210384f | ||
|
|
d685682dd9 | ||
|
|
e31f9b6e5e | ||
|
|
a56851fefa | ||
|
|
0fc88c542f | ||
|
|
16307cb67d | ||
|
|
9f05bd11cc | ||
|
|
4b6ee2dc88 | ||
|
|
a0d829a91e | ||
|
|
dbabc24d7a | ||
|
|
e3ee3c411c | ||
|
|
d3e1bbf355 | ||
|
|
2fa2497ed8 | ||
|
|
a5727052bc | ||
|
|
083518c127 | ||
|
|
c36b233c49 | ||
|
|
bc7fc1285d | ||
|
|
9ddcc5d2ed | ||
|
|
a3ce728e26 | ||
|
|
cf0d9a2c86 | ||
|
|
ec7953ccf0 | ||
|
|
44a4bde626 | ||
|
|
5db0a57599 | ||
|
|
834f2f4160 | ||
|
|
4367f05b24 | ||
|
|
97aec5f125 | ||
|
|
5191fd6475 | ||
|
|
32017e53f5 | ||
|
|
37aab8a42b | ||
|
|
bfa0307231 | ||
|
|
8eb0d685ac | ||
|
|
43e543eabc | ||
|
|
eee6ef018c | ||
|
|
f7da9ac071 | ||
|
|
928198ff03 | ||
|
|
0cd82507d9 | ||
|
|
2d939d26ee | ||
|
|
d6c7ea921a | ||
|
|
19f43689ca | ||
|
|
e78e82ef42 | ||
|
|
fdfc600b3d | ||
|
|
334e14ea4d | ||
|
|
8115ee0c97 | ||
|
|
e21cc9d479 | ||
|
|
d5e4ceebcc | ||
|
|
51646f28ec | ||
|
|
2c5ba29648 | ||
|
|
41bed5c14d | ||
|
|
5ef9414a25 | ||
|
|
2ebed9cb6c | ||
|
|
7a1409c42a | ||
|
|
093e3e55b9 | ||
|
|
a911515dec | ||
|
|
7ecb36dbe7 | ||
|
|
d4ea18851d | ||
|
|
646d1caf66 | ||
|
|
74c138620a | ||
|
|
3981d2e1f6 | ||
|
|
6ccaa64ae8 | ||
|
|
5dd9610d36 | ||
|
|
d4ed7b2f73 | ||
|
|
9702dffa12 | ||
|
|
e2992cd3b9 | ||
|
|
4e5ac1ac07 | ||
|
|
e89b3bd1ec | ||
|
|
da9dd62a33 | ||
|
|
e6b4ee8084 | ||
|
|
0133a1b293 | ||
|
|
543283c0f6 | ||
|
|
6d778cdda4 | ||
|
|
3ffcecee6c | ||
|
|
24b2fd2657 | ||
|
|
b74c2da530 | ||
|
|
26415cf8e0 | ||
|
|
2f7b58abaf | ||
|
|
ef1d52ca04 | ||
|
|
f69c8dddad | ||
|
|
70b80e600d | ||
|
|
90d95d8e98 | ||
|
|
7d267e8027 | ||
|
|
0d884d159a | ||
|
|
3893810b76 | ||
|
|
fff4735a15 | ||
|
|
a914ee133c | ||
|
|
d0fb363422 | ||
|
|
992bbe76d7 | ||
|
|
6fc3c9c868 | ||
|
|
4fb844bddd | ||
|
|
dce2fe43a5 | ||
|
|
d54dad4225 | ||
|
|
91f4e17037 | ||
|
|
c597cd4a17 | ||
|
|
08d8e764d7 | ||
|
|
e626edeffa | ||
|
|
f9c3797397 | ||
|
|
8e45c5ecd7 | ||
|
|
76791220b9 | ||
|
|
a76e7c79e6 | ||
|
|
83eb94126b | ||
|
|
0a529dcaac | ||
|
|
128a481259 | ||
|
|
87ef15d371 | ||
|
|
9679861b56 | ||
|
|
3a2120391e | ||
|
|
3d197d732c | ||
|
|
5d6fc6d63e | ||
|
|
40505a23dc | ||
|
|
31e833ec59 | ||
|
|
2e65f577d8 | ||
|
|
89cd3fd73a | ||
|
|
9ef55e03be | ||
|
|
930de64bcd | ||
|
|
5c0a76ae46 | ||
|
|
df26f9ac51 | ||
|
|
14e36f0a2b | ||
|
|
96f4998d11 | ||
|
|
4a98bdd9d6 | ||
|
|
796e8c836a | ||
|
|
7081868143 | ||
|
|
ce7aae9ca0 | ||
|
|
1e455ac4c3 | ||
|
|
4669e4713c | ||
|
|
26330120ce | ||
|
|
c3ebe80f53 | ||
|
|
5eb2e6401f | ||
|
|
ee9c72b8c7 | ||
|
|
dc436a3cc9 | ||
|
|
99357e427b | ||
|
|
8bbcdaa951 | ||
|
|
92edfd3217 | ||
|
|
aa936ade7e | ||
|
|
bf695a5f36 | ||
|
|
91bc051e6d | ||
|
|
bc7d1a4ef0 | ||
|
|
debae67ae7 | ||
|
|
28e851c3fd | ||
|
|
c61bfae785 | ||
|
|
e3d9b94367 | ||
|
|
b182819aff | ||
|
|
a1b37d3407 | ||
|
|
b3777ef6f0 | ||
|
|
d54fecca4e | ||
|
|
0f14ed0a6c | ||
|
|
b3012b7ee5 | ||
|
|
2f7e200bef | ||
|
|
16d2c565e8 | ||
|
|
a74f038cba | ||
|
|
bd9bf585d3 | ||
|
|
56dd3eab23 | ||
|
|
cb42440963 | ||
|
|
da61090dc5 | ||
|
|
098f38fb83 | ||
|
|
c442fd3886 | ||
|
|
00bf7879af | ||
|
|
2ba68c9b6e | ||
|
|
2e48b88113 | ||
|
|
a2f06cb077 | ||
|
|
b9443d87aa | ||
|
|
e351f35cf2 | ||
|
|
be9d637c7c | ||
|
|
42986c852a | ||
|
|
de712ce41a | ||
|
|
f6f9b9cd03 | ||
|
|
1a671f2877 | ||
|
|
6f763c6418 | ||
|
|
3eb20d3bd1 | ||
|
|
1c06c2af9f | ||
|
|
eb27e744f7 | ||
|
|
c8269d67c3 | ||
|
|
21f3cc6f7a | ||
|
|
e3ed637942 | ||
|
|
ccb4596299 | ||
|
|
2741de90e5 | ||
|
|
adc51519fd | ||
|
|
72e22b6744 | ||
|
|
030d09740c | ||
|
|
d381f091e9 | ||
|
|
e7fa0ae38b | ||
|
|
5cf1a87657 | ||
|
|
25841c072a | ||
|
|
f40bd0745c | ||
|
|
fe3afaab3d | ||
|
|
8a7a3ec668 | ||
|
|
f96d8bf645 | ||
|
|
b1b3d9df6e | ||
|
|
29124c3416 | ||
|
|
71951a4e6a | ||
|
|
8dbfd0f19b | ||
|
|
5c6355489f | ||
|
|
8edac1f86c | ||
|
|
1a8b128640 | ||
|
|
a83dcbadb9 | ||
|
|
a5e3f271ea |
110
.github/workflows/main.yml
vendored
110
.github/workflows/main.yml
vendored
@@ -1,21 +1,11 @@
|
||||
name: Continuous Integration
|
||||
name: Continuous Integration (Legacy serial build)
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the master branch
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
# setup:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
workflow_dispatch:
|
||||
|
||||
# - name: Startup
|
||||
# run: echo "No action setup currently needed, skipping..."
|
||||
jobs:
|
||||
|
||||
ci-build:
|
||||
# needs: setup
|
||||
ci-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -23,6 +13,12 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install cppcheck
|
||||
run: |
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
@@ -36,9 +32,42 @@ jobs:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
#- name: Install linux apt packages
|
||||
# run: |
|
||||
# sudo apt-get install -y libgpiod-dev
|
||||
- name: Upgrade python tools and install platformio
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Check everything
|
||||
run: bin/check-all.sh
|
||||
|
||||
|
||||
|
||||
ci-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
# We actually want to run this every time
|
||||
@@ -58,6 +87,19 @@ jobs:
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/meshtastic-web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||
- name: Build for native
|
||||
run: platformio run -e native
|
||||
@@ -68,22 +110,23 @@ jobs:
|
||||
echo "Simulator started, launching python test..."
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
|
||||
# - name: Build for tbeam
|
||||
# run: platformio run -e tbeam
|
||||
# - name: Build for heltec
|
||||
# run: platformio run -e heltec
|
||||
# - name: Build for wisblock RAK4631
|
||||
# run: platformio run -e rak4631
|
||||
- name: Cat bin/build-all.sh
|
||||
run: |
|
||||
cat bin/build-all.sh
|
||||
|
||||
- name: Build everything
|
||||
run: bin/build-all.sh
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: built
|
||||
path: release/archive/firmware-*.zip
|
||||
retention-days: 30
|
||||
name: firmware-${{ steps.version.outputs.version }}.zip
|
||||
path: release/archive/firmware-${{ steps.version.outputs.version }}.zip
|
||||
retention-days: 90
|
||||
|
||||
- name: Store debugging elf files as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -91,3 +134,18 @@ jobs:
|
||||
name: debug-elfs
|
||||
path: release/archive/elfs-*.zip
|
||||
retention-days: 7
|
||||
|
||||
- name: Download firmware.zip
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}.zip
|
||||
path: ./
|
||||
|
||||
- name: Pull request artifacts
|
||||
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
||||
uses: gavv/pull-request-artifacts@v1.0.0
|
||||
with:
|
||||
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts-branch: artifacts
|
||||
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
|
||||
|
||||
347
.github/workflows/main_matrix.yml
vendored
Normal file
347
.github/workflows/main_matrix.yml
vendored
Normal file
@@ -0,0 +1,347 @@
|
||||
name: Continuous Integration PR Checks (1.2 Legacy)
|
||||
on:
|
||||
# # Triggers the workflow on push but only for the master branch
|
||||
push:
|
||||
branches: [ 1.2-legacy ]
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- '**.yml'
|
||||
- 'version.properties'
|
||||
|
||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||
pull_request_target:
|
||||
branches: [ 1.2-legacy ]
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- '**.yml'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
check:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- board: rak11200
|
||||
- board: tlora-v2
|
||||
- board: tlora-v1
|
||||
- board: tlora_v1_3
|
||||
- board: tlora-v2-1-1.6
|
||||
- board: tbeam
|
||||
- board: heltec-v1
|
||||
- board: heltec-v2.0
|
||||
- board: heltec-v2.1
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: rak4631_5005
|
||||
- board: rak4631_19003
|
||||
- board: t-echo
|
||||
- board: nano-g1
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install cppcheck
|
||||
run: |
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools and install platformio
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Check ${{ matrix.board }}
|
||||
run: bin/check-all.sh ${{ matrix.board }}
|
||||
|
||||
after-checks:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
build-esp32:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- board: rak11200
|
||||
- board: tlora-v2
|
||||
- board: tlora-v1
|
||||
- board: tlora_v1_3
|
||||
- board: tlora-v2-1-1.6
|
||||
- board: tbeam
|
||||
- board: heltec-v1
|
||||
- board: heltec-v2.0
|
||||
- board: heltec-v2.1
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: nano-g1
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio meshtastic adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/meshtastic-web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
|
||||
build-nrf52:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- board: rak4631_5005
|
||||
- board: rak4631_19003
|
||||
- board: t-echo
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio meshtastic adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Build NRF52
|
||||
run: bin/build-nrf52.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
|
||||
build-native:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio meshtastic adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||
- name: Build for native
|
||||
run: platformio run -e native
|
||||
- name: Integration test
|
||||
run: |
|
||||
.pio/build/native/program &
|
||||
sleep 20 # 5 seconds was not enough
|
||||
echo "Simulator started, launching python test..."
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
|
||||
- name: Build Native
|
||||
run: bin/build-native.sh
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: firmware-native-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/meshtasticd_linux_amd64
|
||||
release/device-*.sh
|
||||
release/device-*.bat
|
||||
retention-days: 90
|
||||
|
||||
gather-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build-esp32, build-nrf52, build-native]
|
||||
steps:
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: ./
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
|
||||
- name: Move files up
|
||||
run: mv -b -t ./ ./*tbeam-*/spiffs*.bin ./*tbeam-*/system-info.bin ./**/firmware*.bin ./**/*.uf2 ./**/*.elf ./**/meshtasticd_linux_amd64 ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||
|
||||
- name: Repackage in single firmware zip
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}
|
||||
path: |
|
||||
./*.bin
|
||||
./*.uf2
|
||||
./meshtasticd_linux_amd64
|
||||
./device-*.sh
|
||||
./device-*.bat
|
||||
retention-days: 90
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: firmware-${{ steps.version.outputs.version }}
|
||||
path: ./output
|
||||
|
||||
# For diagnostics
|
||||
- name: Show artifacts
|
||||
run: ls -lR
|
||||
|
||||
- name: Zip firmware
|
||||
run: zip -j -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
|
||||
|
||||
- name: Repackage in single elfs zip
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
path: ./*.elf
|
||||
retention-days: 90
|
||||
|
||||
- name: Create request artifacts
|
||||
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
||||
uses: gavv/pull-request-artifacts@v1.0.0
|
||||
with:
|
||||
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts-token: ${{ secrets.ARTIFACTS_TOKEN }}
|
||||
artifacts-repo: meshtastic/artifacts
|
||||
artifacts-branch: device
|
||||
artifacts-dir: pr
|
||||
artifacts: ./firmware-${{ steps.version.outputs.version }}.zip
|
||||
45
.github/workflows/release.yml
vendored
45
.github/workflows/release.yml
vendored
@@ -1,15 +1,15 @@
|
||||
name: Make Release
|
||||
on:
|
||||
# Can optionally take parameters from the github UI, more info here https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/#:~:text=You%20can%20now%20create%20workflows,the%20workflow%20is%20run%20on.
|
||||
# workflow_dispatch:
|
||||
#workflow_dispatch:
|
||||
# inputs:
|
||||
|
||||
# Only want to be run if a new tag starting with v is pushed.
|
||||
# Only want to run if version.properties is bumped in master
|
||||
push:
|
||||
branches:
|
||||
- "!*"
|
||||
tags:
|
||||
- "v1*"
|
||||
- 1.2-legacy
|
||||
paths:
|
||||
- 'version.properties'
|
||||
|
||||
jobs:
|
||||
release-build:
|
||||
@@ -21,19 +21,15 @@ jobs:
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
# get github branch and tag names as ${{ steps.branch_name.outputs.SOURCE_TAG }}
|
||||
- name: Branch name
|
||||
id: branch_name
|
||||
run: |
|
||||
echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}
|
||||
echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}
|
||||
echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
|
||||
# Will be available in steps.version.outputs.version
|
||||
- name: Get release version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
# Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine
|
||||
|
||||
- name: Upgrade python tools
|
||||
@@ -47,10 +43,18 @@ jobs:
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
# Will be available in steps.version.outputs.version
|
||||
- name: Get version string
|
||||
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
|
||||
id: version
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/meshtastic-web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
- name: Build everything
|
||||
run: bin/build-all.sh
|
||||
@@ -62,8 +66,7 @@ jobs:
|
||||
draft: true
|
||||
prerelease: true
|
||||
release_name: ${{ steps.version.outputs.version }} alpha
|
||||
tag_name: ${{ steps.branch_name.outputs.SOURCE_TAG }}
|
||||
# was ${{ github.ref }}
|
||||
tag_name: v${{ steps.version.outputs.version }}
|
||||
body: |
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
env:
|
||||
@@ -87,4 +90,4 @@ jobs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: release/archive/elfs-${{ steps.version.outputs.version }}.zip
|
||||
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
asset_content_type: application/zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
33
.github/workflows/update_protobufs.yml
vendored
Normal file
33
.github/workflows/update_protobufs.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: "Update protobufs and regenerate classes"
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
update-protobufs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Update submodule
|
||||
run: |
|
||||
git submodule update --remote proto
|
||||
|
||||
- name: Download nanopb
|
||||
run: |
|
||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.4-linux-x86.tar.gz
|
||||
tar xvzf nanopb-0.4.4-linux-x86.tar.gz
|
||||
mv nanopb-0.4.4-linux-x86 nanopb-0.4.4
|
||||
|
||||
- name: Re-generate protocol buffers
|
||||
run: |
|
||||
./bin/regen-protos.sh
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
add-paths: |
|
||||
proto
|
||||
src/mesh
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -9,7 +9,7 @@ main/credentials.h
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
.idea/workspace.xml
|
||||
.idea
|
||||
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -23,3 +23,9 @@ flash.uf2
|
||||
cmake-build*
|
||||
__pycache__
|
||||
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
venv/
|
||||
release/
|
||||
|
||||
50
.gitlab-ci.yml
Normal file
50
.gitlab-ci.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
image: python:latest
|
||||
|
||||
variables:
|
||||
# make sure GitLab check out submodules
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
||||
stages:
|
||||
- buildall
|
||||
- upload
|
||||
|
||||
build:
|
||||
stage: buildall
|
||||
|
||||
before_script:
|
||||
# we need zip later for packaging
|
||||
- "apt update;apt -y install zip"
|
||||
- "pip install -U platformio"
|
||||
|
||||
script:
|
||||
# clean up residues from previous run
|
||||
- rm -rf release
|
||||
- bin/build-all.sh
|
||||
|
||||
# This is for my local environment, if your runners are tagged differently, modify or remove
|
||||
tags:
|
||||
- dockerized
|
||||
|
||||
# The files which are to be made available in GitLab
|
||||
artifacts:
|
||||
paths:
|
||||
- release/archive/firmware*.zip
|
||||
|
||||
|
||||
upload:
|
||||
image: curlimages/curl:latest
|
||||
|
||||
stage: upload
|
||||
|
||||
script:
|
||||
- |
|
||||
PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/master"
|
||||
cd release/archive
|
||||
for f in *.zip; do
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${f} ${PACKAGE_REGISTRY_URL}/${f}
|
||||
done
|
||||
echo 'Package uploaded!'
|
||||
|
||||
# This is for my local environment, if your runners are tagged differently, modify or remove
|
||||
tags:
|
||||
- dockerized
|
||||
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,6 +1,7 @@
|
||||
[submodule "proto"]
|
||||
path = proto
|
||||
url = https://github.com/meshtastic/Meshtastic-protobufs.git
|
||||
branch = 1.2-legacy
|
||||
[submodule "sdk-nrfxlib"]
|
||||
path = sdk-nrfxlib
|
||||
url = https://github.com/nrfconnect/sdk-nrfxlib.git
|
||||
|
||||
7
.idea/codeStyles/Project.xml
generated
7
.idea/codeStyles/Project.xml
generated
@@ -1,7 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<clangFormatSettings>
|
||||
<option name="ENABLED" value="true" />
|
||||
</clangFormatSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
2
.idea/meshtastic-esp32.iml
generated
2
.idea/meshtastic-esp32.iml
generated
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/meshtastic-esp32.iml" filepath="$PROJECT_DIR$/.idea/meshtastic-esp32.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/vcs.xml
generated
9
.idea/vcs.xml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/design" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/proto" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/sdk-nrfxlib" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -50,7 +50,8 @@
|
||||
"cassert": "cpp",
|
||||
"iterator": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"iostream": "cpp"
|
||||
"iostream": "cpp",
|
||||
"esp_nimble_hci.h": "c"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"Blox",
|
||||
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
FROM ubuntu
|
||||
MAINTAINER Kevin Hester <kevinh@geeksville.com>
|
||||
|
||||
RUN apt-get update
|
||||
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install wget python3 g++ zip python3-venv git vim
|
||||
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -O get-platformio.py; chmod +x get-platformio.py
|
||||
RUN python3 get-platformio.py
|
||||
RUN git clone https://github.com/meshtastic/Meshtastic-device.git
|
||||
RUN cd Meshtastic-device; git submodule update --init --recursive
|
||||
# only build the simulator
|
||||
RUN sed -i 's/^BOARDS_ESP32.*/BOARDS_ESP32=""/' Meshtastic-device/bin/build-all.sh
|
||||
RUN sed -i 's/^BOARDS_NRF52.*/BOARDS_NRF52=""/' Meshtastic-device/bin/build-all.sh
|
||||
RUN sed -i 's/echo "Building SPIFFS.*/exit/' Meshtastic-device/bin/build-all.sh
|
||||
RUN . ~/.platformio/penv/bin/activate; cd Meshtastic-device; ./bin/build-all.sh
|
||||
|
||||
CMD ["/Meshtastic-device/release/latest/bins/universal/meshtasticd_linux_amd64"]
|
||||
@@ -1,5 +1,14 @@
|
||||
# Meshtastic-device
|
||||
[](https://open.vscode.dev/meshtastic/Meshtastic-device)
|
||||
[](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml)
|
||||

|
||||
|
||||
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project.
|
||||
|
||||
Update Instructions
|
||||
|
||||
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32)
|
||||
|
||||
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
|
||||
|
||||
For developer information and specific building instructions, please see the [developer doccumentation](https://meshtastic.org/docs/developers)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v2.0 heltec-v2.1 tbeam0.7"
|
||||
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1"
|
||||
#BOARDS_ESP32=tbeam
|
||||
|
||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||
BOARDS_NRF52="rak4631 t-echo"
|
||||
BOARDS_NRF52="rak4631_5005 rak4631_19003 t-echo"
|
||||
#BOARDS_NRF52=""
|
||||
|
||||
OUTDIR=release/latest
|
||||
@@ -28,7 +28,7 @@ function do_build() {
|
||||
BOARD=$1
|
||||
isNrf=$3
|
||||
|
||||
echo "Building for $BOARD with $PLATFORMIO_BUILD_FLAGS"
|
||||
echo "Building for $BOARD ($isNrf) with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$BOARD/firmware.*
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
@@ -59,6 +59,7 @@ function do_boards() {
|
||||
declare isNrf=$2
|
||||
for board in $boards; do
|
||||
# Build universal
|
||||
echo "about to build $board $isNrf"
|
||||
do_build $board "" "$isNrf"
|
||||
done
|
||||
}
|
||||
|
||||
43
bin/build-esp32.sh
Executable file
43
bin/build-esp32.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
# Are we building a universal/regionless rom?
|
||||
export HW_VERSION="1.0"
|
||||
basename=firmware-$1-$VERSION
|
||||
|
||||
pio run --environment $1 # -v
|
||||
SRCELF=.pio/build/$1/firmware.elf
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
|
||||
echo "Copying ESP32 bin file"
|
||||
SRCBIN=.pio/build/$1/firmware.bin
|
||||
cp $SRCBIN $OUTDIR/$basename.bin
|
||||
|
||||
echo "Building SPIFFS for ESP32 targets"
|
||||
pio run --environment tbeam -t buildfs
|
||||
cp .pio/build/tbeam/spiffs.bin $OUTDIR/spiffs-$VERSION.bin
|
||||
cp images/system-info.bin $OUTDIR/system-info.bin
|
||||
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
26
bin/build-native.sh
Executable file
26
bin/build-native.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
rm -f $OUTDIR/firmware*
|
||||
|
||||
mkdir -p $OUTDIR/
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
|
||||
pio run --environment native
|
||||
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
||||
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/bin/bash
|
||||
source ~/.bashrc
|
||||
|
||||
# Meshtastic Nightly Build Script.
|
||||
# McHamster (jm@casler.org)
|
||||
#
|
||||
# This is the script that is used for the nightly build server.
|
||||
#
|
||||
# It's probably not useful for most people, but you may want to run your own
|
||||
# nightly builds.
|
||||
#
|
||||
# The last line of ~/.bashrc contains an inclusion of platformio in the path.
|
||||
# Without this, the build script won't run from the crontab:
|
||||
#
|
||||
# export PATH="$HOME/.platformio/penv/bin:$PATH"
|
||||
#
|
||||
# The crontab contains:
|
||||
# 0 2 * * * cd ~/meshtastic/github/meshtastic && source "~/.bashrc"; ./build-nightly.sh > ~/cronout.txt 2> ~/cronout.txt
|
||||
|
||||
cd Meshtastic-device
|
||||
|
||||
git pull
|
||||
|
||||
bin/build-all.sh
|
||||
|
||||
date_stamp=$(date +'%Y-%m-%d')
|
||||
|
||||
cd ..
|
||||
|
||||
# TODO: Archive the same binaries used by the build-all script.
|
||||
#zip -r meshtastic_device_nightly_${date_stamp} Meshtastic-device/release/latest/bins
|
||||
cp Meshtastic-device/release/archive/`ls -t ./Meshtastic-device/release/archive/| head -1` meshtastic_device_nightly_${date_stamp}.zip
|
||||
|
||||
# Copy the file to the webserver
|
||||
scp meshtastic_device_nightly_${date_stamp}.zip jm@10.11.12.20:/volume1/web/meshtastic/nightly_builds/
|
||||
|
||||
# Delete the local copy
|
||||
rm meshtastic_device_nightly_${date_stamp}.zip
|
||||
37
bin/build-nrf52.sh
Executable file
37
bin/build-nrf52.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
export HW_VERSION="1.0"
|
||||
basename=firmware-$1-$VERSION
|
||||
|
||||
pio run --environment $1 # -v
|
||||
SRCELF=.pio/build/$1/firmware.elf
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
|
||||
echo "Generating NRF52 uf2 file"
|
||||
SRCHEX=.pio/build/$1/firmware.hex
|
||||
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/$basename.uf2 -f 0xADA52840
|
||||
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
26
bin/check-all.sh
Executable file
26
bin/check-all.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Note: This is a prototype for how we could add static code analysis to the CI.
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
if [[ $# -gt 0 ]]; then
|
||||
# can override which environment by passing arg
|
||||
BOARDS="$@"
|
||||
else
|
||||
BOARDS="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 rak4631_5005 rak4631_19003 rak11200 t-echo"
|
||||
fi
|
||||
|
||||
echo "BOARDS:${BOARDS}"
|
||||
|
||||
CHECK=""
|
||||
for BOARD in $BOARDS; do
|
||||
CHECK="${CHECK} -e ${BOARD}"
|
||||
done
|
||||
|
||||
pio check --flags "-DAPP_VERSION=${APP_VERSION} --suppressions-list=suppressions.txt" $CHECK --skip-packages --pattern="src/" --fail-on-defect=low --fail-on-defect=medium --fail-on-defect=high
|
||||
@@ -11,7 +11,7 @@ Usage: $(basename $0) [-h] [-p ESPTOOL_PORT] [-P PYTHON] [-f FILENAME|FILENAME]
|
||||
Flash image file to device, but first erasing and writing system information"
|
||||
|
||||
-h Display this help and exit
|
||||
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerrous).
|
||||
-p ESPTOOL_PORT Set the environment variable for ESPTOOL_PORT. If not set, ESPTOOL iterates all ports (Dangerous).
|
||||
-P PYTHON Specify alternate python interpreter to use to invoke esptool. (Default: "$PYTHON")
|
||||
-f FILENAME The .bin file to flash. Custom to your device type and region.
|
||||
EOF
|
||||
@@ -46,10 +46,10 @@ shift "$((OPTIND-1))"
|
||||
|
||||
if [ -f "${FILENAME}" ]; then
|
||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||
$PYTHON -m esptool --baud 921600 erase_flash
|
||||
$PYTHON -m esptool --baud 921600 write_flash 0x1000 system-info.bin
|
||||
$PYTHON -m esptool --baud 921600 write_flash 0x00390000 spiffs-*.bin
|
||||
$PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
|
||||
"$PYTHON" -m esptool erase_flash
|
||||
"$PYTHON" -m esptool write_flash 0x1000 system-info.bin
|
||||
"$PYTHON" -m esptool write_flash 0x00390000 spiffs-*.bin
|
||||
"$PYTHON" -m esptool write_flash 0x10000 ${FILENAME}
|
||||
else
|
||||
echo "Invalid file: ${FILENAME}"
|
||||
show_help
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80
|
||||
|
||||
nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python2
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# This is a layout for 4MB of flash
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
@@ -38,4 +38,4 @@ app0, app, ota_0, , 0x{app:x},
|
||||
app1, app, ota_1, , 0x{app:x},
|
||||
spiffs, data, spiffs, , 0x{spi:x} """.format(**locals())
|
||||
|
||||
print(table)
|
||||
print(table)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
||||
|
||||
set -e
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
|
||||
|
||||
set -e
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\#
|
||||
# mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j"
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
pio run --environment native
|
||||
gdbserver --once localhost:2345 .pio/build/native/program "$@"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
pio run --environment native
|
||||
.pio/build/native/program "$@"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# JLinkRTTViewer
|
||||
JLinkRTTClient
|
||||
JLinkRTTClient
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
|
||||
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
|
||||
esptool.py --baud 921600 erase_region 0xe000 0x2000
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
|
||||
@@ -6,6 +8,10 @@ VERSION=`bin/buildinfo.py long`
|
||||
|
||||
# Must have a V prefix to trigger github
|
||||
git tag "v${VERSION}"
|
||||
git push root "v${VERSION}" # push the tag
|
||||
|
||||
# Commented out per https://github.com/meshtastic/Meshtastic-device/issues/947
|
||||
#git push root "v${VERSION}" # push the tag
|
||||
|
||||
git push origin "v${VERSION}" # push the tag
|
||||
|
||||
echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
|
||||
|
||||
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img
|
||||
|
||||
1
bin/regen-protos.bat
Normal file
1
bin/regen-protos.bat
Normal file
@@ -0,0 +1 @@
|
||||
cd proto && ..\nanopb-0.4.4\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.proto
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
@@ -12,4 +12,4 @@ cd proto
|
||||
|
||||
#echo "Regenerating protobuf documentation - if you see an error message"
|
||||
#echo "you can ignore it unless doing a new protobuf release to github."
|
||||
#bin/regen-docs.sh
|
||||
#bin/regen-docs.sh
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pio run --upload-port /dev/ttyUSB0 -t upload -t monitor
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pio run --upload-port /dev/ttyUSB1 -t upload -t monitor
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo uploading to usb1
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
TARG=tbeam
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg
|
||||
/home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pio device monitor -b 921600
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pio device monitor -p /dev/ttyUSB1 -b 921600
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Starting simulator"
|
||||
|
||||
2
bin/uf2-convert.bat
Normal file
2
bin/uf2-convert.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
if [%1]==[] (echo "Please specify a platformio NRF target (i.e. rak4631) as the first argument.") else (python3 .\bin\uf2conv.py .\.pio\build\%1\firmware.hex -c -o .\.pio\build\%1\firmware.uf2 -f 0xADA52840)
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "building for t-echo"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "Converting to uf2 for NRF52 Adafruit bootloader"
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
pio run --upload-port /dev/ttyUSB1 -t upload
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo using amap tool to display memory map
|
||||
amap .pio/build/output.map
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS113",
|
||||
"sd_name": "s113",
|
||||
"sd_version": "7.2.0",
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
|
||||
39
boards/wiscore_rak11200.json
Normal file
39
boards/wiscore_rak11200.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino":{
|
||||
"ldscript": "esp32_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": "-DARDUINO_ESP32_DEV",
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "WisCore_RAK11200_Board"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"name": "WisCore RAK11200 Board",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"protocols": [
|
||||
"esptool",
|
||||
"espota",
|
||||
"ftdi"
|
||||
],
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
"url": "https://www.rakwireless.com",
|
||||
"vendor": "RAKwireless"
|
||||
}
|
||||
0
data/static/.gitkeep
Normal file
0
data/static/.gitkeep
Normal file
@@ -1 +0,0 @@
|
||||
not yet supported - soon will be included in build
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 532 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z"/></svg>
|
||||
|
Before Width: | Height: | Size: 442 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
17
docker.txt
Normal file
17
docker.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
To build:
|
||||
docker build -t meshtastic/device .
|
||||
|
||||
To run:
|
||||
docker run --rm -p 4403:4403 meshtastic/device
|
||||
or, to get a shell on the docker image:
|
||||
docker run -it meshtastic/device bash
|
||||
|
||||
To use python cli against it:
|
||||
meshtastic --info --host localhost
|
||||
|
||||
To stop:
|
||||
# run this to get id
|
||||
docker ps
|
||||
# tip: you can just use the first few characters of the id in the next command
|
||||
docker kill <id>
|
||||
|
||||
@@ -325,7 +325,7 @@ Items after the first final candidate release.
|
||||
- add "store and forward" support for messages, or move to the DB sync model. This would allow messages to be eventually delivered even if nodes are out of contact at the moment.
|
||||
- use variable length Strings in protobufs (instead of current fixed buffers). This would save lots of RAM
|
||||
- use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability
|
||||
- make a HAM build: just a new frequency list, a bool to say 'never do encryption' and use hte callsign as that node's unique id. -from Girts
|
||||
- make a Ham build: just a new frequency list, a bool to say 'never do encryption' and use the callsign as that node's unique id. -from Girts
|
||||
- don't forward redundant pings or ping responses to the phone, it just wastes phone battery
|
||||
- don't send location packets if we haven't moved significantly
|
||||
- scrub default radio config settings for bandwidth/range/speed
|
||||
|
||||
@@ -20,4 +20,6 @@ make
|
||||
|
||||
* todo run hello world on hardware (check for bl604 vs bl602 first)
|
||||
* build/run in the crummy arduino environment
|
||||
* build in platformio
|
||||
* build in platformio
|
||||
|
||||
https://lupyuen.github.io/articles/lorawan2
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
|
||||
* install python
|
||||
* install git (including git-bash)
|
||||
* install platformio
|
||||
* install vscode
|
||||
* install https://sourceforge.net/projects/mingw-w64/ (for windows gcc/g++) - you'll need to add the bin directory to your PATH
|
||||
302
platformio.ini
302
platformio.ini
@@ -9,18 +9,30 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
;default_envs = tbeam
|
||||
default_envs = tbeam
|
||||
;default_envs = tbeam0.7
|
||||
;default_envs = heltec-v1
|
||||
;default_envs = heltec-v2.0
|
||||
;default_envs = heltec-v2.1
|
||||
;default_envs = tlora-v1
|
||||
;default_envs = tlora-v1
|
||||
;default_envs = tlora_v1_3
|
||||
;default_envs = tlora-v2
|
||||
;default_envs = tlora-v2-1-1.6
|
||||
;default_envs = lora-relay-v1 # nrf board
|
||||
default_envs = t-echo
|
||||
;default_envs = t-echo
|
||||
;default_envs = nrf52840dk-geeksville
|
||||
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||
;default_envs = rak4631
|
||||
;default_envs = rak4630
|
||||
;default_envs = rak4631_5005
|
||||
;default_envs = rak4631_5005_eink
|
||||
;default_envs = rak4631_19003
|
||||
;default_envs = nano-g1
|
||||
;default_envs = meshtastic-diy-v1
|
||||
;default_envs = meshtastic-diy-v1.1
|
||||
|
||||
; board specific config can be moved to the respective 'variants' file.
|
||||
; See https://docs.platformio.org/en/latest/projectconf/section_platformio.html#extra-configs
|
||||
extra_configs = variants/*/platformio.ini
|
||||
|
||||
[common]
|
||||
; common is not currently used
|
||||
@@ -67,20 +79,24 @@ debug_tool = jlink
|
||||
; monitor adapter_khz 10000
|
||||
|
||||
lib_deps =
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306
|
||||
https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||
https://github.com/meshtastic/arduino-fsm.git
|
||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||
https://github.com/meshtastic/RadioLib.git#80ed10d689a0568782c5bd152906b0f97d2bce93
|
||||
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
|
||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||
SPI
|
||||
https://github.com/geeksville/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
PubSubClient
|
||||
|
||||
; Common settings for conventional (non Portduino) Ardino targets
|
||||
|
||||
; Used for the code analysis in PIO Home / Inspect
|
||||
check_tool = cppcheck
|
||||
check_skip_packages = yes
|
||||
|
||||
; Common settings for conventional (non Portduino) Arduino targets
|
||||
[arduino_base]
|
||||
|
||||
framework = arduino
|
||||
@@ -93,31 +109,52 @@ build_flags = ${env.build_flags} -Os
|
||||
|
||||
src_filter = ${env.src_filter} -<portduino/>
|
||||
|
||||
; Common libs for environmental measurements (not included in native / portduino)
|
||||
[environmental]
|
||||
lib_deps =
|
||||
adafruit/DHT sensor library@^1.4.1
|
||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
||||
paulstoffregen/OneWire@^2.3.5
|
||||
robtillaart/DS18B20@^0.1.11
|
||||
adafruit/Adafruit BME280 Library@^2.2.2
|
||||
adafruit/Adafruit BME680 Library@^2.0.1
|
||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||
|
||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||
[esp32_base]
|
||||
extends = arduino_base
|
||||
platform = espressif32
|
||||
platform = espressif32@3.5.0
|
||||
src_filter =
|
||||
${arduino_base.src_filter} -<nrf52/>
|
||||
upload_speed = 921600
|
||||
debug_init_break = tbreak setup
|
||||
|
||||
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
|
||||
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
|
||||
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
|
||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
|
||||
-DAXP_DEBUG_PORT=Serial
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git
|
||||
adafruit/DHT sensor library@^1.4.1
|
||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
||||
h2zero/NimBLE-Arduino@1.3.6
|
||||
tobozo/ESP32-targz@^1.1.4
|
||||
arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a
|
||||
|
||||
# Hmm - this doesn't work yet
|
||||
# board_build.ldscript = linker/esp32.extram.bss.ld
|
||||
lib_ignore = segger_rtt
|
||||
lib_ignore =
|
||||
segger_rtt
|
||||
ESP32 BLE Arduino
|
||||
|
||||
platform_packages =
|
||||
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
|
||||
|
||||
; leave this commented out to avoid breaking Windows
|
||||
upload_port = /dev/ttyUSB0
|
||||
;upload_port = /dev/ttyUSB0
|
||||
;monitor_port = /dev/ttyUSB0
|
||||
|
||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
||||
@@ -134,62 +171,6 @@ board_build.partitions = partition-table.csv
|
||||
|
||||
; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
|
||||
; The 1.0 release of the TBEAM board
|
||||
[env:tbeam]
|
||||
extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TBEAM_V10
|
||||
|
||||
; The original TBEAM board without the AXP power chip and a few other changes
|
||||
; Note: I've heard reports this didn't work. Disabled until someone with a 0.7 can test and debug.
|
||||
[env:tbeam0.7]
|
||||
extends = esp32_base
|
||||
board = ttgo-t-beam
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TBEAM_V07
|
||||
|
||||
[env:heltec-v2.0]
|
||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||
extends = esp32_base
|
||||
board = heltec_wifi_lora_32_V2
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D HELTEC_V2_0
|
||||
|
||||
[env:heltec-v2.1]
|
||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||
extends = esp32_base
|
||||
board = heltec_wifi_lora_32_V2
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D HELTEC_V2_1
|
||||
|
||||
[env:tlora-v1]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v1
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V1
|
||||
|
||||
; note: the platformio definition for lora32-v2 seems stale, it is missing a pins_arduino.h file, therefore I don't think it works
|
||||
[env:tlora_v1_3]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v1
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V1_3
|
||||
|
||||
[env:tlora-v2]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v1
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V2
|
||||
|
||||
[env:tlora-v2-1-1.6]
|
||||
extends = esp32_base
|
||||
board = ttgo-lora32-v1
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D TLORA_V2_1_16
|
||||
|
||||
; The Heltec Cubecell plus
|
||||
; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now.
|
||||
; For more details see my post in the forum.
|
||||
@@ -259,42 +240,17 @@ extends = nrf52_base
|
||||
build_flags = ${nrf52_base.build_flags}
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental.lib_deps}
|
||||
Adafruit nRFCrypto
|
||||
# Adafruit TinyUSB Arduino
|
||||
# add Adafruit nRFCrypto platform IO automated scan is broken
|
||||
|
||||
[env:lora_isp4520]
|
||||
extends = nrf52_base
|
||||
board = lora_isp4520
|
||||
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${nrf52_base.build_flags} -Ivariants/lora_isp4520
|
||||
|
||||
# No screen and GPS on the board. We still need RTC.cpp for the RTC clock.
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_isp4520> -<graphics> -<gps> +<gps/GPS.cpp> +<gps/RTC.cpp>
|
||||
lib_ignore = ${nrf52_base.lib_ignore}
|
||||
ESP8266_SSD1306
|
||||
SparkFun Ublox Arduino Library
|
||||
AXP202X_Library
|
||||
TinyGPSPlus
|
||||
|
||||
upload_protocol = jlink
|
||||
monitor_port = /dev/ttyUSB0
|
||||
|
||||
; The NRF52840-dk development board
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:nrf52840dk]
|
||||
extends = nrf52840_base
|
||||
board = nrf52840_dk
|
||||
|
||||
; The NRF52840-dk development board, but @geeksville's board - which has a busted oscilliator
|
||||
[env:nrf52840dk-geeksville]
|
||||
extends = nrf52840_base
|
||||
board = nrf52840_dk_modified
|
||||
# add our variants files to the include and src paths
|
||||
build_flags = ${nrf52_base.build_flags} -Ivariants/pca10056-rc-clock
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/pca10056-rc-clock>
|
||||
|
||||
; Note: By default no lora device is created for this build - it uses a simulated interface
|
||||
[env:feather_nrf52832]
|
||||
extends = nrf52_base
|
||||
@@ -308,155 +264,3 @@ upload_protocol = jlink
|
||||
monitor_port = /dev/ttyUSB0
|
||||
; this board's serial chip can only run at 115200, not faster
|
||||
monitor_speed = 115200
|
||||
|
||||
# For experimenting with RAM sizes
|
||||
# board_build.ldscript = linker/nrf52840_s140_sim832.ld
|
||||
|
||||
; The very slick RAK wireless RAK 4631 / 4630 board
|
||||
[env:rak4631]
|
||||
extends = nrf52840_base
|
||||
board = wiscore_rak4631
|
||||
# add our variants files to the include and src paths
|
||||
# define build flags for the TFT_eSPI library
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
|
||||
; Note, this board is not yet supported! It will not work without futher development.
|
||||
; THIS IS UNTESTED (I don't have this board), but other developers can use it as a starting point
|
||||
[env:rak4600]
|
||||
extends = nrf52_base
|
||||
board = wiscore_rak4600
|
||||
# add our variants files to the include and src paths
|
||||
# define build flags for the TFT_eSPI library
|
||||
build_flags = ${nrf52_base.build_flags} -Ivariants/WisCore_RAK4600_Board
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4600_Board>
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
|
||||
; The PPR board
|
||||
[env:ppr]
|
||||
extends = nrf52_base
|
||||
board = ppr
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
UC1701
|
||||
|
||||
; The PPR board
|
||||
[env:ppr1]
|
||||
extends = nrf52_base
|
||||
board = ppr1
|
||||
build_flags = ${nrf52_base.build_flags} -Ivariants/ppr1
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/ppr1>
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
|
||||
; First prototype eink/nrf52840/sx1262 device
|
||||
[env:t-echo]
|
||||
extends = nrf52840_base
|
||||
board = t-echo
|
||||
debug_tool = jlink
|
||||
upload_protocol = jlink
|
||||
# add our variants files to the include and src paths
|
||||
# define build flags for the TFT_eSPI library - NOTE: WE NOT LONGER USE TFT_eSPI, it was for an earlier version of the TTGO eink screens
|
||||
# -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
||||
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/t-echo
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/geeksville/GxEPD2.git
|
||||
adafruit/Adafruit BusIO
|
||||
;upload_protocol = fs
|
||||
|
||||
; First prototype eink/nrf52840/sx1262 device (removed from build because didn't ship in quantity)
|
||||
;[env:eink0.1]
|
||||
;extends = nrf52840_base
|
||||
;board = eink0.1
|
||||
;# add our variants files to the include and src paths
|
||||
;# define build flags for the TFT_eSPI library
|
||||
;build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
|
||||
; -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
||||
;src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
|
||||
;lib_deps =
|
||||
; ${nrf52840_base.lib_deps}
|
||||
; https://github.com/geeksville/EPD_Libraries.git
|
||||
; TFT_eSPI
|
||||
|
||||
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
|
||||
[env:lora-relay-v1]
|
||||
extends = nrf52840_base
|
||||
board = lora-relay-v1
|
||||
# add our variants files to the include and src paths
|
||||
# define build flags for the TFT_eSPI library
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v1
|
||||
-DUSER_SETUP_LOADED
|
||||
-DTFT_WIDTH=80
|
||||
-DTFT_HEIGHT=160
|
||||
-DST7735_GREENTAB160x80
|
||||
-DST7735_DRIVER
|
||||
-DTFT_CS=ST7735_CS
|
||||
-DTFT_DC=ST7735_RS
|
||||
-DTFT_RST=ST7735_RESET
|
||||
-DSPI_FREQUENCY=27000000
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
||||
TFT_eSPI
|
||||
|
||||
; The https://github.com/BigCorvus/LoRa-BLE-Relay-v2 board by @BigCorvus
|
||||
[env:lora-relay-v2]
|
||||
extends = nrf52840_base
|
||||
board = lora-relay-v2
|
||||
# add our variants files to the include and src paths
|
||||
# define build flags for the TFT_eSPI library
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/lora_relay_v2
|
||||
-DUSER_SETUP_LOADED
|
||||
-DTFT_WIDTH=80
|
||||
-DTFT_HEIGHT=160
|
||||
-DST7735_GREENTAB160x80
|
||||
-DST7735_DRIVER
|
||||
-DTFT_CS=ST7735_CS
|
||||
-DTFT_DC=ST7735_RS
|
||||
-DTFT_RST=ST7735_RESET
|
||||
-DSPI_FREQUENCY=27000000
|
||||
-DTFT_WR=ST7735_SDA
|
||||
-DTFT_SCLK=ST7735_SCK
|
||||
src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v2>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
SparkFun BQ27441 LiPo Fuel Gauge Arduino Library
|
||||
TFT_eSPI
|
||||
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[env:native]
|
||||
platform = https://github.com/geeksville/platform-native.git
|
||||
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
|
||||
build_flags = ${arduino_base.build_flags} -O0
|
||||
framework = arduino
|
||||
board = cross_platform
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
rweather/Crypto
|
||||
|
||||
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
||||
[env:linux]
|
||||
platform = https://github.com/geeksville/platform-native.git
|
||||
src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<mesh/http/> -<plugins/esp32>
|
||||
build_flags = ${arduino_base.build_flags} -O0 -lgpiod
|
||||
framework = arduino
|
||||
board = linux_hardware
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
rweather/Crypto
|
||||
|
||||
; The GenieBlocks LORA prototype board
|
||||
; note: @geeksville disabled because genieblocks_lora is not checked into the boards directory, please send in a PR to add it ;-)
|
||||
;[env:genieblocks_lora]
|
||||
;extends = esp32_base
|
||||
;board = genieblocks_lora
|
||||
;build_flags =
|
||||
; ${esp32_base.build_flags} -D GENIEBLOCKS
|
||||
|
||||
2
proto
2
proto
Submodule proto updated: f5b3d0643b...c851209e0b
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
main.ino.cpp
|
||||
61
src/DebugConfiguration.h
Normal file
61
src/DebugConfiguration.h
Normal file
@@ -0,0 +1,61 @@
|
||||
// DEBUG LED
|
||||
#ifndef LED_INVERTED
|
||||
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// DEBUG
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CONSOLE_MAX_BAUD
|
||||
#define SERIAL_BAUD CONSOLE_MAX_BAUD
|
||||
#else
|
||||
#define SERIAL_BAUD 921600 // Serial debug baud rate
|
||||
#endif
|
||||
|
||||
#include "SerialConsole.h"
|
||||
|
||||
#define DEBUG_PORT (*console) // Serial debug port
|
||||
|
||||
// What platforms should use SEGGER?
|
||||
#ifdef NRF52_SERIES
|
||||
|
||||
// Always include the SEGGER code on NRF52 - because useful for debugging
|
||||
#include "SEGGER_RTT.h"
|
||||
|
||||
// The channel we send stdout data to
|
||||
#define SEGGER_STDOUT_CH 0
|
||||
|
||||
// Debug printing to segger console
|
||||
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
|
||||
|
||||
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
|
||||
// use SEGGER for debug output
|
||||
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
|
||||
// No serial ports on this board - ONLY use segger in memory console
|
||||
#define USE_SEGGER
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
|
||||
#endif
|
||||
|
||||
#ifdef USE_SEGGER
|
||||
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||
#else
|
||||
#ifdef DEBUG_PORT
|
||||
#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_MSG(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// AXP192 (Rev1-specific options)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define GPS_POWER_CTRL_CH 3
|
||||
#define LORA_POWER_CTRL_CH 2
|
||||
|
||||
// Default Bluetooth PIN
|
||||
#define defaultBLEPin 123456
|
||||
136
src/GPSStatus.h
136
src/GPSStatus.h
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
#include "Status.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
extern NodeDB nodeDB;
|
||||
|
||||
namespace meshtastic
|
||||
{
|
||||
|
||||
@@ -16,28 +19,39 @@ class GPSStatus : public Status
|
||||
|
||||
bool hasLock = false; // default to false, until we complete our first read
|
||||
bool isConnected = false; // Do we have a GPS we are talking to
|
||||
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
||||
int32_t altitude = 0;
|
||||
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
|
||||
// scaling before use)
|
||||
uint32_t heading = 0;
|
||||
uint32_t numSatellites = 0;
|
||||
|
||||
Position p = Position_init_default;
|
||||
|
||||
public:
|
||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||
|
||||
// proposed for deprecation
|
||||
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
|
||||
uint32_t heading, uint32_t numSatellites)
|
||||
: Status()
|
||||
{
|
||||
this->hasLock = hasLock;
|
||||
this->isConnected = isConnected;
|
||||
this->latitude = latitude;
|
||||
this->longitude = longitude;
|
||||
this->altitude = altitude;
|
||||
this->dop = dop;
|
||||
this->heading = heading;
|
||||
this->numSatellites = numSatellites;
|
||||
|
||||
this->p.latitude_i = latitude;
|
||||
this->p.longitude_i = longitude;
|
||||
this->p.altitude = altitude;
|
||||
this->p.PDOP = dop;
|
||||
this->p.ground_track = heading;
|
||||
this->p.sats_in_view = numSatellites;
|
||||
}
|
||||
|
||||
// preferred method
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position& pos)
|
||||
: Status()
|
||||
{
|
||||
this->hasLock = hasLock;
|
||||
this->isConnected = isConnected;
|
||||
|
||||
// all-in-one struct copy
|
||||
this->p = pos;
|
||||
}
|
||||
|
||||
GPSStatus(const GPSStatus &);
|
||||
GPSStatus &operator=(const GPSStatus &);
|
||||
|
||||
@@ -47,45 +61,91 @@ class GPSStatus : public Status
|
||||
|
||||
bool getIsConnected() const { return isConnected; }
|
||||
|
||||
int32_t getLatitude() const { return latitude; }
|
||||
int32_t getLatitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
#if GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed latitude\n");
|
||||
#endif
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
return node->position.latitude_i;
|
||||
} else {
|
||||
return p.latitude_i;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getLongitude() const { return longitude; }
|
||||
int32_t getLongitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
#if GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed longitude\n");
|
||||
#endif
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
return node->position.longitude_i;
|
||||
} else {
|
||||
return p.longitude_i;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getAltitude() const { return altitude; }
|
||||
int32_t getAltitude() const {
|
||||
if (radioConfig.preferences.fixed_position){
|
||||
#if GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("WARNING: Using fixed altitude\n");
|
||||
#endif
|
||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||
return node->position.altitude;
|
||||
} else {
|
||||
return p.altitude;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getDOP() const { return dop; }
|
||||
uint32_t getDOP() const { return p.PDOP; }
|
||||
|
||||
uint32_t getHeading() const { return heading; }
|
||||
uint32_t getHeading() const { return p.ground_track; }
|
||||
|
||||
uint32_t getNumSatellites() const { return numSatellites; }
|
||||
uint32_t getNumSatellites() const { return p.sats_in_view; }
|
||||
|
||||
bool matches(const GPSStatus *newStatus) const
|
||||
{
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->latitude != latitude ||
|
||||
newStatus->longitude != longitude || newStatus->altitude != altitude || newStatus->dop != dop ||
|
||||
newStatus->heading != heading || newStatus->numSatellites != numSatellites);
|
||||
#if GPS_EXTRAVERBOSE
|
||||
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
|
||||
newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||
#endif
|
||||
return (newStatus->hasLock != hasLock ||
|
||||
newStatus->isConnected != isConnected ||
|
||||
newStatus->p.latitude_i != p.latitude_i ||
|
||||
newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude ||
|
||||
newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP ||
|
||||
newStatus->p.ground_track != p.ground_track ||
|
||||
newStatus->p.sats_in_view != p.sats_in_view);
|
||||
}
|
||||
|
||||
int updateStatus(const GPSStatus *newStatus)
|
||||
{
|
||||
// Only update the status if values have actually changed
|
||||
bool isDirty;
|
||||
{
|
||||
isDirty = matches(newStatus);
|
||||
initialized = true;
|
||||
hasLock = newStatus->hasLock;
|
||||
isConnected = newStatus->isConnected;
|
||||
latitude = newStatus->latitude;
|
||||
longitude = newStatus->longitude;
|
||||
altitude = newStatus->altitude;
|
||||
dop = newStatus->dop;
|
||||
heading = newStatus->heading;
|
||||
numSatellites = newStatus->numSatellites;
|
||||
bool isDirty = matches(newStatus);
|
||||
|
||||
if (isDirty && p.pos_timestamp &&
|
||||
(newStatus->p.pos_timestamp == p.pos_timestamp)) {
|
||||
// We can NEVER be in two locations at the same time! (also PR #886)
|
||||
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
hasLock = newStatus->hasLock;
|
||||
isConnected = newStatus->isConnected;
|
||||
|
||||
p = newStatus->p;
|
||||
|
||||
if (isDirty) {
|
||||
if (hasLock)
|
||||
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f, heading=%f, sats=%d\n", latitude * 1e-7, longitude * 1e-7,
|
||||
altitude, dop * 1e-2, heading * 1e-5, numSatellites);
|
||||
else
|
||||
if (hasLock) {
|
||||
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
||||
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n",
|
||||
p.pos_timestamp,
|
||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7,
|
||||
p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||
p.sats_in_view);
|
||||
} else
|
||||
DEBUG_MSG("No GPS lock\n");
|
||||
onNewStatus.notifyObservers(this);
|
||||
}
|
||||
@@ -95,4 +155,4 @@ class GPSStatus : public Status
|
||||
|
||||
} // namespace meshtastic
|
||||
|
||||
extern meshtastic::GPSStatus *gpsStatus;
|
||||
extern meshtastic::GPSStatus *gpsStatus;
|
||||
|
||||
@@ -47,7 +47,7 @@ template <class Callback, class T> class CallbackObserver : public Observer<T>
|
||||
CallbackObserver(Callback *_objPtr, ObserverCallback _method) : objPtr(_objPtr), method(_method) {}
|
||||
|
||||
protected:
|
||||
virtual int onNotify(T arg) { return (objPtr->*method)(arg); }
|
||||
virtual int onNotify(T arg) override { return (objPtr->*method)(arg); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -104,4 +104,4 @@ template <class T> void Observer<T>::observe(Observable<T> *o)
|
||||
|
||||
observed = o;
|
||||
o->addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
*
|
||||
* FIXME - use a lipo lookup table, the current % full is super wrong
|
||||
*/
|
||||
virtual int getBattPercentage()
|
||||
virtual int getBattPercentage() override
|
||||
{
|
||||
float v = getBattVoltage();
|
||||
|
||||
@@ -94,12 +94,16 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
/**
|
||||
* The raw voltage of the batteryin millivolts or NAN if unknown
|
||||
*/
|
||||
virtual float getBattVoltage()
|
||||
virtual float getBattVoltage() override
|
||||
{
|
||||
|
||||
#ifndef ADC_MULTIPLIER
|
||||
#define ADC_MULTIPLIER 2.0
|
||||
#endif
|
||||
// Override variant or default ADC_MULTIPLIER if we have the override pref
|
||||
float operativeAdcMultiplier = radioConfig.preferences.adc_multiplier_override > 0 ?
|
||||
radioConfig.preferences.adc_multiplier_override :
|
||||
ADC_MULTIPLIER;
|
||||
|
||||
#ifdef BATTERY_PIN
|
||||
// Do not call analogRead() often.
|
||||
@@ -109,7 +113,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
uint32_t raw = analogRead(BATTERY_PIN);
|
||||
float scaled;
|
||||
#ifndef VBAT_RAW_TO_SCALED
|
||||
scaled = 1000.0 * ADC_MULTIPLIER * (AREF_VOLTAGE / 1024.0) * raw;
|
||||
scaled = 1000.0 * operativeAdcMultiplier * (AREF_VOLTAGE / 1024.0) * raw;
|
||||
#else
|
||||
scaled = VBAT_RAW_TO_SCALED(raw); //defined in variant.h
|
||||
#endif
|
||||
@@ -127,15 +131,15 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() { return getBattPercentage() != -1; }
|
||||
virtual bool isBatteryConnect() override { return getBattPercentage() != -1; }
|
||||
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
/// in power
|
||||
virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; }
|
||||
virtual bool isVBUSPlug() override { return getBattVoltage() > chargingVolt; }
|
||||
|
||||
/// Assume charging if we have a battery and external power is connected.
|
||||
/// we can't be smart enough to say 'full'?
|
||||
virtual bool isChargeing() { return isBatteryConnect() && isVBUSPlug(); }
|
||||
virtual bool isChargeing() override { return isBatteryConnect() && isVBUSPlug(); }
|
||||
|
||||
private:
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
@@ -149,7 +153,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
|
||||
AnalogBatteryLevel analogLevel;
|
||||
|
||||
Power::Power() : OSThread("Power") {}
|
||||
Power::Power() : OSThread("Power") {
|
||||
statusHandler = {};
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
|
||||
bool Power::analogInit()
|
||||
{
|
||||
@@ -192,6 +199,7 @@ bool Power::setup()
|
||||
found = analogInit();
|
||||
}
|
||||
enabled = found;
|
||||
low_voltage_counter = 0;
|
||||
|
||||
return found;
|
||||
}
|
||||
@@ -231,20 +239,35 @@ void Power::readPowerStatus()
|
||||
}
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const PowerStatus powerStatus =
|
||||
const PowerStatus powerStatus2 =
|
||||
PowerStatus(hasBattery ? OptTrue : OptFalse, batteryLevel->isVBUSPlug() ? OptTrue : OptFalse,
|
||||
batteryLevel->isChargeing() ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
|
||||
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus.getHasUSB(),
|
||||
powerStatus.getIsCharging(), powerStatus.getBatteryVoltageMv(), powerStatus.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus);
|
||||
DEBUG_MSG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
|
||||
|
||||
// If we have a battery at all and it is less than 10% full, force deep sleep if we have more than 3 low readings in a row
|
||||
// Supect fluctuating voltage on the RAK4631 to force it to deep sleep even if battery is at 85% after only a few days
|
||||
#ifdef NRF52_SERIES
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()){
|
||||
if (batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS){
|
||||
low_voltage_counter++;
|
||||
if (low_voltage_counter>3)
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// If we have a battery at all and it is less than 10% full, force deep sleep
|
||||
if (powerStatus.getHasBattery() && !powerStatus.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB() && batteryLevel->getBattVoltage() < MIN_BAT_MILLIVOLTS)
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
#endif
|
||||
} else {
|
||||
// No power sensing on this board - tell everyone else we have no idea what is happening
|
||||
const PowerStatus powerStatus = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
|
||||
newStatus.notifyObservers(&powerStatus);
|
||||
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
|
||||
newStatus.notifyObservers(&powerStatus3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "configuration.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "GPS.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "graphics/Screen.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
@@ -11,6 +11,11 @@
|
||||
/// Should we behave as if we have AC power now?
|
||||
static bool isPowered()
|
||||
{
|
||||
// Completely circumvents the battery / power sensing logic and assumes constant power source
|
||||
if (radioConfig.preferences.is_always_powered) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isRouter = radioConfig.preferences.is_router;
|
||||
|
||||
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
|
||||
@@ -32,6 +37,14 @@ static void sdsEnter()
|
||||
doDeepSleep(getPref_sds_secs() * 1000LL);
|
||||
}
|
||||
|
||||
extern Power *power;
|
||||
|
||||
static void shutdownEnter()
|
||||
{
|
||||
DEBUG_MSG("Enter state: SHUTDOWN\n");
|
||||
power->shutdown();
|
||||
}
|
||||
|
||||
#include "error.h"
|
||||
|
||||
static uint32_t secsSlept;
|
||||
@@ -50,7 +63,6 @@ static void lsIdle()
|
||||
// DEBUG_MSG("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
|
||||
|
||||
#ifndef NO_ESP32
|
||||
esp_sleep_source_t wakeCause = ESP_SLEEP_WAKEUP_UNDEFINED;
|
||||
|
||||
// Do we have more sleeping to do?
|
||||
if (secsSlept < getPref_ls_secs()) {
|
||||
@@ -60,14 +72,14 @@ static void lsIdle()
|
||||
// If some other service would stall sleep, don't let sleep happen yet
|
||||
if (doPreflightSleep()) {
|
||||
setLed(false); // Never leave led on while in light sleep
|
||||
wakeCause = doLightSleep(sleepTime * 1000LL);
|
||||
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
|
||||
|
||||
switch (wakeCause) {
|
||||
switch (wakeCause2) {
|
||||
case ESP_SLEEP_WAKEUP_TIMER:
|
||||
// Normal case: timer expired, we should just go back to sleep ASAP
|
||||
|
||||
setLed(true); // briefly turn on led
|
||||
wakeCause = doLightSleep(1); // leave led on for 1ms
|
||||
wakeCause2 = doLightSleep(1); // leave led on for 1ms
|
||||
|
||||
secsSlept += sleepTime;
|
||||
// DEBUG_MSG("sleeping, flash led!\n");
|
||||
@@ -81,7 +93,7 @@ static void lsIdle()
|
||||
default:
|
||||
// We woke for some other reason (button press, device interrupt)
|
||||
// uint64_t status = esp_sleep_get_ext1_wakeup_status();
|
||||
DEBUG_MSG("wakeCause %d\n", wakeCause);
|
||||
DEBUG_MSG("wakeCause2 %d\n", wakeCause2);
|
||||
|
||||
#ifdef BUTTON_PIN
|
||||
bool pressed = !digitalRead(BUTTON_PIN);
|
||||
@@ -208,10 +220,12 @@ static void screenPress()
|
||||
screen->onPress();
|
||||
}
|
||||
|
||||
static void bootEnter() {
|
||||
static void bootEnter()
|
||||
{
|
||||
DEBUG_MSG("Enter state: BOOT\n");
|
||||
}
|
||||
|
||||
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
||||
State stateSDS(sdsEnter, NULL, NULL, "SDS");
|
||||
State stateLS(lsEnter, lsIdle, lsExit, "LS");
|
||||
State stateNB(nbEnter, NULL, NULL, "NB");
|
||||
@@ -234,8 +248,10 @@ void PowerFSM_setup()
|
||||
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
|
||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
|
||||
|
||||
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from light sleep we _always_ transition to NB or dark and
|
||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
|
||||
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
|
||||
// light sleep we _always_ transition to NB or dark and
|
||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
|
||||
"Received packet, exiting light sleep");
|
||||
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
|
||||
|
||||
// Handle press events - note: we ignore button presses when in API mode
|
||||
@@ -255,6 +271,20 @@ void PowerFSM_setup()
|
||||
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
|
||||
// Handle being told to power off
|
||||
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateLS, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateNB, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateDARK, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
|
||||
|
||||
// Inputbroker
|
||||
powerFSM.add_transition(&stateLS, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateNB, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_INPUT, NULL, "Input Device");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_INPUT, NULL, "Input Device"); // restarts the sleep timer
|
||||
|
||||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
|
||||
|
||||
@@ -312,15 +342,23 @@ void PowerFSM_setup()
|
||||
#ifndef NRF52_SERIES
|
||||
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
|
||||
|
||||
// I don't think this transition is correct, turning off for now - @geeksville
|
||||
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
|
||||
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
|
||||
if (isRouter || radioConfig.preferences.is_power_saving) {
|
||||
|
||||
// I don't think this transition is correct, turning off for now - @geeksville
|
||||
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
|
||||
meshSds = getPref_mesh_sds_timeout_secs();
|
||||
|
||||
} else {
|
||||
|
||||
meshSds = UINT32_MAX;
|
||||
}
|
||||
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
|
||||
meshSds = getPref_mesh_sds_timeout_secs();
|
||||
#else
|
||||
lowPowerState = &stateDARK;
|
||||
meshSds = UINT32_MAX; //Workaround for now: Don't go into deep sleep on the RAK4631
|
||||
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
|
||||
#endif
|
||||
|
||||
if (meshSds != UINT32_MAX)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#define EVENT_POWER_CONNECTED 13
|
||||
#define EVENT_POWER_DISCONNECTED 14
|
||||
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
|
||||
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
|
||||
#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
|
||||
|
||||
extern Fsm powerFSM;
|
||||
extern State statePOWER, stateSERIAL;
|
||||
|
||||
7
src/RF95Configuration.h
Normal file
7
src/RF95Configuration.h
Normal file
@@ -0,0 +1,7 @@
|
||||
// TODO refactor this out with better radio configuration system
|
||||
#ifdef USE_RF95
|
||||
#define RF95_RESET LORA_RESET
|
||||
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
|
||||
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
|
||||
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
|
||||
#endif
|
||||
@@ -22,7 +22,7 @@ class RedirectablePrint : public Print
|
||||
volatile bool inDebugPrint = false;
|
||||
|
||||
public:
|
||||
RedirectablePrint(Print *_dest) : dest(_dest) {}
|
||||
explicit RedirectablePrint(Print *_dest) : dest(_dest) {}
|
||||
|
||||
/**
|
||||
* Set a new destination
|
||||
@@ -56,4 +56,4 @@ class NoopPrint : public Print
|
||||
/**
|
||||
* A printer that doesn't go anywhere
|
||||
*/
|
||||
extern NoopPrint noopPrint;
|
||||
extern NoopPrint noopPrint;
|
||||
|
||||
@@ -15,9 +15,9 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
|
||||
* we override this to notice when we've received a protobuf over the serial stream. Then we shunt off
|
||||
* debug serial output.
|
||||
*/
|
||||
virtual bool handleToRadio(const uint8_t *buf, size_t len);
|
||||
virtual bool handleToRadio(const uint8_t *buf, size_t len) override;
|
||||
|
||||
virtual size_t write(uint8_t c)
|
||||
virtual size_t write(uint8_t c) override
|
||||
{
|
||||
if (c == '\n') // prefix any newlines with carriage return
|
||||
RedirectablePrint::write('\r');
|
||||
@@ -27,7 +27,7 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
|
||||
protected:
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected();
|
||||
virtual bool checkIsConnected() override;
|
||||
};
|
||||
|
||||
// A simple wrapper to allow non class aware code write to the console
|
||||
|
||||
190
src/airtime.cpp
190
src/airtime.cpp
@@ -1,107 +1,187 @@
|
||||
#include "configuration.h"
|
||||
#include "airtime.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#define periodsToLog 48
|
||||
|
||||
AirTime *airTime;
|
||||
|
||||
uint32_t secondsPerPeriod = 3600;
|
||||
uint32_t lastMillis = 0;
|
||||
uint32_t secSinceBoot = 0;
|
||||
|
||||
// AirTime at;
|
||||
AirTime *airTime = NULL;
|
||||
|
||||
// Don't read out of this directly. Use the helper functions.
|
||||
struct airtimeStruct {
|
||||
uint32_t periodTX[periodsToLog]; // AirTime transmitted
|
||||
uint32_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
|
||||
uint32_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
|
||||
uint8_t lastPeriodIndex;
|
||||
} airtimes;
|
||||
|
||||
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
||||
{
|
||||
|
||||
if (reportType == TX_LOG) {
|
||||
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
|
||||
airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
|
||||
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
|
||||
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
|
||||
|
||||
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
|
||||
|
||||
} else if (reportType == RX_LOG) {
|
||||
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
|
||||
airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
|
||||
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
|
||||
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
|
||||
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
|
||||
} else {
|
||||
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
|
||||
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
|
||||
}
|
||||
|
||||
// Log all airtime type for channel utilization
|
||||
this->channelUtilization[this->getPeriodUtilMinute()] = channelUtilization[this->getPeriodUtilMinute()] + airtime_ms;
|
||||
}
|
||||
|
||||
uint8_t currentPeriodIndex()
|
||||
uint8_t AirTime::currentPeriodIndex()
|
||||
{
|
||||
return ((getSecondsSinceBoot() / secondsPerPeriod) % periodsToLog);
|
||||
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
|
||||
}
|
||||
|
||||
void airtimeRotatePeriod()
|
||||
uint8_t AirTime::getPeriodUtilMinute() {
|
||||
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
|
||||
}
|
||||
|
||||
uint8_t AirTime::getPeriodUtilHour() {
|
||||
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
|
||||
}
|
||||
|
||||
void AirTime::airtimeRotatePeriod()
|
||||
{
|
||||
|
||||
if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
|
||||
DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex());
|
||||
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
|
||||
DEBUG_MSG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex());
|
||||
|
||||
for (int i = periodsToLog - 2; i >= 0; --i) {
|
||||
airtimes.periodTX[i + 1] = airtimes.periodTX[i];
|
||||
airtimes.periodRX[i + 1] = airtimes.periodRX[i];
|
||||
airtimes.periodRX_ALL[i + 1] = airtimes.periodRX_ALL[i];
|
||||
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
|
||||
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
|
||||
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
|
||||
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
|
||||
|
||||
myNodeInfo.air_period_tx[i + 1] = this->airtimes.periodTX[i];
|
||||
myNodeInfo.air_period_rx[i + 1] = this->airtimes.periodRX[i];
|
||||
}
|
||||
airtimes.periodTX[0] = 0;
|
||||
airtimes.periodRX[0] = 0;
|
||||
airtimes.periodRX_ALL[0] = 0;
|
||||
|
||||
airtimes.lastPeriodIndex = currentPeriodIndex();
|
||||
this->airtimes.periodTX[0] = 0;
|
||||
this->airtimes.periodRX[0] = 0;
|
||||
this->airtimes.periodRX_ALL[0] = 0;
|
||||
|
||||
myNodeInfo.air_period_tx[0] = 0;
|
||||
myNodeInfo.air_period_rx[0] = 0;
|
||||
|
||||
this->airtimes.lastPeriodIndex = this->currentPeriodIndex();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t *airtimeReport(reportTypes reportType)
|
||||
uint32_t *AirTime::airtimeReport(reportTypes reportType)
|
||||
{
|
||||
|
||||
if (reportType == TX_LOG) {
|
||||
return airtimes.periodTX;
|
||||
return this->airtimes.periodTX;
|
||||
} else if (reportType == RX_LOG) {
|
||||
return airtimes.periodRX;
|
||||
return this->airtimes.periodRX;
|
||||
} else if (reportType == RX_ALL_LOG) {
|
||||
return airtimes.periodRX_ALL;
|
||||
return this->airtimes.periodRX_ALL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t getPeriodsToLog()
|
||||
uint8_t AirTime::getPeriodsToLog()
|
||||
{
|
||||
return periodsToLog;
|
||||
return PERIODS_TO_LOG;
|
||||
}
|
||||
|
||||
uint32_t getSecondsPerPeriod()
|
||||
uint32_t AirTime::getSecondsPerPeriod()
|
||||
{
|
||||
return secondsPerPeriod;
|
||||
return SECONDS_PER_PERIOD;
|
||||
}
|
||||
|
||||
uint32_t getSecondsSinceBoot()
|
||||
uint32_t AirTime::getSecondsSinceBoot()
|
||||
{
|
||||
return secSinceBoot;
|
||||
return this->secSinceBoot;
|
||||
}
|
||||
|
||||
AirTime::AirTime() : concurrency::OSThread("AirTime") {}
|
||||
float AirTime::channelUtilizationPercent()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
|
||||
sum += this->channelUtilization[i];
|
||||
// DEBUG_MSG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
|
||||
}
|
||||
|
||||
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
|
||||
}
|
||||
|
||||
float AirTime::utilizationTXPercent()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
|
||||
sum += this->utilizationTX[i];
|
||||
}
|
||||
|
||||
return (float(sum) / float(MS_IN_HOUR)) * 100;
|
||||
}
|
||||
|
||||
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
|
||||
}
|
||||
|
||||
int32_t AirTime::runOnce()
|
||||
{
|
||||
//DEBUG_MSG("AirTime::runOnce()\n");
|
||||
|
||||
airtimeRotatePeriod();
|
||||
secSinceBoot++;
|
||||
|
||||
/*
|
||||
This actually doesn't need to be run once per second but we currently use it for the
|
||||
secSinceBoot counter.
|
||||
uint8_t utilPeriod = this->getPeriodUtilMinute();
|
||||
uint8_t utilPeriodTX = this->getPeriodUtilHour();
|
||||
|
||||
If we have a better counter of how long the device has been online (and not millis())
|
||||
then we can change this to something less frequent. Maybe once ever 5 seconds?
|
||||
*/
|
||||
if (firstTime) {
|
||||
|
||||
// Init utilizationTX window to all 0
|
||||
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
|
||||
this->utilizationTX[i] = 0;
|
||||
}
|
||||
|
||||
// Init channelUtilization window to all 0
|
||||
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
|
||||
this->channelUtilization[i] = 0;
|
||||
}
|
||||
|
||||
// Init airtime windows to all 0
|
||||
for (int i = 0; i < PERIODS_TO_LOG; i++) {
|
||||
this->airtimes.periodTX[i] = 0;
|
||||
this->airtimes.periodRX[i] = 0;
|
||||
this->airtimes.periodRX_ALL[i] = 0;
|
||||
|
||||
// myNodeInfo.air_period_tx[i] = 0;
|
||||
// myNodeInfo.air_period_rx[i] = 0;
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
lastUtilPeriod = utilPeriod;
|
||||
|
||||
} else {
|
||||
this->airtimeRotatePeriod();
|
||||
|
||||
// Reset the channelUtilization window when we roll over
|
||||
if (lastUtilPeriod != utilPeriod) {
|
||||
lastUtilPeriod = utilPeriod;
|
||||
|
||||
this->channelUtilization[utilPeriod] = 0;
|
||||
}
|
||||
|
||||
if (lastUtilPeriodTX != utilPeriodTX) {
|
||||
lastUtilPeriodTX = utilPeriodTX;
|
||||
|
||||
this->utilizationTX[utilPeriodTX] = 0;
|
||||
}
|
||||
|
||||
// Update channel_utilization every second.
|
||||
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
|
||||
|
||||
// Update channel_utilization every second.
|
||||
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
|
||||
}
|
||||
/*
|
||||
DEBUG_MSG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
|
||||
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
|
||||
DEBUG_MSG(
|
||||
"%d,", this->utilizationTX[i]
|
||||
);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
*/
|
||||
return (1000 * 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@
|
||||
|
||||
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
|
||||
*/
|
||||
|
||||
#define CHANNEL_UTILIZATION_PERIODS 6
|
||||
#define SECONDS_PER_PERIOD 3600
|
||||
#define PERIODS_TO_LOG 24
|
||||
#define MINUTES_IN_HOUR 60
|
||||
#define SECONDS_IN_MINUTE 60
|
||||
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
|
||||
|
||||
|
||||
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
|
||||
|
||||
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
|
||||
|
||||
void airtimeRotatePeriod();
|
||||
|
||||
uint8_t currentPeriodIndex();
|
||||
uint8_t getPeriodsToLog();
|
||||
|
||||
uint32_t getSecondsSinceBoot();
|
||||
|
||||
uint32_t *airtimeReport(reportTypes reportType);
|
||||
|
||||
uint32_t getSecondsPerPeriod();
|
||||
|
||||
class AirTime : private concurrency::OSThread
|
||||
{
|
||||
|
||||
@@ -45,9 +45,38 @@ class AirTime : private concurrency::OSThread
|
||||
AirTime();
|
||||
|
||||
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
|
||||
float channelUtilizationPercent();
|
||||
float utilizationTXPercent();
|
||||
|
||||
float UtilizationPercentTX();
|
||||
uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS] = {0};
|
||||
uint32_t utilizationTX[MINUTES_IN_HOUR] = {0};
|
||||
|
||||
void airtimeRotatePeriod();
|
||||
uint8_t getPeriodsToLog();
|
||||
uint32_t getSecondsPerPeriod();
|
||||
uint32_t getSecondsSinceBoot();
|
||||
uint32_t *airtimeReport(reportTypes reportType);
|
||||
|
||||
private:
|
||||
bool firstTime = true;
|
||||
uint8_t lastUtilPeriod = 0;
|
||||
uint8_t lastUtilPeriodTX = 0;
|
||||
uint32_t secSinceBoot = 0;
|
||||
|
||||
struct airtimeStruct {
|
||||
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
|
||||
uint32_t periodRX[PERIODS_TO_LOG]; // AirTime received and repeated (Only valid mesh packets)
|
||||
uint32_t periodRX_ALL[PERIODS_TO_LOG]; // AirTime received regardless of valid mesh packet. Could include noise.
|
||||
uint8_t lastPeriodIndex;
|
||||
} airtimes;
|
||||
|
||||
uint8_t getPeriodUtilMinute();
|
||||
uint8_t getPeriodUtilHour();
|
||||
uint8_t currentPeriodIndex();
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
};
|
||||
|
||||
extern AirTime *airTime;
|
||||
extern AirTime *airTime;
|
||||
|
||||
@@ -13,4 +13,5 @@ enum class Cmd {
|
||||
STOP_BLUETOOTH_PIN_SCREEN,
|
||||
STOP_BOOT_SCREEN,
|
||||
PRINT,
|
||||
START_SHUTDOWN_SCREEN,
|
||||
};
|
||||
@@ -7,9 +7,8 @@
|
||||
namespace concurrency
|
||||
{
|
||||
|
||||
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS()
|
||||
BinarySemaphoreFreeRTOS::BinarySemaphoreFreeRTOS() : semaphore(xSemaphoreCreateBinary())
|
||||
{
|
||||
semaphore = xSemaphoreCreateBinary();
|
||||
assert(semaphore);
|
||||
}
|
||||
|
||||
@@ -38,4 +37,4 @@ IRAM_ATTR void BinarySemaphoreFreeRTOS::giveFromISR(BaseType_t *pxHigherPriority
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,8 @@ namespace concurrency
|
||||
{
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
Lock::Lock()
|
||||
Lock::Lock() : handle(xSemaphoreCreateBinary())
|
||||
{
|
||||
handle = xSemaphoreCreateBinary();
|
||||
assert(handle);
|
||||
assert(xSemaphoreGive(handle));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace concurrency {
|
||||
class LockGuard
|
||||
{
|
||||
public:
|
||||
LockGuard(Lock *lock);
|
||||
explicit LockGuard(Lock *lock);
|
||||
~LockGuard();
|
||||
|
||||
LockGuard(const LockGuard &) = delete;
|
||||
|
||||
@@ -39,7 +39,7 @@ class NotifiedWorkerThread : public OSThread
|
||||
virtual void onNotify(uint32_t notification) = 0;
|
||||
|
||||
/// just calls checkNotification()
|
||||
virtual int32_t runOnce();
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change
|
||||
/// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently
|
||||
|
||||
@@ -18,7 +18,7 @@ class Periodic : public OSThread
|
||||
Periodic(const char *name, int32_t (*_callback)()) : OSThread(name), callback(_callback) {}
|
||||
|
||||
protected:
|
||||
int32_t runOnce() { return callback(); }
|
||||
int32_t runOnce() override { return callback(); }
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
@@ -45,10 +45,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// If we are using the JTAG port for debugging, some pins must be left free for that (and things like GPS have to be disabled)
|
||||
// we don't support jtag on the ttgo - access to gpio 12 is a PITA
|
||||
#ifdef ARDUINO_HELTEC_WIFI_LORA_32_V2
|
||||
//#define USE_JTAG
|
||||
#endif
|
||||
|
||||
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
|
||||
|
||||
/// Convert a preprocessor name into a quoted string
|
||||
@@ -84,17 +80,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define BUTTON_PIN_ALT PIN_BUTTON2
|
||||
#endif
|
||||
|
||||
// FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets)
|
||||
#elif defined(CubeCell_BoardPlus)
|
||||
|
||||
//
|
||||
// Standard definitions for CubeCell targets
|
||||
//
|
||||
|
||||
#define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth)
|
||||
|
||||
#define LED_PIN -1 // FIXME totally bogus
|
||||
#define BUTTON_PIN -1
|
||||
#ifdef PIN_BUTTON_TOUCH
|
||||
#define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -165,251 +153,59 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_TBEAM
|
||||
|
||||
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
|
||||
|
||||
#define I2C_SDA 21
|
||||
#define I2C_SCL 22
|
||||
|
||||
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
|
||||
#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed
|
||||
|
||||
#define LED_INVERTED 1
|
||||
#define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
|
||||
|
||||
// TTGO uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
||||
// not found then probe for SX1262
|
||||
#define USE_RF95
|
||||
#define USE_SX1262
|
||||
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 23
|
||||
#define LORA_DIO1 33 // SX1262 IRQ
|
||||
#define LORA_DIO2 32 // SX1262 BUSY
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX1262_CS RF95_NSS // FIXME - we really should define LORA_CS instead
|
||||
#define SX1262_DIO1 LORA_DIO1
|
||||
#define SX1262_BUSY LORA_DIO2
|
||||
#define SX1262_RESET LORA_RESET
|
||||
#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
|
||||
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
|
||||
// code)
|
||||
#endif
|
||||
|
||||
// Leave undefined to disable our PMU IRQ handler. DO NOT ENABLE THIS because the pmuirq can cause sperious interrupts
|
||||
// and waking from light sleep
|
||||
// #define PMU_IRQ 35
|
||||
#define AXP192_SLAVE_ADDRESS 0x34
|
||||
|
||||
#elif defined(TBEAM_V07)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_TBEAM0p7
|
||||
|
||||
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
|
||||
#elif defined(DIY_V1)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_DIY_V1
|
||||
|
||||
#define I2C_SDA 21
|
||||
#define I2C_SCL 22
|
||||
|
||||
#define BUTTON_PIN 39
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 23
|
||||
#define LORA_DIO1 33 // Not really used
|
||||
#define LORA_DIO2 32 // Not really used
|
||||
|
||||
// This board has different GPS pins than all other boards
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 12
|
||||
#define GPS_TX_PIN 15
|
||||
#elif defined(RAK_11200)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_RAK11200
|
||||
|
||||
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32_V2)
|
||||
|
||||
// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine.
|
||||
// Tested on Neo6m module.
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 37
|
||||
|
||||
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
|
||||
#define I2C_SDA 4 // I2C pins for this board
|
||||
#define I2C_SCL 15
|
||||
#endif
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#ifndef USE_JTAG
|
||||
#define LORA_RESET 14
|
||||
#endif
|
||||
#define LORA_DIO1 35 // Not really used
|
||||
#define LORA_DIO2 34 // Not really used
|
||||
|
||||
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
|
||||
#define ADC_MULTIPLIER 3.2
|
||||
|
||||
#ifdef HELTEC_V2_0
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V2_0
|
||||
|
||||
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HELTEC_V2_1
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V2_1
|
||||
|
||||
#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
|
||||
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V1
|
||||
|
||||
#elif defined(TLORA_V1)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 37
|
||||
|
||||
#define I2C_SDA 4 // I2C pins for this board
|
||||
#define I2C_SCL 15
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
// #define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 2 // If defined we will blink this LED
|
||||
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 35 // Not really used
|
||||
#define LORA_DIO2 34 // Not really used
|
||||
|
||||
#elif defined(TLORA_V2)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2
|
||||
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 13 // per @eugene
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#define I2C_SDA 21 // I2C pins for this board
|
||||
#define I2C_SCL 22
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN \
|
||||
0 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one
|
||||
// between this pin and ground
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 35 // Not really used
|
||||
#define LORA_DIO2 34 // Not really used
|
||||
|
||||
#elif defined(TLORA_V1_3)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1_1p3
|
||||
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 36
|
||||
#define GPS_TX_PIN 13 // per @eugene
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#define I2C_SDA 4 // I2C pins for this board
|
||||
#define I2C_SCL 15
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN 36
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 35 // Not really used
|
||||
#define LORA_DIO2 34 // Not really used
|
||||
|
||||
#elif defined(TLORA_V2_1_16)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1p6
|
||||
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 15 // per @der_bear on the forum, 36 is incorrect for this board type and 15 is a better pick
|
||||
#define GPS_TX_PIN 13
|
||||
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
|
||||
#define I2C_SDA 21 // I2C pins for this board
|
||||
#define I2C_SCL 22
|
||||
|
||||
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
|
||||
|
||||
#define VEXT_ENABLE 21 // active low, powers the oled display and the lora antenna boost
|
||||
#define LED_PIN 25 // If defined we will blink this LED
|
||||
#define BUTTON_PIN 12 // If defined, this will be used for user button presses,
|
||||
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 35 // Not really used
|
||||
#define LORA_DIO2 34 // Not really used
|
||||
|
||||
#elif defined(GENIEBLOCKS)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_GENIEBLOCKS
|
||||
#undef GPS_RX_PIN
|
||||
#undef GPS_TX_PIN
|
||||
#define GPS_RX_PIN 5
|
||||
#define GPS_TX_PIN 18
|
||||
#define GPS_RESET_N 10
|
||||
#define GPS_EXTINT 23 // On MAX-M8 module pin name is EXTINT. On L70 module pin name is STANDBY.
|
||||
|
||||
#define BATTERY_PIN 39 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define BATTERY_EN_PIN 14 // Voltage voltage divider enable pin connected to mosfet
|
||||
|
||||
#define I2C_SDA 4 // I2C pins for this board
|
||||
#define I2C_SCL 2
|
||||
|
||||
#define LED_PIN 12 // If defined we will blink this LED
|
||||
//#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen -->
|
||||
// Long press start!) #define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal
|
||||
// pull-ups or pull-down resistors.
|
||||
|
||||
#define USE_RF95
|
||||
#define LORA_DIO0 38 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 9
|
||||
|
||||
#define RF95_SCK 22
|
||||
#define RF95_MISO 19
|
||||
#define RF95_MOSI 13
|
||||
#define RF95_NSS 21
|
||||
#elif defined(PRIVATE_HW)
|
||||
// This string must exactly match the case used in release file names or the android updater won't work
|
||||
#define HW_VENDOR HardwareModel_PRIVATE_HW
|
||||
|
||||
#endif
|
||||
|
||||
@@ -434,6 +230,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define HW_VENDOR HardwareModel_T_ECHO
|
||||
|
||||
#elif defined(NANO_G1)
|
||||
|
||||
#define HW_VENDOR HardwareModel_NANO_G1
|
||||
|
||||
#elif NRF52_SERIES
|
||||
|
||||
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
||||
@@ -442,100 +242,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define HW_VENDOR HardwareModel_PORTDUINO
|
||||
|
||||
#define USE_SIM_RADIO
|
||||
|
||||
// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
||||
// not found then probe for SX1262. Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
|
||||
// #define USE_RF95
|
||||
#define USE_SX1262
|
||||
|
||||
// Fake SPI device selections
|
||||
#define RF95_SCK 5
|
||||
#define RF95_MISO 19
|
||||
#define RF95_MOSI 27
|
||||
#define RF95_NSS RADIOLIB_NC // the ch341f spi controller does CS for us
|
||||
|
||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 14
|
||||
#define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
|
||||
#define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#ifdef USE_SX1262
|
||||
#define SX1262_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
|
||||
#define SX1262_DIO1 LORA_DIO1
|
||||
#define SX1262_BUSY LORA_DIO2
|
||||
#define SX1262_RESET LORA_RESET
|
||||
// HOPE RFM90 does not have a TCXO therefore not SX1262_E22
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// DEBUG LED
|
||||
#ifndef LED_INVERTED
|
||||
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
|
||||
#endif
|
||||
|
||||
#ifdef USE_RF95
|
||||
#define RF95_RESET LORA_RESET
|
||||
#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
|
||||
#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
|
||||
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// DEBUG
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifdef CONSOLE_MAX_BAUD
|
||||
#define SERIAL_BAUD CONSOLE_MAX_BAUD
|
||||
#else
|
||||
#define SERIAL_BAUD 921600 // Serial debug baud rate
|
||||
#endif
|
||||
|
||||
#include "SerialConsole.h"
|
||||
|
||||
#define DEBUG_PORT (*console) // Serial debug port
|
||||
|
||||
// What platforms should use SEGGER?
|
||||
#ifdef NRF52_SERIES
|
||||
|
||||
// Always include the SEGGER code on NRF52 - because useful for debugging
|
||||
#include "SEGGER_RTT.h"
|
||||
|
||||
// The channel we send stdout data to
|
||||
#define SEGGER_STDOUT_CH 0
|
||||
|
||||
// Debug printing to segger console
|
||||
#define SEGGER_MSG(...) SEGGER_RTT_printf(SEGGER_STDOUT_CH, __VA_ARGS__)
|
||||
|
||||
// If we are not on a NRF52840 (which has built in USB-ACM serial support) and we don't have serial pins hooked up, then we MUST
|
||||
// use SEGGER for debug output
|
||||
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
|
||||
// No serial ports on this board - ONLY use segger in memory console
|
||||
#define USE_SEGGER
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define SERIAL0_RX_GPIO 3 // Always GPIO3 on ESP32
|
||||
#endif
|
||||
|
||||
#ifdef USE_SEGGER
|
||||
#define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||
#else
|
||||
#ifdef DEBUG_PORT
|
||||
#define DEBUG_MSG(...) DEBUG_PORT.logDebug(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_MSG(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// AXP192 (Rev1-specific options)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define GPS_POWER_CTRL_CH 3
|
||||
#define LORA_POWER_CTRL_CH 2
|
||||
|
||||
// Default Bluetooth PIN
|
||||
#define defaultBLEPin 123456
|
||||
#include "variant.h"
|
||||
#include "RF95Configuration.h"
|
||||
#include "DebugConfiguration.h"
|
||||
@@ -58,7 +58,7 @@ int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_BLOCKSIZE 512
|
||||
#define MAX_BLOCKSIZE_FOR_BT 512
|
||||
|
||||
/// Handle writes to data
|
||||
int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
@@ -66,7 +66,7 @@ int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_
|
||||
concurrency::LockGuard g(updateLock);
|
||||
|
||||
static uint8_t
|
||||
data[MAX_BLOCKSIZE]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
|
||||
data[MAX_BLOCKSIZE_FOR_BT]; // we temporarily copy here because I'm worried that a fast sender might be able overwrite srcbuf
|
||||
|
||||
uint16_t len = 0;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class ESP32CryptoEngine : public CryptoEngine
|
||||
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
|
||||
* provided pointer)
|
||||
*/
|
||||
virtual void setKey(const CryptoKey &k)
|
||||
virtual void setKey(const CryptoKey &k) override
|
||||
{
|
||||
CryptoEngine::setKey(k);
|
||||
|
||||
@@ -47,7 +47,7 @@ class ESP32CryptoEngine : public CryptoEngine
|
||||
*
|
||||
* @param bytes is updated in place
|
||||
*/
|
||||
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
|
||||
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
|
||||
{
|
||||
if (key.length > 0) {
|
||||
uint8_t stream_block[16];
|
||||
@@ -66,7 +66,7 @@ class ESP32CryptoEngine : public CryptoEngine
|
||||
}
|
||||
}
|
||||
|
||||
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
|
||||
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes) override
|
||||
{
|
||||
// DEBUG_MSG("ESP32 decrypt!\n");
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
class SimpleAllocator
|
||||
{
|
||||
uint8_t bytes[POOL_SIZE];
|
||||
uint8_t bytes[POOL_SIZE] = {};
|
||||
|
||||
uint32_t nextFree;
|
||||
uint32_t nextFree = 0;
|
||||
|
||||
public:
|
||||
SimpleAllocator();
|
||||
@@ -37,6 +37,6 @@ void *operator new(size_t size, SimpleAllocator &p);
|
||||
*/
|
||||
class AllocatorScope {
|
||||
public:
|
||||
AllocatorScope(SimpleAllocator &a);
|
||||
explicit AllocatorScope(SimpleAllocator &a);
|
||||
~AllocatorScope();
|
||||
};
|
||||
|
||||
@@ -43,8 +43,8 @@ void esp32Setup()
|
||||
nvs_stats_t nvs_stats;
|
||||
auto res = nvs_get_stats(NULL, &nvs_stats);
|
||||
assert(res == ESP_OK);
|
||||
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
|
||||
nvs_stats.total_entries);
|
||||
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
|
||||
nvs_stats.total_entries, nvs_stats.namespace_count);
|
||||
|
||||
DEBUG_MSG("Setup Preferences in Flash Storage\n");
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ class Air530GPS : public NMEAGPS
|
||||
{
|
||||
protected:
|
||||
/// If possible force the GPS into sleep/low power mode
|
||||
virtual void sleep();
|
||||
virtual void sleep() override;
|
||||
|
||||
/// wake the GPS into normal operation mode
|
||||
virtual void wake();
|
||||
virtual void wake() override;
|
||||
|
||||
private:
|
||||
/// Send a NMEA cmd with checksum
|
||||
|
||||
@@ -80,6 +80,8 @@ GPS::~GPS()
|
||||
notifyDeepSleepObserver.unobserve();
|
||||
}
|
||||
|
||||
bool GPS::hasLock() { return hasValidLocation; }
|
||||
|
||||
// Allow defining the polarity of the WAKE output. default is active high
|
||||
#ifndef GPS_WAKE_ACTIVE
|
||||
#define GPS_WAKE_ACTIVE 1
|
||||
@@ -200,11 +202,13 @@ void GPS::publishUpdate()
|
||||
if (shouldPublish) {
|
||||
shouldPublish = false;
|
||||
|
||||
DEBUG_MSG("publishing GPS lock=%d\n", hasLock());
|
||||
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
||||
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n",
|
||||
p.pos_timestamp, hasValidLocation, hasLock());
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const meshtastic::GPSStatus status =
|
||||
meshtastic::GPSStatus(hasLock(), isConnected(), latitude, longitude, altitude, dop, heading, numSatellites);
|
||||
meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
|
||||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
}
|
||||
@@ -242,6 +246,7 @@ int32_t GPS::runOnce()
|
||||
|
||||
bool gotLoc = lookForLocation();
|
||||
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
|
||||
DEBUG_MSG("hasValidLocation RISING EDGE\n");
|
||||
hasValidLocation = true;
|
||||
shouldPublish = true;
|
||||
}
|
||||
@@ -258,6 +263,10 @@ int32_t GPS::runOnce()
|
||||
|
||||
if (tooLong) {
|
||||
// we didn't get a location during this ack window, therefore declare loss of lock
|
||||
if (hasValidLocation) {
|
||||
DEBUG_MSG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
|
||||
}
|
||||
p = Position_init_default;
|
||||
hasValidLocation = false;
|
||||
}
|
||||
|
||||
@@ -325,6 +334,11 @@ GPS *createGps()
|
||||
#ifdef NO_GPS
|
||||
return nullptr;
|
||||
#else
|
||||
#ifdef GPS_ALTITUDE_HAE
|
||||
DEBUG_MSG("Using HAE altitude model\n");
|
||||
#else
|
||||
DEBUG_MSG("Using MSL altitude model\n");
|
||||
#endif
|
||||
// If we don't have bidirectional comms, we can't even try talking to UBLOX
|
||||
#ifdef GPS_TX_PIN
|
||||
// Init GPS - first try ublox
|
||||
|
||||
@@ -17,6 +17,10 @@ class GPS : private concurrency::OSThread
|
||||
private:
|
||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0;
|
||||
|
||||
/**
|
||||
* hasValidLocation - indicates that the position variables contain a complete
|
||||
* GPS location, valid and fresh (< gps_update_interval + gps_attempt_time)
|
||||
*/
|
||||
bool hasValidLocation = false; // default to false, until we complete our first read
|
||||
|
||||
bool isAwake = false; // true if we want a location right now
|
||||
@@ -39,11 +43,7 @@ class GPS : private concurrency::OSThread
|
||||
/** If !0 we will attempt to connect to the GPS over I2C */
|
||||
static uint8_t i2cAddress;
|
||||
|
||||
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
||||
int32_t altitude = 0;
|
||||
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
|
||||
// scaling before use)
|
||||
uint32_t heading = 0; // Heading of motion, in degrees * 10^-5
|
||||
Position p = Position_init_default;
|
||||
|
||||
GPS() : concurrency::OSThread("GPS") {}
|
||||
|
||||
@@ -57,8 +57,8 @@ class GPS : private concurrency::OSThread
|
||||
*/
|
||||
virtual bool setup();
|
||||
|
||||
/// Returns ture if we have acquired GPS lock.
|
||||
bool hasLock() const { return hasValidLocation; }
|
||||
/// Returns true if we have acquired GPS lock.
|
||||
virtual bool hasLock();
|
||||
|
||||
/// Return true if we are connected to a GPS
|
||||
bool isConnected() const { return hasGPS; }
|
||||
@@ -145,7 +145,7 @@ class GPS : private concurrency::OSThread
|
||||
*/
|
||||
void publishUpdate();
|
||||
|
||||
virtual int32_t runOnce();
|
||||
virtual int32_t runOnce() override;
|
||||
};
|
||||
|
||||
// Creates an instance of the GPS class.
|
||||
|
||||
450
src/gps/GeoCoord.cpp
Normal file
450
src/gps/GeoCoord.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
#include "GeoCoord.h"
|
||||
|
||||
GeoCoord::GeoCoord() {
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord (int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt) {
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord (float lat, float lon, int32_t alt) : _altitude(alt) {
|
||||
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
|
||||
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
// Initialize all the coordinate systems
|
||||
void GeoCoord::setCoords() {
|
||||
double lat = _latitude * 1e-7;
|
||||
double lon = _longitude * 1e-7;
|
||||
GeoCoord::latLongToDMS(lat, lon, _dms);
|
||||
GeoCoord::latLongToUTM(lat, lon, _utm);
|
||||
GeoCoord::latLongToMGRS(lat, lon, _mgrs);
|
||||
GeoCoord::latLongToOSGR(lat, lon, _osgr);
|
||||
GeoCoord::latLongToOLC(lat, lon, _olc);
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
|
||||
// If marked dirty or new coordiantes
|
||||
if(_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
|
||||
_dirty = true;
|
||||
_latitude = lat;
|
||||
_longitude = lon;
|
||||
_altitude = alt;
|
||||
setCoords();
|
||||
}
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt) {
|
||||
int32_t iLat = lat * 1e+7;
|
||||
int32_t iLon = lon * 1e+7;
|
||||
// If marked dirty or new coordiantes
|
||||
if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
||||
_dirty = true;
|
||||
_latitude = iLat;
|
||||
_longitude = iLon;
|
||||
_altitude = alt;
|
||||
setCoords();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt) {
|
||||
int32_t iLat = lat * 1e+7;
|
||||
int32_t iLon = lon * 1e+7;
|
||||
// If marked dirty or new coordiantes
|
||||
if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
||||
_dirty = true;
|
||||
_latitude = iLat;
|
||||
_longitude = iLon;
|
||||
_altitude = alt;
|
||||
setCoords();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
|
||||
* DD°MM'SS"C DDD°MM'SS"C
|
||||
*/
|
||||
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
|
||||
if (lat < 0) dms.latCP = 'S';
|
||||
else dms.latCP = 'N';
|
||||
|
||||
double latDeg = lat;
|
||||
|
||||
if (lat < 0)
|
||||
latDeg = latDeg * -1;
|
||||
|
||||
dms.latDeg = floor(latDeg);
|
||||
double latMin = (latDeg - dms.latDeg) * 60;
|
||||
dms.latMin = floor(latMin);
|
||||
dms.latSec = (latMin - dms.latMin) * 60;
|
||||
|
||||
if (lon < 0) dms.lonCP = 'W';
|
||||
else dms.lonCP = 'E';
|
||||
|
||||
double lonDeg = lon;
|
||||
|
||||
if (lon < 0)
|
||||
lonDeg = lonDeg * -1;
|
||||
|
||||
dms.lonDeg = floor(lonDeg);
|
||||
double lonMin = (lonDeg - dms.lonDeg) * 60;
|
||||
dms.lonMin = floor(lonMin);
|
||||
dms.lonSec = (lonMin - dms.lonMin) * 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts lat long coordinates to UTM.
|
||||
* based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino
|
||||
*/
|
||||
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
|
||||
|
||||
const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX";
|
||||
utm.zone = int((lon + 180)/6 + 1);
|
||||
utm.band = latBands[int(lat/8 + 10)];
|
||||
double a = 6378137; // WGS84 - equatorial radius
|
||||
double k0 = 0.9996; // UTM point scale on the central meridian
|
||||
double eccSquared = 0.00669438; // eccentricity squared
|
||||
double lonTemp = (lon + 180) - int((lon + 180)/360) * 360 - 180; //Make sure the longitude is between -180.00 .. 179.9
|
||||
double latRad = toRadians(lat);
|
||||
double lonRad = toRadians(lonTemp);
|
||||
|
||||
// Special Zones for Norway and Svalbard
|
||||
if( lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0 ) // Norway
|
||||
utm.zone = 32;
|
||||
if( lat >= 72.0 && lat < 84.0 ) { // Svalbard
|
||||
if ( lonTemp >= 0.0 && lonTemp < 9.0 ) utm.zone = 31;
|
||||
else if( lonTemp >= 9.0 && lonTemp < 21.0 ) utm.zone = 33;
|
||||
else if( lonTemp >= 21.0 && lonTemp < 33.0 ) utm.zone = 35;
|
||||
else if( lonTemp >= 33.0 && lonTemp < 42.0 ) utm.zone = 37;
|
||||
}
|
||||
|
||||
double lonOrigin = (utm.zone - 1)*6 - 180 + 3; // puts origin in middle of zone
|
||||
double lonOriginRad = toRadians(lonOrigin);
|
||||
double eccPrimeSquared = (eccSquared)/(1 - eccSquared);
|
||||
double N = a/sqrt(1 - eccSquared*sin(latRad)*sin(latRad));
|
||||
double T = tan(latRad)*tan(latRad);
|
||||
double C = eccPrimeSquared*cos(latRad)*cos(latRad);
|
||||
double A = cos(latRad)*(lonRad - lonOriginRad);
|
||||
double M = a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*latRad
|
||||
- (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*latRad)
|
||||
+ (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*latRad)
|
||||
- (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*latRad));
|
||||
utm.easting = (double)(k0*N*(A+(1-T+C)*pow(A, 3)/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
|
||||
+ 500000.0);
|
||||
utm.northing = (double)(k0*(M+N*tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
|
||||
+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
|
||||
|
||||
if(lat < 0)
|
||||
utm.northing += 10000000.0; //10000000 meter offset for southern hemisphere
|
||||
}
|
||||
|
||||
// Converts lat long coordinates to an MGRS.
|
||||
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
|
||||
const std::string e100kLetters[3] = { "ABCDEFGH", "JKLMNPQR", "STUVWXYZ" };
|
||||
const std::string n100kLetters[2] = { "ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE" };
|
||||
UTM utm;
|
||||
latLongToUTM(lat, lon, utm);
|
||||
mgrs.zone = utm.zone;
|
||||
mgrs.band = utm.band;
|
||||
double col = floor(utm.easting / 100000);
|
||||
mgrs.east100k = e100kLetters[(mgrs.zone - 1) % 3][col - 1];
|
||||
double row = (int32_t)floor(utm.northing / 100000.0) % 20;
|
||||
mgrs.north100k = n100kLetters[(mgrs.zone-1)%2][row];
|
||||
mgrs.easting = (int32_t)utm.easting % 100000;
|
||||
mgrs.northing = (int32_t)utm.northing % 100000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref).
|
||||
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
|
||||
*/
|
||||
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
|
||||
const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
|
||||
double a = 6377563.396; // Airy 1830 semi-major axis
|
||||
double b = 6356256.909; // Airy 1830 semi-minor axis
|
||||
double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
|
||||
double phi0 = toRadians(49);
|
||||
double lambda0 = toRadians(-2);
|
||||
double n0 = -100000;
|
||||
double e0 = 400000;
|
||||
double e2 = 1 - (b*b)/(a*a); // eccentricity squared
|
||||
double n = (a - b)/(a + b);
|
||||
|
||||
double osgb_Latitude;
|
||||
double osgb_Longitude;
|
||||
convertWGS84ToOSGB36(lat, lon, osgb_Latitude, osgb_Longitude);
|
||||
double phi = osgb_Latitude; // already in radians
|
||||
double lambda = osgb_Longitude; // already in radians
|
||||
double v = a * f0 / sqrt(1 - e2 * sin(phi) * sin(phi));
|
||||
double rho = a * f0 * (1 - e2) / pow(1 - e2 * sin(phi) * sin(phi), 1.5);
|
||||
double eta2 = v / rho - 1;
|
||||
double mA = (1 + n + (5/4)*n*n + (5/4)*n*n*n) * (phi - phi0);
|
||||
double mB = (3*n + 3*n*n + (21/8)*n*n*n) * sin(phi - phi0) * cos(phi + phi0);
|
||||
// loss of precision in mC & mD due to floating point rounding can cause innaccuracy of northing by a few meters
|
||||
double mC = (15/8*n*n + 15/8*n*n*n) * sin(2*(phi - phi0)) * cos(2*(phi + phi0));
|
||||
double mD = (35/24)*n*n*n * sin(3*(phi - phi0)) * cos(3*(phi + phi0));
|
||||
double m = b*f0*(mA - mB + mC - mD);
|
||||
|
||||
double cos3Phi = cos(phi)*cos(phi)*cos(phi);
|
||||
double cos5Phi = cos3Phi*cos(phi)*cos(phi);
|
||||
double tan2Phi = tan(phi)*tan(phi);
|
||||
double tan4Phi = tan2Phi*tan2Phi;
|
||||
double I = m + n0;
|
||||
double II = (v/2)*sin(phi)*cos(phi);
|
||||
double III = (v/24)*sin(phi)*cos3Phi*(5 - tan2Phi + 9*eta2);
|
||||
double IIIA = (v/720)*sin(phi)*cos5Phi*(61 - 58*tan2Phi + tan4Phi);
|
||||
double IV = v*cos(phi);
|
||||
double V = (v/6)*cos3Phi*(v/rho - tan2Phi);
|
||||
double VI = (v/120)*cos5Phi*(5 - 18*tan2Phi + tan4Phi + 14*eta2 - 58*tan2Phi*eta2);
|
||||
|
||||
double deltaLambda = lambda - lambda0;
|
||||
double deltaLambda2 = deltaLambda*deltaLambda;
|
||||
double northing = I + II*deltaLambda2 + III*deltaLambda2*deltaLambda2 + IIIA*deltaLambda2*deltaLambda2*deltaLambda2;
|
||||
double easting = e0 + IV*deltaLambda + V*deltaLambda2*deltaLambda + VI*deltaLambda2*deltaLambda2*deltaLambda;
|
||||
|
||||
if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries
|
||||
osgr = { 'I', 'I', 0, 0 };
|
||||
else {
|
||||
uint32_t e100k = floor(easting / 100000);
|
||||
uint32_t n100k = floor(northing / 100000);
|
||||
int8_t l1 = (19 - n100k) - (19 - n100k) % 5 + floor((e100k + 10) / 5);
|
||||
int8_t l2 = (19 - n100k) * 5 % 25 + e100k % 5;
|
||||
osgr.e100k = letter[l1];
|
||||
osgr.n100k = letter[l2];
|
||||
osgr.easting = floor((int)easting % 100000);
|
||||
osgr.northing = floor((int)northing % 100000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts lat long coordinates to Open Location Code.
|
||||
* Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c
|
||||
*/
|
||||
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
|
||||
char tempCode[] = "1234567890abc";
|
||||
const char kAlphabet[] = "23456789CFGHJMPQRVWX";
|
||||
double latitude;
|
||||
double longitude = lon;
|
||||
double latitude_degrees = std::min(90.0, std::max(-90.0, lat));
|
||||
|
||||
if (latitude_degrees < 90) // Check latitude less than lat max
|
||||
latitude = latitude_degrees;
|
||||
else {
|
||||
double precision;
|
||||
if (OLC_CODE_LEN <= 10)
|
||||
precision = pow_neg(20, floor((OLC_CODE_LEN / -2) + 2));
|
||||
else
|
||||
precision = pow_neg(20, -3) / pow(5, OLC_CODE_LEN - 10);
|
||||
latitude = latitude_degrees - precision / 2;
|
||||
}
|
||||
while (longitude < -180) // Normalize longitude
|
||||
longitude += 360;
|
||||
while (longitude >= 180)
|
||||
longitude -= 360;
|
||||
int64_t lat_val = 90 * 2.5e7;
|
||||
int64_t lng_val = 180 * 8.192e6;
|
||||
lat_val += latitude * 2.5e7;
|
||||
lng_val += longitude * 8.192e6;
|
||||
size_t pos = OLC_CODE_LEN;
|
||||
|
||||
if (OLC_CODE_LEN > 10) { // Compute grid part of code if needed
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
int lat_digit = lat_val % 5;
|
||||
int lng_digit = lng_val % 4;
|
||||
int ndx = lat_digit * 4 + lng_digit;
|
||||
tempCode[pos--] = kAlphabet[ndx];
|
||||
lat_val /= 5;
|
||||
lng_val /= 4;
|
||||
}
|
||||
} else {
|
||||
lat_val /= pow(5, 5);
|
||||
lng_val /= pow(4, 5);
|
||||
}
|
||||
|
||||
pos = 10;
|
||||
|
||||
for (size_t i = 0; i < 5; i++) { // Compute pair section of code
|
||||
int lat_ndx = lat_val % 20;
|
||||
int lng_ndx = lng_val % 20;
|
||||
tempCode[pos--] = kAlphabet[lng_ndx];
|
||||
tempCode[pos--] = kAlphabet[lat_ndx];
|
||||
lat_val /= 20;
|
||||
lng_val /= 20;
|
||||
|
||||
if (i == 0)
|
||||
tempCode[pos--] = '+';
|
||||
}
|
||||
|
||||
if (OLC_CODE_LEN < 9) { // Add padding if needed
|
||||
for (size_t i = OLC_CODE_LEN; i < 9; i++)
|
||||
tempCode[i] = '0';
|
||||
tempCode[9] = '+';
|
||||
}
|
||||
|
||||
size_t char_count = OLC_CODE_LEN;
|
||||
if (10 > char_count) {
|
||||
char_count = 10;
|
||||
}
|
||||
for (size_t i = 0; i < char_count; i++) {
|
||||
olc.code[i] = tempCode[i];
|
||||
}
|
||||
olc.code[char_count] = '\0';
|
||||
}
|
||||
|
||||
// Converts the coordinate in WGS84 datum to the OSGB36 datum.
|
||||
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude) {
|
||||
// Convert lat long to cartesian
|
||||
double phi = toRadians(lat);
|
||||
double lambda = toRadians(lon);
|
||||
double h = 0.0; // No OSTN height data used, some loss of accuracy (up to 5m)
|
||||
double wgsA = 6378137; // WGS84 datum semi major axis
|
||||
double wgsF = 1 / 298.257223563; // WGS84 datum flattening
|
||||
double ecc = 2*wgsF - wgsF*wgsF;
|
||||
double vee = wgsA / sqrt(1 - ecc * pow(sin(phi), 2));
|
||||
double wgsX = (vee + h) * cos(phi) * cos(lambda);
|
||||
double wgsY = (vee + h) * cos(phi) * sin(lambda);
|
||||
double wgsZ = ((1 - ecc) * vee + h) * sin(phi);
|
||||
|
||||
// 7-parameter Helmert transform
|
||||
double tx = -446.448; // x shift in meters
|
||||
double ty = 125.157; // y shift in meters
|
||||
double tz = -542.060; // z shift in meters
|
||||
double s = 20.4894/1e6 + 1; // scale normalized parts per million to (s + 1)
|
||||
double rx = toRadians(-0.1502/3600); // x rotation normalize arcseconds to radians
|
||||
double ry = toRadians(-0.2470/3600); // y rotation normalize arcseconds to radians
|
||||
double rz = toRadians(-0.8421/3600); // z rotation normalize arcseconds to radians
|
||||
double osgbX = tx + wgsX*s - wgsY*rz + wgsZ*ry;
|
||||
double osgbY = ty + wgsX*rz + wgsY*s - wgsZ*rx;
|
||||
double osgbZ = tz - wgsX*ry + wgsY*rx + wgsZ*s;
|
||||
|
||||
// Convert cartesian to lat long
|
||||
double airyA = 6377563.396; // Airy1830 datum semi major axis
|
||||
double airyB = 6356256.909; // Airy1830 datum semi minor axis
|
||||
double airyF = 1/ 299.3249646; // Airy1830 datum flattening
|
||||
double airyEcc = 2*airyF - airyF*airyF;
|
||||
double airyEcc2 = airyEcc / (1 - airyEcc);
|
||||
double p = sqrt(osgbX*osgbX + osgbY*osgbY);
|
||||
double R = sqrt(p*p + osgbZ*osgbZ);
|
||||
double tanBeta = (airyB*osgbZ) / (airyA*p) * (1 + airyEcc2*airyB/R);
|
||||
double sinBeta = tanBeta / sqrt(1 + tanBeta*tanBeta);
|
||||
double cosBeta = sinBeta / tanBeta;
|
||||
osgb_Latitude = atan2(osgbZ + airyEcc2*airyB*sinBeta*sinBeta*sinBeta, p - airyEcc*airyA*cosBeta*cosBeta*cosBeta); // leave in radians
|
||||
osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
|
||||
//osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
|
||||
//(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
|
||||
}
|
||||
|
||||
/// Ported from my old java code, returns distance in meters along the globe
|
||||
/// surface (by magic?)
|
||||
float GeoCoord::latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b)
|
||||
{
|
||||
double pk = (180 / 3.14169);
|
||||
double a1 = lat_a / pk;
|
||||
double a2 = lng_a / pk;
|
||||
double b1 = lat_b / pk;
|
||||
double b2 = lng_b / pk;
|
||||
double cos_b1 = cos(b1);
|
||||
double cos_a1 = cos(a1);
|
||||
double t1 = cos_a1 * cos(a2) * cos_b1 * cos(b2);
|
||||
double t2 = cos_a1 * sin(a2) * cos_b1 * sin(b2);
|
||||
double t3 = sin(a1) * sin(b1);
|
||||
double tt = acos(t1 + t2 + t3);
|
||||
if (std::isnan(tt))
|
||||
tt = 0.0; // Must have been the same point?
|
||||
|
||||
return (float)(6366000 * tt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the bearing in degrees between two points on Earth. Ported from my
|
||||
* old Gaggle android app.
|
||||
*
|
||||
* @param lat1
|
||||
* Latitude of the first point
|
||||
* @param lon1
|
||||
* Longitude of the first point
|
||||
* @param lat2
|
||||
* Latitude of the second point
|
||||
* @param lon2
|
||||
* Longitude of the second point
|
||||
* @return Bearing between the two points in radians. A value of 0 means due
|
||||
* north.
|
||||
*/
|
||||
float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
|
||||
{
|
||||
double lat1Rad = toRadians(lat1);
|
||||
double lat2Rad = toRadians(lat2);
|
||||
double deltaLonRad = toRadians(lon2 - lon1);
|
||||
double y = sin(deltaLonRad) * cos(lat2Rad);
|
||||
double x = cos(lat1Rad) * sin(lat2Rad) - (sin(lat1Rad) * cos(lat2Rad) * cos(deltaLonRad));
|
||||
return atan2(y, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ported from http://www.edwilliams.org/avform147.htm#Intro
|
||||
* @brief Convert from meters to range in radians on a great circle
|
||||
* @param range_meters
|
||||
* The range in meters
|
||||
* @return range in radians on a great circle
|
||||
*/
|
||||
float GeoCoord::rangeMetersToRadians(double range_meters) {
|
||||
// 1 nm is 1852 meters
|
||||
double distance_nm = range_meters * 1852;
|
||||
return (PI / (180 * 60)) *distance_nm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ported from http://www.edwilliams.org/avform147.htm#Intro
|
||||
* @brief Convert from radians to range in meters on a great circle
|
||||
* @param range_radians
|
||||
* The range in radians
|
||||
* @return Range in meters on a great circle
|
||||
*/
|
||||
float GeoCoord::rangeRadiansToMeters(double range_radians) {
|
||||
double distance_nm = ((180 * 60) / PI) * range_radians;
|
||||
// 1 meter is 0.000539957 nm
|
||||
return distance_nm * 0.000539957;
|
||||
}
|
||||
|
||||
// Find distance from point to passed in point
|
||||
int32_t GeoCoord::distanceTo(const GeoCoord& pointB) {
|
||||
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
|
||||
}
|
||||
|
||||
// Find bearing from point to passed in point
|
||||
int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
|
||||
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new point bassed on the passed in poin
|
||||
* Ported from http://www.edwilliams.org/avform147.htm#LL
|
||||
* @param bearing
|
||||
* The bearing in raidans
|
||||
* @param range_meters
|
||||
* range in meters
|
||||
* @return GeoCoord object of point at bearing and range from initial point
|
||||
*/
|
||||
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters) {
|
||||
double range_radians = rangeMetersToRadians(range_meters);
|
||||
double lat1 = this->getLatitude() * 1e-7;
|
||||
double lon1 = this->getLongitude() * 1e-7;
|
||||
double lat = asin(sin(lat1) * cos(range_radians) + cos(lat1) * sin(range_radians) * cos(bearing));
|
||||
double dlon = atan2(sin(bearing) * sin(range_radians) * cos(lat1), cos(range_radians) - sin(lat1) * sin(lat));
|
||||
double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI;
|
||||
|
||||
return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude());
|
||||
|
||||
}
|
||||
164
src/gps/GeoCoord.h
Normal file
164
src/gps/GeoCoord.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define OLC_CODE_LEN 11
|
||||
|
||||
// Helper functions
|
||||
// Raises a number to an exponent, handling negative exponents.
|
||||
static inline double pow_neg(double base, double exponent) {
|
||||
if (exponent == 0) {
|
||||
return 1;
|
||||
} else if (exponent > 0) {
|
||||
return pow(base, exponent);
|
||||
}
|
||||
return 1 / pow(base, -exponent);
|
||||
}
|
||||
|
||||
static inline double toRadians(double deg)
|
||||
{
|
||||
return deg * PI / 180;
|
||||
}
|
||||
|
||||
static inline double toDegrees(double r)
|
||||
{
|
||||
return r * 180 / PI;
|
||||
}
|
||||
|
||||
// GeoCoord structs/classes
|
||||
// A struct to hold the data for a DMS coordinate.
|
||||
struct DMS
|
||||
{
|
||||
uint8_t latDeg;
|
||||
uint8_t latMin;
|
||||
uint32_t latSec;
|
||||
char latCP;
|
||||
uint8_t lonDeg;
|
||||
uint8_t lonMin;
|
||||
uint32_t lonSec;
|
||||
char lonCP;
|
||||
};
|
||||
|
||||
// A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate.
|
||||
struct UTM
|
||||
{
|
||||
uint8_t zone;
|
||||
char band;
|
||||
uint32_t easting;
|
||||
uint32_t northing;
|
||||
};
|
||||
|
||||
// A struct to hold the data for a MGRS coordinate.
|
||||
struct MGRS
|
||||
{
|
||||
uint8_t zone;
|
||||
char band;
|
||||
char east100k;
|
||||
char north100k;
|
||||
uint32_t easting;
|
||||
uint32_t northing;
|
||||
};
|
||||
|
||||
// A struct to hold the data for a OSGR coordiante
|
||||
struct OSGR {
|
||||
char e100k;
|
||||
char n100k;
|
||||
uint32_t easting;
|
||||
uint32_t northing;
|
||||
};
|
||||
|
||||
// A struct to hold the data for a OLC coordinate
|
||||
struct OLC {
|
||||
char code[OLC_CODE_LEN + 1]; // +1 for null termination
|
||||
};
|
||||
|
||||
class GeoCoord {
|
||||
private:
|
||||
int32_t _latitude = 0;
|
||||
int32_t _longitude = 0;
|
||||
int32_t _altitude = 0;
|
||||
|
||||
DMS _dms = {};
|
||||
UTM _utm = {};
|
||||
MGRS _mgrs = {};
|
||||
OSGR _osgr = {};
|
||||
OLC _olc = {};
|
||||
|
||||
bool _dirty = true;
|
||||
|
||||
void setCoords();
|
||||
|
||||
public:
|
||||
GeoCoord();
|
||||
GeoCoord(int32_t lat, int32_t lon, int32_t alt);
|
||||
GeoCoord(double lat, double lon, int32_t alt);
|
||||
GeoCoord(float lat, float lon, int32_t alt);
|
||||
|
||||
void updateCoords(const int32_t lat, const int32_t lon, const int32_t alt);
|
||||
void updateCoords(const double lat, const double lon, const int32_t alt);
|
||||
void updateCoords(const float lat, const float lon, const int32_t alt);
|
||||
|
||||
// Conversions
|
||||
static void latLongToDMS(const double lat, const double lon, DMS &dms);
|
||||
static void latLongToUTM(const double lat, const double lon, UTM &utm);
|
||||
static void latLongToMGRS(const double lat, const double lon, MGRS &mgrs);
|
||||
static void latLongToOSGR(const double lat, const double lon, OSGR &osgr);
|
||||
static void latLongToOLC(const double lat, const double lon, OLC &olc);
|
||||
static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
|
||||
static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
|
||||
static float bearing(double lat1, double lon1, double lat2, double lon2);
|
||||
static float rangeRadiansToMeters(double range_radians);
|
||||
static float rangeMetersToRadians(double range_meters);
|
||||
|
||||
// Point to point conversions
|
||||
int32_t distanceTo(const GeoCoord& pointB);
|
||||
int32_t bearingTo(const GeoCoord& pointB);
|
||||
std::shared_ptr<GeoCoord> pointAtDistance(double bearing, double range);
|
||||
|
||||
// Lat lon alt getters
|
||||
int32_t getLatitude() const { return _latitude; }
|
||||
int32_t getLongitude() const { return _longitude; }
|
||||
int32_t getAltitude() const { return _altitude; }
|
||||
|
||||
// DMS getters
|
||||
uint8_t getDMSLatDeg() const { return _dms.latDeg; }
|
||||
uint8_t getDMSLatMin() const { return _dms.latMin; }
|
||||
uint32_t getDMSLatSec() const { return _dms.latSec; }
|
||||
char getDMSLatCP() const { return _dms.latCP; }
|
||||
uint8_t getDMSLonDeg() const { return _dms.lonDeg; }
|
||||
uint8_t getDMSLonMin() const { return _dms.lonMin; }
|
||||
uint32_t getDMSLonSec() const { return _dms.lonSec; }
|
||||
char getDMSLonCP() const { return _dms.lonCP; }
|
||||
|
||||
// UTM getters
|
||||
uint8_t getUTMZone() const { return _utm.zone; }
|
||||
char getUTMBand() const { return _utm.band; }
|
||||
uint32_t getUTMEasting() const { return _utm.easting; }
|
||||
uint32_t getUTMNorthing() const { return _utm.northing; }
|
||||
|
||||
// MGRS getters
|
||||
uint8_t getMGRSZone() const { return _mgrs.zone; }
|
||||
char getMGRSBand() const { return _mgrs.band; }
|
||||
char getMGRSEast100k() const { return _mgrs.east100k; }
|
||||
char getMGRSNorth100k() const { return _mgrs.north100k; }
|
||||
uint32_t getMGRSEasting() const { return _mgrs.easting; }
|
||||
uint32_t getMGRSNorthing() const { return _mgrs.northing; }
|
||||
|
||||
// OSGR getters
|
||||
char getOSGRE100k() const { return _osgr.e100k; }
|
||||
char getOSGRN100k() const { return _osgr.n100k; }
|
||||
uint32_t getOSGREasting() const { return _osgr.easting; }
|
||||
uint32_t getOSGRNorthing() const { return _osgr.northing; }
|
||||
|
||||
// OLC getter
|
||||
void getOLCCode(char* code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user