mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-14 14:52:32 +00:00
Compare commits
530 Commits
custom-esp
...
v2.5.2.771
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
771cb52616 | ||
|
|
10869ea10a | ||
|
|
e4d0e38f37 | ||
|
|
d7badcc9cb | ||
|
|
4fbf666cd9 | ||
|
|
adb094ebc9 | ||
|
|
b709d47832 | ||
|
|
4fde1ca2a8 | ||
|
|
c72612d826 | ||
|
|
682133501a | ||
|
|
b4c09ace23 | ||
|
|
c39d270f40 | ||
|
|
428a567078 | ||
|
|
0ad1f776ae | ||
|
|
e78c706999 | ||
|
|
c442cd7267 | ||
|
|
9cbabb0468 | ||
|
|
9a7a4d3814 | ||
|
|
fa1cc59841 | ||
|
|
e8829b8f52 | ||
|
|
1afd61698b | ||
|
|
3ff9398b92 | ||
|
|
76900555e8 | ||
|
|
1487ca2a30 | ||
|
|
f960164c0e | ||
|
|
11598beb16 | ||
|
|
1f8aa1efc7 | ||
|
|
18aac0ba25 | ||
|
|
2e24d244be | ||
|
|
7db98ca1da | ||
|
|
9f8d86cb25 | ||
|
|
2ff0af55b1 | ||
|
|
51af747508 | ||
|
|
893bbe09d1 | ||
|
|
d21087f639 | ||
|
|
01203eb854 | ||
|
|
2072ebd196 | ||
|
|
202699239f | ||
|
|
906b0233d2 | ||
|
|
d584031d10 | ||
|
|
f324ab7de7 | ||
|
|
54f56438da | ||
|
|
e6c7c80b3f | ||
|
|
c053c7d9ae | ||
|
|
953beb56b1 | ||
|
|
acd044fdea | ||
|
|
de706523f5 | ||
|
|
52cef05c70 | ||
|
|
6490cadd35 | ||
|
|
3882841283 | ||
|
|
74e6470439 | ||
|
|
dca711ac24 | ||
|
|
7368cb99dc | ||
|
|
ec848bab52 | ||
|
|
ed13105aec | ||
|
|
c2272ce5a1 | ||
|
|
0664c09f9d | ||
|
|
ba31a7c753 | ||
|
|
85d722232e | ||
|
|
921d92c649 | ||
|
|
0f3450ad44 | ||
|
|
114df8cb1b | ||
|
|
d3a293a0d8 | ||
|
|
91b4199f9d | ||
|
|
6473cf0b69 | ||
|
|
84e197574b | ||
|
|
5c4c0965af | ||
|
|
7289b295e8 | ||
|
|
7c32ab3023 | ||
|
|
2bc036f9eb | ||
|
|
cc89e85e71 | ||
|
|
da45cb8557 | ||
|
|
2ebfcea94e | ||
|
|
deada41cee | ||
|
|
777bcf691a | ||
|
|
35e1c401e2 | ||
|
|
19c57e8ec6 | ||
|
|
c6196b2260 | ||
|
|
3eebdcefa4 | ||
|
|
4289cb089b | ||
|
|
2d52803dbd | ||
|
|
c78302a2ee | ||
|
|
923458bc18 | ||
|
|
50fb4ab22a | ||
|
|
f5016763fd | ||
|
|
2a6921292e | ||
|
|
a47570d65a | ||
|
|
db4dc88d6f | ||
|
|
be306cc384 | ||
|
|
a967dd52f3 | ||
|
|
11378325e0 | ||
|
|
4b5bcf52d2 | ||
|
|
5ba418b2cd | ||
|
|
bc753e6903 | ||
|
|
34a543ec74 | ||
|
|
06cd9abd81 | ||
|
|
af30485611 | ||
|
|
cd6bd1e9a3 | ||
|
|
b025eeb13c | ||
|
|
21eb54e58a | ||
|
|
6f1db6fc63 | ||
|
|
a5118787b3 | ||
|
|
39c90dd581 | ||
|
|
33e6f7f6e0 | ||
|
|
97fd189f43 | ||
|
|
1e665d5181 | ||
|
|
b3343303a9 | ||
|
|
f37276d5fc | ||
|
|
905194c604 | ||
|
|
51b22630b4 | ||
|
|
5d831ef461 | ||
|
|
4e8672cce4 | ||
|
|
41a769aa06 | ||
|
|
8d57b6164a | ||
|
|
dc3eba9100 | ||
|
|
ff8baa1c85 | ||
|
|
3a10a27851 | ||
|
|
8893529653 | ||
|
|
1ab5bf4355 | ||
|
|
ae791ca7e1 | ||
|
|
35cfe4318a | ||
|
|
b59bd6fee9 | ||
|
|
8b911f14cf | ||
|
|
d36c69396b | ||
|
|
3d72fbb19e | ||
|
|
625254cf90 | ||
|
|
910b6b7512 | ||
|
|
371c3e05bf | ||
|
|
f37df4d6bf | ||
|
|
ba9a3cd719 | ||
|
|
9ac0e26d42 | ||
|
|
1ba4f6e222 | ||
|
|
e8e9826adc | ||
|
|
6724f1f7ea | ||
|
|
013021941e | ||
|
|
4e850296b6 | ||
|
|
f1602ee3f6 | ||
|
|
5537f98dd6 | ||
|
|
4ed12bf21d | ||
|
|
106dab23db | ||
|
|
2f9dcee954 | ||
|
|
68d6ff8c24 | ||
|
|
dc8cc122a6 | ||
|
|
e9d55de3cb | ||
|
|
dacb452d47 | ||
|
|
8ab2e91df6 | ||
|
|
e985ee878f | ||
|
|
b2e2f1dba3 | ||
|
|
fabd6b0d6f | ||
|
|
ebe1b40bee | ||
|
|
6217e97c41 | ||
|
|
e470619e3d | ||
|
|
bf34329033 | ||
|
|
8e88b9e819 | ||
|
|
56a2e40681 | ||
|
|
ba28ffb65a | ||
|
|
9651b5a0ec | ||
|
|
2f2ddae12a | ||
|
|
c77b89d85c | ||
|
|
5c2fe4a2c0 | ||
|
|
b8cee51e84 | ||
|
|
fd1ebdf363 | ||
|
|
35b47467c7 | ||
|
|
8f35a42f4f | ||
|
|
35a565cd84 | ||
|
|
ee68e727ed | ||
|
|
962d9ff220 | ||
|
|
8e0a342f06 | ||
|
|
55292f8a84 | ||
|
|
d72a836e07 | ||
|
|
26a3841a93 | ||
|
|
8e519d09b4 | ||
|
|
ae41a7cc06 | ||
|
|
011e640e95 | ||
|
|
e4e1ea971f | ||
|
|
bcdc36c07c | ||
|
|
972a5d5779 | ||
|
|
7c6454f171 | ||
|
|
9e55e6befb | ||
|
|
1d3d44061b | ||
|
|
4d57c99ad1 | ||
|
|
22e23997c1 | ||
|
|
8d29ce939d | ||
|
|
bb9ddcf2b5 | ||
|
|
ff40a3f120 | ||
|
|
8b1d7825b9 | ||
|
|
6fc4a1754b | ||
|
|
d83f8edd54 | ||
|
|
543e7f3342 | ||
|
|
f9e513f4fd | ||
|
|
7dad2286e2 | ||
|
|
190c7ecdd4 | ||
|
|
8598645931 | ||
|
|
3bb1cb8f1d | ||
|
|
cdea602181 | ||
|
|
b526a3ad53 | ||
|
|
2f0c19ebea | ||
|
|
06e27bb6c2 | ||
|
|
0588d69694 | ||
|
|
367d787d74 | ||
|
|
c8bf43de93 | ||
|
|
e543b61dd8 | ||
|
|
1fc6cc2d6c | ||
|
|
719faf4f97 | ||
|
|
3bf20dc3a6 | ||
|
|
d93425fde1 | ||
|
|
234e652a07 | ||
|
|
cd16b7b00a | ||
|
|
24501c30c0 | ||
|
|
7d2f3a3425 | ||
|
|
56223710b5 | ||
|
|
e45a358de0 | ||
|
|
b71e12c5e5 | ||
|
|
eb1f80f520 | ||
|
|
6c0911038a | ||
|
|
644e213b13 | ||
|
|
33eb073535 | ||
|
|
8729cdb699 | ||
|
|
7475cc301e | ||
|
|
eb071ec80d | ||
|
|
8144dcbc25 | ||
|
|
2b0113ae82 | ||
|
|
6a24566efb | ||
|
|
dd933e6bab | ||
|
|
79925406d6 | ||
|
|
5bc17a9911 | ||
|
|
a1d0af6636 | ||
|
|
22454c95c7 | ||
|
|
b99fd93247 | ||
|
|
50631f96fc | ||
|
|
a6cc7041d3 | ||
|
|
171512d2f6 | ||
|
|
db870dc17d | ||
|
|
28d0cef427 | ||
|
|
6d2011c172 | ||
|
|
47e1580a62 | ||
|
|
fc1e60ac58 | ||
|
|
c02bbad9f3 | ||
|
|
f1f66cf54a | ||
|
|
92eae39a1b | ||
|
|
9e20b0e9b9 | ||
|
|
dc9f6e1360 | ||
|
|
a1bf0d8519 | ||
|
|
f5633bf0c5 | ||
|
|
ad931799c9 | ||
|
|
3ad0af5ce8 | ||
|
|
545d32fcec | ||
|
|
94c3bb4a56 | ||
|
|
72c82c1c08 | ||
|
|
cc93df27a5 | ||
|
|
e3ce3a3a4f | ||
|
|
3c4d964334 | ||
|
|
574124aee5 | ||
|
|
1fe80e0f30 | ||
|
|
927a35ef51 | ||
|
|
c11a66030f | ||
|
|
059d5582d1 | ||
|
|
17b2a83b44 | ||
|
|
eddb72705f | ||
|
|
9631a1be38 | ||
|
|
8a9cc727a8 | ||
|
|
cdafa87cef | ||
|
|
5ce5b7b08b | ||
|
|
b285aa5bd6 | ||
|
|
9de0b7cfac | ||
|
|
fe9a80a4e0 | ||
|
|
de41a054b0 | ||
|
|
9b2ef971c2 | ||
|
|
710fdbd4e5 | ||
|
|
06175737cc | ||
|
|
4a2a00a227 | ||
|
|
50f06840d7 | ||
|
|
6660aec79a | ||
|
|
a34170654c | ||
|
|
d611a38ce2 | ||
|
|
5b3579af52 | ||
|
|
f27281d3fa | ||
|
|
59ecea507f | ||
|
|
f7f21ecefd | ||
|
|
d1e64c74de | ||
|
|
b8609ff130 | ||
|
|
ef9ecec341 | ||
|
|
0ee9d375b3 | ||
|
|
50d778d281 | ||
|
|
ab62590aa9 | ||
|
|
ada61ae178 | ||
|
|
b9a8683a4b | ||
|
|
5824a8f4c1 | ||
|
|
777ae2b99c | ||
|
|
d0fd17134e | ||
|
|
d6dac1737a | ||
|
|
23844389ac | ||
|
|
8847945734 | ||
|
|
5514aab007 | ||
|
|
aa54335e21 | ||
|
|
2a279c7f3d | ||
|
|
7abc194ef5 | ||
|
|
f99b81acf7 | ||
|
|
0850ad6c8d | ||
|
|
00ea9182a4 | ||
|
|
601ae29fe9 | ||
|
|
ff500bc5a9 | ||
|
|
e6163a59cd | ||
|
|
5c5cbb23cf | ||
|
|
f77c5f6a5b | ||
|
|
2a7cf9d387 | ||
|
|
db6e591c07 | ||
|
|
02c34e6214 | ||
|
|
5570b6bbc6 | ||
|
|
2dda640d27 | ||
|
|
5ccb6df142 | ||
|
|
3ae8aadaf0 | ||
|
|
7fb9b094d5 | ||
|
|
734f36589d | ||
|
|
1e655052fc | ||
|
|
d017fc7a5d | ||
|
|
6ddee795d6 | ||
|
|
d556ae762c | ||
|
|
48e0fd7ed0 | ||
|
|
b19c1a52cb | ||
|
|
ba771ae507 | ||
|
|
9014058935 | ||
|
|
ab7de7f6a0 | ||
|
|
6ee30043c3 | ||
|
|
314009a10f | ||
|
|
2d9126f873 | ||
|
|
d404a49336 | ||
|
|
ee9e46ec92 | ||
|
|
929b3e4f88 | ||
|
|
2043ad3bd0 | ||
|
|
2472c7cdc7 | ||
|
|
058e9769d6 | ||
|
|
3b2c37c47f | ||
|
|
ef5279e85e | ||
|
|
bd21a0455b | ||
|
|
9b4ad68f43 | ||
|
|
e20d57f3ad | ||
|
|
33b12126e0 | ||
|
|
9d323a3832 | ||
|
|
2a664e01b0 | ||
|
|
c1569b0f70 | ||
|
|
48dc222b75 | ||
|
|
ab9268cba9 | ||
|
|
6de3ca4301 | ||
|
|
e65e79c6c9 | ||
|
|
14146d6ff5 | ||
|
|
273beef148 | ||
|
|
94d5ee9fe6 | ||
|
|
7b64c4a5bf | ||
|
|
ecb4fb72db | ||
|
|
f439081674 | ||
|
|
bfbc4bf93a | ||
|
|
22e129e716 | ||
|
|
a85df199a5 | ||
|
|
7a65c8838d | ||
|
|
e3e36e23f9 | ||
|
|
7129cee944 | ||
|
|
23e3e6db92 | ||
|
|
a8999d7759 | ||
|
|
c7c620ac69 | ||
|
|
1bbc273ba6 | ||
|
|
33ced7e87a | ||
|
|
578ac6711b | ||
|
|
e37acae405 | ||
|
|
daddaf7146 | ||
|
|
5ff1078c8c | ||
|
|
0b010b4fd8 | ||
|
|
f86dde3c40 | ||
|
|
fdaaf71366 | ||
|
|
a577dd4142 | ||
|
|
9dad62e3c4 | ||
|
|
e0b4a8e31e | ||
|
|
7cbae56e6c | ||
|
|
6eabbaf432 | ||
|
|
cec8233cd1 | ||
|
|
0ebdc7ab0c | ||
|
|
e61bd84116 | ||
|
|
b0c1b7b7b5 | ||
|
|
eefe9efa9f | ||
|
|
390de724ba | ||
|
|
85176756ec | ||
|
|
6f1dae1b1b | ||
|
|
ef56fae976 | ||
|
|
d398419aef | ||
|
|
96cf78aadd | ||
|
|
ced87596cb | ||
|
|
1be635a797 | ||
|
|
36f1a62b0b | ||
|
|
8ef72a5c08 | ||
|
|
efc27f2051 | ||
|
|
837c4e9e7b | ||
|
|
181325103a | ||
|
|
207b9b49a5 | ||
|
|
8ce1c07c4e | ||
|
|
2661fc694f | ||
|
|
b528290fde | ||
|
|
ff89dca5b3 | ||
|
|
80fd121d87 | ||
|
|
f3fa8daedf | ||
|
|
bcd77c4523 | ||
|
|
308c0a6bb8 | ||
|
|
754db3f2bc | ||
|
|
c16f20de21 | ||
|
|
b4cbea1b3d | ||
|
|
0e7253d309 | ||
|
|
b91d66b436 | ||
|
|
7537b55586 | ||
|
|
2d18130235 | ||
|
|
67ddae2851 | ||
|
|
884bc529f0 | ||
|
|
8f3614d66c | ||
|
|
e7dfabc20f | ||
|
|
185eb318ad | ||
|
|
c86a3200f0 | ||
|
|
c3aa56ef30 | ||
|
|
192af05a25 | ||
|
|
26d0b2b477 | ||
|
|
b726792efd | ||
|
|
c451db3a3f | ||
|
|
95682c9095 | ||
|
|
da53b8152d | ||
|
|
8d1a34a4bf | ||
|
|
464f270b12 | ||
|
|
7740b4bccd | ||
|
|
e85a2e827b | ||
|
|
62a0321c7d | ||
|
|
6e8300287b | ||
|
|
f97ae52263 | ||
|
|
9bd293a941 | ||
|
|
bc69621c3e | ||
|
|
2ee53d1500 | ||
|
|
bee959150b | ||
|
|
c74bce9360 | ||
|
|
48eee747da | ||
|
|
a28f10e0c2 | ||
|
|
6cd1882aaa | ||
|
|
0bd17e6da6 | ||
|
|
9bc2224164 | ||
|
|
e1b4b226c9 | ||
|
|
cf392a4c20 | ||
|
|
54a2e14e35 | ||
|
|
1cfd5d12d2 | ||
|
|
b573e0eacc | ||
|
|
8ca884bafd | ||
|
|
864b793ce0 | ||
|
|
74afd13171 | ||
|
|
8daebf80dd | ||
|
|
a767997cea | ||
|
|
861f0b6769 | ||
|
|
2012a0ae1c | ||
|
|
3513d88794 | ||
|
|
debf4b934f | ||
|
|
3878e025e4 | ||
|
|
3ab4bebdcb | ||
|
|
e38aca3cba | ||
|
|
d8bdb92efe | ||
|
|
c6a9edf8c7 | ||
|
|
a7da3537e2 | ||
|
|
5b4530325f | ||
|
|
b498c0bfbf | ||
|
|
02ae24b6fa | ||
|
|
5111bd703a | ||
|
|
789e8f02bf | ||
|
|
92526fca23 | ||
|
|
9ec7dbd695 | ||
|
|
66c41e683d | ||
|
|
c1870f91fc | ||
|
|
06eaf2ba5d | ||
|
|
4a79a690db | ||
|
|
1f458d6397 | ||
|
|
02231fd487 | ||
|
|
66a4632f34 | ||
|
|
e509a91019 | ||
|
|
d8f3c3324c | ||
|
|
9ddfc6de4c | ||
|
|
1a38c4e51d | ||
|
|
40d6b99911 | ||
|
|
7d00e1cef9 | ||
|
|
5bbafdfd31 | ||
|
|
5453c495e2 | ||
|
|
d1ff160256 | ||
|
|
dd552a99e1 | ||
|
|
09ea198205 | ||
|
|
703da1d8c7 | ||
|
|
48c0635188 | ||
|
|
8db6039264 | ||
|
|
4b4c1669a9 | ||
|
|
d2ea430a3e | ||
|
|
4c1c5b070e | ||
|
|
bcdda4de8a | ||
|
|
24ecfa1a45 | ||
|
|
106a50bce2 | ||
|
|
103ab0c242 | ||
|
|
848b9773b9 | ||
|
|
ce1eb149ac | ||
|
|
29fe6e7448 | ||
|
|
a111f54b61 | ||
|
|
9f5f630dca | ||
|
|
1f9dacf486 | ||
|
|
5dde738a31 | ||
|
|
1951569b1a | ||
|
|
93ba19d1e1 | ||
|
|
a1c998e7e0 | ||
|
|
302caa854a | ||
|
|
59cc57fc29 | ||
|
|
6813b8e4e9 | ||
|
|
4aa6f60e95 | ||
|
|
2ffc93324d | ||
|
|
c501cc501d | ||
|
|
8c0ff89972 | ||
|
|
cf22b7ff04 | ||
|
|
811a9ae261 | ||
|
|
8b0208d1c6 | ||
|
|
1a1d545c38 | ||
|
|
32bc2f1137 | ||
|
|
1b249c32bf | ||
|
|
bca9fbe7e4 | ||
|
|
e70435ebd7 | ||
|
|
f583837b4e | ||
|
|
6f235232f0 | ||
|
|
8641777bac | ||
|
|
4ee15d8128 | ||
|
|
394e0e1b3e | ||
|
|
755952c261 | ||
|
|
f645ae943d | ||
|
|
4b0bbb8af1 | ||
|
|
7ac64bd762 | ||
|
|
1481ce987e | ||
|
|
c5f2d2736d | ||
|
|
a000a8d347 |
25
.devcontainer/Dockerfile
Normal file
25
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
|
||||
|
||||
# [Optional] Uncomment this section to install additional packages.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends \
|
||||
ca-certificates \
|
||||
g++ \
|
||||
git \
|
||||
libbluetooth-dev \
|
||||
libgpiod-dev \
|
||||
liborcania-dev \
|
||||
libssl-dev \
|
||||
libulfius-dev \
|
||||
libyaml-cpp-dev \
|
||||
pipx \
|
||||
pkg-config \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
python3-wheel \
|
||||
wget \
|
||||
zip \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pipx install platformio==6.1.15
|
||||
28
.devcontainer/devcontainer.json
Normal file
28
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,28 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/cpp
|
||||
{
|
||||
"name": "Meshtastic Firmware Dev",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/python:1": {
|
||||
"installTools": true,
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"platformio.platformio-ide",
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [ 4403 ],
|
||||
|
||||
// Run commands to prepare the container for use
|
||||
"postCreateCommand": ".devcontainer/setup.sh",
|
||||
}
|
||||
3
.devcontainer/setup.sh
Executable file
3
.devcontainer/setup.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
git submodule update --init
|
||||
14
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
14
.github/ISSUE_TEMPLATE/Bug Report.yml
vendored
@@ -49,10 +49,24 @@ body:
|
||||
- Heltec V3
|
||||
- Heltec Wireless Paper
|
||||
- Heltec Wireless Tracker
|
||||
- Heltec Mesh Node T114
|
||||
- Heltec Vision Master E213
|
||||
- Heltec Vision Master E290
|
||||
- Heltec Vision Master T190
|
||||
- Nano G1
|
||||
- Nano G1 Explorer
|
||||
- Nano G2 Ultra
|
||||
- Raspberry Pi Pico (W)
|
||||
- Relay v1
|
||||
- Relay v2
|
||||
- Seeed Wio Tracker 1110
|
||||
- Seeed Card Tracker T1000-E
|
||||
- Station G1
|
||||
- Station G2
|
||||
- unPhone
|
||||
- CanaryOne
|
||||
- Chatter
|
||||
- Linux Native
|
||||
- DIY
|
||||
- Other
|
||||
validations:
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/feature.yml
vendored
1
.github/ISSUE_TEMPLATE/feature.yml
vendored
@@ -18,6 +18,7 @@ body:
|
||||
- ESP32
|
||||
- RP2040
|
||||
- Linux Native
|
||||
- Cross-Platform
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
90
.github/actions/build-variant/action.yml
vendored
Normal file
90
.github/actions/build-variant/action.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: Setup Build Variant Composite Action
|
||||
description: Variant build actions for Meshtastic Platform IO steps
|
||||
|
||||
inputs:
|
||||
board:
|
||||
description: The board to build for
|
||||
required: true
|
||||
github_token:
|
||||
description: GitHub token
|
||||
required: true
|
||||
build-script-path:
|
||||
description: Path to the build script
|
||||
required: true
|
||||
remove-debug-flags:
|
||||
description: A space separated list of files to remove debug flags from
|
||||
required: false
|
||||
default: ""
|
||||
ota-firmware-source:
|
||||
description: The OTA firmware file to pull
|
||||
required: false
|
||||
default: ""
|
||||
ota-firmware-target:
|
||||
description: The target path to store the OTA firmware file
|
||||
required: false
|
||||
default: ""
|
||||
artifact-paths:
|
||||
description: A newline separated list of paths to store as artifacts
|
||||
required: false
|
||||
default: ""
|
||||
include-web-ui:
|
||||
description: Include the web UI in the build
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Pull web ui
|
||||
if: inputs.include-web-ui == 'true'
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: meshtastic/web
|
||||
file: build.tar
|
||||
target: build.tar
|
||||
token: ${{ inputs.github_token }}
|
||||
|
||||
- name: Unpack web ui
|
||||
if: inputs.include-web-ui == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
- name: Remove debug flags for release
|
||||
shell: bash
|
||||
if: inputs.remove-debug-flags != ''
|
||||
run: |
|
||||
for INI_FILE in ${{ inputs.remove-debug-flags }}; do
|
||||
sed -i '/DDEBUG_HEAP/d' ${INI_FILE}
|
||||
done
|
||||
|
||||
- name: Build ${{ inputs.board }}
|
||||
shell: bash
|
||||
run: ${{ inputs.build-script-path }} ${{ inputs.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
if: inputs.ota-firmware-source != '' && inputs.ota-firmware-target != ''
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: meshtastic/firmware-ota
|
||||
file: ${{ inputs.ota-firmware-source }}
|
||||
target: ${{ inputs.ota-firmware-target }}
|
||||
token: ${{ inputs.github_token }}
|
||||
|
||||
- name: Get release version string
|
||||
shell: bash
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
${{ inputs.artifact-paths }}
|
||||
20
.github/actions/setup-base/action.yml
vendored
20
.github/actions/setup-base/action.yml
vendored
@@ -11,7 +11,7 @@ runs:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install dependencies
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get -y update --fix-missing
|
||||
@@ -22,19 +22,21 @@ runs:
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v4
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
# - name: Cache python libs
|
||||
# uses: actions/cache@v4
|
||||
# id: cache-pip # needed in if test
|
||||
# with:
|
||||
# path: ~/.cache/pip
|
||||
# key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
pip install -U meshtastic --pre
|
||||
pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
|
||||
pip install -U platformio adafruit-nrfutil --no-build-isolation
|
||||
pip install -U poetry --no-build-isolation
|
||||
pip install -U meshtastic --pre --no-build-isolation
|
||||
|
||||
- name: Upgrade platformio
|
||||
shell: bash
|
||||
|
||||
26
.github/dependabot.yml
vendored
Normal file
26
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: docker
|
||||
directory: devcontainer
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: gitsubmodule
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
timezone: US/Pacific
|
||||
- package-ecosystem: github-actions
|
||||
directory: /.github/workflows
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
|
||||
timezone: US/Pacific
|
||||
7
.github/pull_request_template.md
vendored
7
.github/pull_request_template.md
vendored
@@ -1,9 +1,9 @@
|
||||
### ❌ (Please delete all these tips and replace them with your text) ❌
|
||||
|
||||
## Thank you for sending in a pull request, here's some tips to get started!
|
||||
|
||||
(Please delete all these tips and replace with your text)
|
||||
|
||||
- Before starting on some new big chunk of code, it it is optional but highly recommended to open an issue first
|
||||
to say "hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
||||
to say "Hey, I think this idea X should be implemented and I'm starting work on it. My general plan is Y, any feedback
|
||||
is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc...
|
||||
- Please do not check in files that don't have real changes
|
||||
- Please do not reformat lines that you didn't have to change the code on
|
||||
@@ -12,3 +12,4 @@
|
||||
- If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description.
|
||||
- If your other co-developers have comments on your PR please tweak as needed.
|
||||
- Please also enable "Allow edits by maintainers".
|
||||
- If your PR gets accepted you can request a "Contributor" role in the Meshtastic Discord
|
||||
|
||||
58
.github/workflows/build_esp32.yml
vendored
58
.github/workflows/build_esp32.yml
vendored
@@ -12,52 +12,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: 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: Remove debug flags for release
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
repo: meshtastic/firmware-ota
|
||||
file: firmware.bin
|
||||
target: release/bleota.bin
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
shell: bash
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
remove-debug-flags: >-
|
||||
./arch/esp32/esp32.ini
|
||||
./arch/esp32/esp32s2.ini
|
||||
./arch/esp32/esp32s3.ini
|
||||
./arch/esp32/esp32c3.ini
|
||||
build-script-path: bin/build-esp32.sh
|
||||
ota-firmware-source: firmware.bin
|
||||
ota-firmware-target: release/bleota.bin
|
||||
artifact-paths: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
include-web-ui: true
|
||||
|
||||
57
.github/workflows/build_esp32_c3.yml
vendored
57
.github/workflows/build_esp32_c3.yml
vendored
@@ -14,50 +14,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
- name: Build ESP32-C3
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
repo: 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: Remove debug flags for release
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: meshtastic/firmware-ota
|
||||
file: firmware-c3.bin
|
||||
target: release/bleota-c3.bin
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
shell: bash
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
remove-debug-flags: >-
|
||||
./arch/esp32/esp32.ini
|
||||
./arch/esp32/esp32s2.ini
|
||||
./arch/esp32/esp32s3.ini
|
||||
./arch/esp32/esp32c3.ini
|
||||
build-script-path: bin/build-esp32.sh
|
||||
ota-firmware-source: firmware-c3.bin
|
||||
ota-firmware-target: release/bleota-c3.bin
|
||||
artifact-paths: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
|
||||
58
.github/workflows/build_esp32_s3.yml
vendored
58
.github/workflows/build_esp32_s3.yml
vendored
@@ -12,50 +12,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
- name: Build ESP32-S3
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
repo: 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: Remove debug flags for release
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
run: |
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32c3.ini
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: meshtastic/firmware-ota
|
||||
file: firmware-s3.bin
|
||||
target: release/bleota-s3.bin
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
shell: bash
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
remove-debug-flags: >-
|
||||
./arch/esp32/esp32.ini
|
||||
./arch/esp32/esp32s2.ini
|
||||
./arch/esp32/esp32s3.ini
|
||||
./arch/esp32/esp32c3.ini
|
||||
build-script-path: bin/build-esp32.sh
|
||||
ota-firmware-source: firmware-s3.bin
|
||||
ota-firmware-target: release/bleota-s3.bin
|
||||
artifact-paths: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
include-web-ui: true
|
||||
|
||||
6
.github/workflows/build_native.yml
vendored
6
.github/workflows/build_native.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
build-native:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install libbluetooth
|
||||
- name: Install libs needed for native build
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update --fix-missing
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
- name: Docker build and push tagged versions
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
continue-on-error: true # FIXME: Failing docker login auth
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
- name: Docker build and push
|
||||
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }}
|
||||
continue-on-error: true # FIXME: Failing docker login auth
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
20
.github/workflows/build_nrf52.yml
vendored
20
.github/workflows/build_nrf52.yml
vendored
@@ -12,23 +12,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Build NRF52
|
||||
run: bin/build-nrf52.sh ${{ inputs.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
build-script-path: bin/build-nrf52.sh
|
||||
artifact-paths: |
|
||||
release/*.hex
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
|
||||
20
.github/workflows/build_rpi2040.yml
vendored
20
.github/workflows/build_rpi2040.yml
vendored
@@ -12,22 +12,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Build Raspberry Pi 2040
|
||||
run: ./bin/build-rpi2040.sh ${{ inputs.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
overwrite: true
|
||||
path: |
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
build-script-path: bin/build-rpi2040.sh
|
||||
artifact-paths: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
|
||||
25
.github/workflows/build_stm32.yml
vendored
Normal file
25
.github/workflows/build_stm32.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Build STM32
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
board:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-stm32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build Raspberry Pi 2040
|
||||
id: build
|
||||
uses: ./.github/actions/build-variant
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
board: ${{ inputs.board }}
|
||||
build-script-path: bin/build-stm32.sh
|
||||
artifact-paths: |
|
||||
release/*.hex
|
||||
release/*.bin
|
||||
88
.github/workflows/main_matrix.yml
vendored
88
.github/workflows/main_matrix.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, check]
|
||||
arch: [esp32, esp32s3, esp32c3, nrf52840, rp2040, stm32, check]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: checkout
|
||||
@@ -41,6 +41,7 @@ jobs:
|
||||
esp32c3: ${{ steps.jsonStep.outputs.esp32c3 }}
|
||||
nrf52840: ${{ steps.jsonStep.outputs.nrf52840 }}
|
||||
rp2040: ${{ steps.jsonStep.outputs.rp2040 }}
|
||||
stm32: ${{ steps.jsonStep.outputs.stm32 }}
|
||||
check: ${{ steps.jsonStep.outputs.check }}
|
||||
|
||||
check:
|
||||
@@ -50,6 +51,7 @@ jobs:
|
||||
matrix: ${{ fromJson(needs.setup.outputs.check) }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build base
|
||||
@@ -103,17 +105,27 @@ jobs:
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
build-stm32:
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.setup.outputs.stm32) }}
|
||||
uses: ./.github/workflows/build_stm32.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
package-raspbian:
|
||||
uses: ./.github/workflows/package_raspbian.yml
|
||||
|
||||
package-raspbian-armv7l:
|
||||
uses: ./.github/workflows/package_raspbian_armv7l.yml
|
||||
|
||||
package-native:
|
||||
uses: ./.github/workflows/package_amd64.yml
|
||||
# package-native:
|
||||
# uses: ./.github/workflows/package_amd64.yml
|
||||
|
||||
after-checks:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
needs: [check]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -127,16 +139,16 @@ jobs:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
[
|
||||
needs: [
|
||||
build-esp32,
|
||||
build-esp32-s3,
|
||||
build-esp32-c3,
|
||||
build-nrf52,
|
||||
build-rpi2040,
|
||||
build-stm32,
|
||||
package-raspbian,
|
||||
package-raspbian-armv7l,
|
||||
package-native,
|
||||
# package-native,
|
||||
]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -220,7 +232,7 @@ jobs:
|
||||
release-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
needs: [gather-artifacts, after-checks]
|
||||
needs: [gather-artifacts]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -240,12 +252,6 @@ jobs:
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
@@ -255,7 +261,7 @@ jobs:
|
||||
chmod +x ./output/device-update.sh
|
||||
|
||||
- name: Zip firmware
|
||||
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x *.deb
|
||||
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x meshtasticd_*
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -303,6 +309,12 @@ jobs:
|
||||
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
||||
merge-multiple: true
|
||||
path: ./output
|
||||
|
||||
- name: Add raspbian aarch64 .deb
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
@@ -323,22 +335,50 @@ jobs:
|
||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
|
||||
- name: Add raspbian amd64 .deb
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||
asset_content_type: application/vnd.debian.binary-package
|
||||
# - name: Add raspbian amd64 .deb
|
||||
# uses: actions/upload-release-asset@v1
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ github.token }}
|
||||
# with:
|
||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
# asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||
# asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||
# asset_content_type: application/vnd.debian.binary-package
|
||||
|
||||
- name: Bump version.properties
|
||||
run: >-
|
||||
bin/bump_version.py
|
||||
|
||||
- name: Create version.properties pull request
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
title: Bump version.properties
|
||||
add-paths: |
|
||||
version.properties
|
||||
|
||||
- name: Checkout meshtastic/meshtastic.github.io
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: meshtastic/meshtastic.github.io
|
||||
token: ${{ secrets.ARTIFACTS_TOKEN }}
|
||||
path: meshtastic.github.io
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Extract firmware.zip
|
||||
run: |
|
||||
unzip ./firmware-${{ steps.version.outputs.version }}.zip -d meshtastic.github.io/firmware-${{ steps.version.outputs.version }}
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
cd meshtastic.github.io
|
||||
find . -type f -name 'meshtasticd_*' -exec rm -f {} +
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add .
|
||||
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
|
||||
git push
|
||||
|
||||
2
.github/workflows/package_amd64.yml
vendored
2
.github/workflows/package_amd64.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: ./.github/workflows/build_native.yml
|
||||
|
||||
package-native:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
needs: build-native
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
2
.github/workflows/package_raspbian.yml
vendored
2
.github/workflows/package_raspbian.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: ./.github/workflows/build_raspbian.yml
|
||||
|
||||
package-raspbian:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
needs: build-raspbian
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: ./.github/workflows/build_raspbian_armv7l.yml
|
||||
|
||||
package-raspbian_armv7l:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
needs: build-raspbian_armv7l
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
2
.github/workflows/sec_sast_semgrep_cron.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
semgrep-full:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
image: semgrep/semgrep
|
||||
|
||||
steps:
|
||||
# step 1
|
||||
|
||||
4
.github/workflows/sec_sast_semgrep_pull.yml
vendored
4
.github/workflows/sec_sast_semgrep_pull.yml
vendored
@@ -4,9 +4,9 @@ on: pull_request
|
||||
|
||||
jobs:
|
||||
semgrep-diff:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
image: semgrep/semgrep
|
||||
|
||||
steps:
|
||||
# step 1
|
||||
|
||||
91
.github/workflows/tests.yml
vendored
Normal file
91
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
name: End to end tests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Run every day at midnight
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
test-simulator:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install libbluetooth
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Upgrade python tools
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
pip install -U meshtastic --pre
|
||||
|
||||
- name: Upgrade platformio
|
||||
shell: bash
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Build Native
|
||||
run: bin/build-native.sh
|
||||
|
||||
# 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 10 # 5 seconds was not enough
|
||||
echo "Simulator started, launching python test..."
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
|
||||
- name: PlatformIO Tests
|
||||
run: platformio test -e native --junit-output-path testreport.xml
|
||||
|
||||
- name: Test Report
|
||||
uses: dorny/test-reporter@v1.9.1
|
||||
if: success() || failure() # run this step even if previous step failed
|
||||
with:
|
||||
name: PlatformIO Tests
|
||||
path: testreport.xml
|
||||
reporter: java-junit
|
||||
|
||||
hardware-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Upgrade python tools
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U --no-build-isolation --no-cache-dir "setuptools<72"
|
||||
pip install -U platformio adafruit-nrfutil --no-build-isolation
|
||||
pip install -U poetry --no-build-isolation
|
||||
pip install -U meshtastic --pre --no-build-isolation
|
||||
|
||||
- name: Upgrade platformio
|
||||
shell: bash
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Setup devices
|
||||
run: pnpm run setup
|
||||
|
||||
- name: Execute end to end tests on connected hardware
|
||||
run: pnpm run test
|
||||
5
.github/workflows/update_protobufs.yml
vendored
5
.github/workflows/update_protobufs.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: "Update protobufs and regenerate classes"
|
||||
name: Update protobufs and regenerate classes
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
@@ -26,8 +26,9 @@ jobs:
|
||||
./bin/regen-protos.sh
|
||||
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
title: Update protobufs and classes
|
||||
add-paths: |
|
||||
protobufs
|
||||
src/mesh
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "protobufs"]
|
||||
path = protobufs
|
||||
url = https://github.com/meshtastic/protobufs.git
|
||||
[submodule "meshtestic"]
|
||||
path = meshtestic
|
||||
url = https://github.com/meshtastic/meshTestic
|
||||
|
||||
2
.gitpod.yml
Normal file
2
.gitpod.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
tasks:
|
||||
- init: pip install platformio && pip install --upgrade pip
|
||||
@@ -1,36 +1,36 @@
|
||||
version: 0.1
|
||||
cli:
|
||||
version: 1.22.2
|
||||
version: 1.22.3
|
||||
plugins:
|
||||
sources:
|
||||
- id: trunk
|
||||
ref: v1.5.0
|
||||
ref: v1.6.2
|
||||
uri: https://github.com/trunk-io/plugins
|
||||
lint:
|
||||
enabled:
|
||||
- trufflehog@3.76.3
|
||||
- trufflehog@3.81.9
|
||||
- yamllint@1.35.1
|
||||
- bandit@1.7.8
|
||||
- checkov@3.2.95
|
||||
- bandit@1.7.9
|
||||
- checkov@3.2.238
|
||||
- terrascan@1.19.1
|
||||
- trivy@0.51.1
|
||||
- trivy@0.54.1
|
||||
#- trufflehog@3.63.2-rc0
|
||||
- taplo@0.8.1
|
||||
- ruff@0.4.4
|
||||
- taplo@0.9.3
|
||||
- ruff@0.6.2
|
||||
- isort@5.13.2
|
||||
- markdownlint@0.40.0
|
||||
- oxipng@9.1.1
|
||||
- markdownlint@0.41.0
|
||||
- oxipng@9.1.2
|
||||
- svgo@3.3.2
|
||||
- actionlint@1.7.0
|
||||
- flake8@7.0.0
|
||||
- actionlint@1.7.1
|
||||
- flake8@7.1.1
|
||||
- hadolint@2.12.0
|
||||
- shfmt@3.6.0
|
||||
- shellcheck@0.10.0
|
||||
- black@24.4.2
|
||||
- black@24.8.0
|
||||
- git-diff-check
|
||||
- gitleaks@8.18.2
|
||||
- gitleaks@8.18.4
|
||||
- clang-format@16.0.3
|
||||
- prettier@3.2.5
|
||||
- prettier@3.3.3
|
||||
ignore:
|
||||
- linters: [ALL]
|
||||
paths:
|
||||
|
||||
7
.vscode/extensions.json
vendored
7
.vscode/extensions.json
vendored
@@ -2,8 +2,9 @@
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"ms-vscode.cpptools",
|
||||
"platformio.platformio-ide",
|
||||
"trunk.io"
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
|
||||
47
CONTRIBUTING.md
Normal file
47
CONTRIBUTING.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Contributing to Meshtastic Firmware
|
||||
|
||||
We're excited that you're interested in contributing to the Meshtastic firmware! This document provides a high-level overview of how you can get involved.
|
||||
|
||||
## Important First Steps
|
||||
|
||||
Before you begin, please:
|
||||
|
||||
1. **Read our documentation**: Our [official documentation](https://meshtastic.org/docs/) is a crucial resource. It contains essential information about the project.
|
||||
|
||||
2. **Check out the firmware build guide**: For specific instructions on setting up your development environment and building the firmware, refer to our [Firmware Build Guide](https://meshtastic.org/docs/development/firmware/build/).
|
||||
|
||||
3. Read our [Code of Conduct](https://meshtastic.org/docs/legal/conduct/)
|
||||
|
||||
4. Join our [Discord community](https://discord.com/invite/ktMAKGBnBs) to connect with developers and other contributors to get help.
|
||||
|
||||
## Getting Help and Discussing Ideas
|
||||
|
||||
We encourage open communication and discussion before diving into code changes:
|
||||
|
||||
1. **Use GitHub Discussions**: For new ideas, questions, or to discuss potential changes, start a conversation in our [GitHub Discussions](https://github.com/meshtastic/firmware/discussions) first. This helps us collaborate and avoid duplicate work.
|
||||
|
||||
2. **Join our Discord**: For real-time chat and quick questions, join our [Discord server](https://discord.com/invite/ktMAKGBnBs). It's a great place to get help and connect with other developers and the community.
|
||||
|
||||
3. **Reporting Issues**: If you've identified a bug, please use our bug report template when creating a new issue in the [issue tracker](https://github.com/meshtastic/firmware/issues). Ensure you've searched existing issues to avoid duplicates.
|
||||
|
||||
## Making Contributions
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Before making any contributions, you must sign our Contributor License Agreement (CLA). You can do this by visiting https://cla-assistant.io/meshtastic/firmware. Be sure to use the GitHub account you will use to submit your contributions when signing.
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a new branch for your feature or bug fix
|
||||
3. Make your changes
|
||||
4. Test your changes thoroughly
|
||||
5. Create a pull request with a clear description, using the provided template, of your changes. Be sure to enable "Allow edits from maintainers".
|
||||
|
||||
## Coding Standards
|
||||
|
||||
To ensure consistent code formatting across the project:
|
||||
|
||||
1. Install the [Trunk](https://marketplace.visualstudio.com/items?itemName=Trunk.io) extension for Visual Studio Code.
|
||||
2. Before submitting your changes, run `trunk fmt` to automatically format your code according to our standards.
|
||||
|
||||
Adhering to these formatting guidelines helps maintain code consistency and makes the review process smoother.
|
||||
|
||||
Thank you for contributing to Meshtastic!
|
||||
@@ -5,7 +5,7 @@ custom_esp32_kind = esp32
|
||||
platform = platformio/espressif32@6.7.0
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
|
||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||
|
||||
upload_speed = 921600
|
||||
debug_init_break = tbreak setup
|
||||
@@ -48,6 +48,7 @@ lib_deps =
|
||||
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||
rweather/Crypto@^0.4.0
|
||||
|
||||
lib_ignore =
|
||||
segger_rtt
|
||||
|
||||
208
arch/nrf52/cpp_overrides/lfs_util.h
Normal file
208
arch/nrf52/cpp_overrides/lfs_util.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* lfs utility functions
|
||||
*
|
||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// MESHTASTIC/@geeksville note: This file is copied from the Adafruit nrf52 arduino lib. And we use a special -include in
|
||||
// nrf52.ini to load it before EVERY file we do this hack because the default definitions for LFS_ASSERT are quite poor and we
|
||||
// don't want to fork the adafruit lib (again) and send in a PR that they probably won't merge anyways. This file might break if
|
||||
// they ever update lfs.util on their side, in which case we'll need to update this file to match their new version. The version
|
||||
// this is a copy from is almost exactly
|
||||
// https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/c25d93268a3b9c23e9a1ccfcaf9b208beca624ca/libraries/Adafruit_LittleFS/src/littlefs/lfs_util.h
|
||||
|
||||
#ifndef LFS_UTIL_H
|
||||
#define LFS_UTIL_H
|
||||
|
||||
// Users can override lfs_util.h with their own configuration by defining
|
||||
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
|
||||
//
|
||||
// If LFS_CONFIG is used, none of the default utils will be emitted and must be
|
||||
// provided by the config file. To start I would suggest copying lfs_util.h and
|
||||
// modifying as needed.
|
||||
#ifdef LFS_CONFIG
|
||||
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
|
||||
#define LFS_STRINGIZE2(x) #x
|
||||
#include LFS_STRINGIZE(LFS_CONFIG)
|
||||
#else
|
||||
|
||||
// System includes
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef LFS_NO_MALLOC
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifndef LFS_NO_ASSERT
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Macros, may be replaced by system specific wrappers. Arguments to these
|
||||
// macros must not have side-effects as the macros can be removed for a smaller
|
||||
// code footprint
|
||||
|
||||
// Logging functions
|
||||
#ifndef LFS_NO_DEBUG
|
||||
|
||||
void logLegacy(const char *level, const char *fmt, ...);
|
||||
#define LFS_DEBUG(fmt, ...) logLegacy("DEBUG", "lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LFS_DEBUG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#ifndef LFS_NO_WARN
|
||||
#define LFS_WARN(fmt, ...) logLegacy("WARN", "lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LFS_WARN(fmt, ...)
|
||||
#endif
|
||||
|
||||
#ifndef LFS_NO_ERROR
|
||||
#define LFS_ERROR(fmt, ...) logLegacy("ERROR", "lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
|
||||
#else
|
||||
#define LFS_ERROR(fmt, ...)
|
||||
#endif
|
||||
|
||||
// Runtime assertions
|
||||
#ifndef LFS_NO_ASSERT
|
||||
#define LFS_ASSERT(test) assert(test)
|
||||
#else
|
||||
extern void lfs_assert(const char *reason);
|
||||
#define LFS_ASSERT(test) \
|
||||
if (!(test)) \
|
||||
lfs_assert(#test)
|
||||
#endif
|
||||
|
||||
// Builtin functions, these may be replaced by more efficient
|
||||
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
||||
// expensive basic C implementation for debugging purposes
|
||||
|
||||
// Min/max functions for unsigned 32-bit numbers
|
||||
static inline uint32_t lfs_max(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
static inline uint32_t lfs_min(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
// Find the next smallest power of 2 less than or equal to a
|
||||
static inline uint32_t lfs_npw2(uint32_t a)
|
||||
{
|
||||
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||
return 32 - __builtin_clz(a - 1);
|
||||
#else
|
||||
uint32_t r = 0;
|
||||
uint32_t s;
|
||||
a -= 1;
|
||||
s = (a > 0xffff) << 4;
|
||||
a >>= s;
|
||||
r |= s;
|
||||
s = (a > 0xff) << 3;
|
||||
a >>= s;
|
||||
r |= s;
|
||||
s = (a > 0xf) << 2;
|
||||
a >>= s;
|
||||
r |= s;
|
||||
s = (a > 0x3) << 1;
|
||||
a >>= s;
|
||||
r |= s;
|
||||
return (r | (a >> 1)) + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Count the number of trailing binary zeros in a
|
||||
// lfs_ctz(0) may be undefined
|
||||
static inline uint32_t lfs_ctz(uint32_t a)
|
||||
{
|
||||
#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
|
||||
return __builtin_ctz(a);
|
||||
#else
|
||||
return lfs_npw2((a & -a) + 1) - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Count the number of binary ones in a
|
||||
static inline uint32_t lfs_popc(uint32_t a)
|
||||
{
|
||||
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||
return __builtin_popcount(a);
|
||||
#else
|
||||
a = a - ((a >> 1) & 0x55555555);
|
||||
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Find the sequence comparison of a and b, this is the distance
|
||||
// between a and b ignoring overflow
|
||||
static inline int lfs_scmp(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (int)(unsigned)(a - b);
|
||||
}
|
||||
|
||||
// Convert from 32-bit little-endian to native order
|
||||
static inline uint32_t lfs_fromle32(uint32_t a)
|
||||
{
|
||||
#if !defined(LFS_NO_INTRINSICS) && ((defined(BYTE_ORDER) && BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \
|
||||
(defined(__BYTE_ORDER) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||
return a;
|
||||
#elif !defined(LFS_NO_INTRINSICS) && \
|
||||
((defined(BYTE_ORDER) && BYTE_ORDER == ORDER_BIG_ENDIAN) || (defined(__BYTE_ORDER) && __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
return __builtin_bswap32(a);
|
||||
#else
|
||||
return (((uint8_t *)&a)[0] << 0) | (((uint8_t *)&a)[1] << 8) | (((uint8_t *)&a)[2] << 16) | (((uint8_t *)&a)[3] << 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Convert to 32-bit little-endian from native order
|
||||
static inline uint32_t lfs_tole32(uint32_t a)
|
||||
{
|
||||
return lfs_fromle32(a);
|
||||
}
|
||||
|
||||
// Calculate CRC-32 with polynomial = 0x04c11db7
|
||||
void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
|
||||
|
||||
// Allocate memory, only used if buffers are not provided to littlefs
|
||||
static inline void *lfs_malloc(size_t size)
|
||||
{
|
||||
#ifndef LFS_NO_MALLOC
|
||||
extern void *pvPortMalloc(size_t xWantedSize);
|
||||
return pvPortMalloc(size);
|
||||
#else
|
||||
(void)size;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Deallocate memory, only used if buffers are not provided to littlefs
|
||||
static inline void lfs_free(void *p)
|
||||
{
|
||||
#ifndef LFS_NO_MALLOC
|
||||
extern void vPortFree(void *pv);
|
||||
vPortFree(p);
|
||||
#else
|
||||
(void)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -2,9 +2,13 @@
|
||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||
platform = platformio/nordicnrf52@^10.5.0
|
||||
extends = arduino_base
|
||||
platform_packages =
|
||||
; our custom Git version until they merge our PR
|
||||
framework-arduinoadafruitnrf52 @ https://github.com/geeksville/Adafruit_nRF52_Arduino.git
|
||||
|
||||
build_type = debug
|
||||
build_flags =
|
||||
build_flags =
|
||||
-include arch/nrf52/cpp_overrides/lfs_util.h
|
||||
${arduino_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
-Wno-unused-variable
|
||||
@@ -12,10 +16,11 @@ build_flags =
|
||||
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/> -<mesh/raspihttp>
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||
|
||||
lib_deps=
|
||||
${arduino_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
@@ -7,3 +7,72 @@ lib_deps =
|
||||
${nrf52_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/Kongduino/Adafruit_nRFCrypto.git#e31a8825ea3300b163a0a3c1ddd5de34e10e1371
|
||||
|
||||
; Common NRF52 debugging settings follow. See the Meshtastic developer docs for how to connect SWD debugging probes to your board.
|
||||
|
||||
; We want the initial breakpoint at setup() instead of main(). Also we want to enable semihosting at that point so instead of
|
||||
debug_init_break = tbreak setup
|
||||
; we just turn off the platformio tbreak and do it in .gdbinit (where we have more flexibility for scripting)
|
||||
; also we use a permanent breakpoint so it gets reused each time we restart the debugging session?
|
||||
; debug_init_break = tbreak main
|
||||
|
||||
; Note: add "monitor arm semihosting_redirect tcp 4444 all" if you want the stdout from the device to go to that port number instead
|
||||
; (for use by meshtastic command line)
|
||||
; monitor arm semihosting disable
|
||||
; monitor debug_level 3
|
||||
;
|
||||
; IMPORTANT: fileio must be disabled before using port 5555 - openocd ver 0.12 has a bug where if enabled it never properly parses the special :tt name
|
||||
; for stdio access.
|
||||
; monitor arm semihosting_redirect tcp 5555 stdio
|
||||
|
||||
; Also note: it is _impossible_ to do non blocking reads on the semihost console port (an oversight when ARM specified the semihost API).
|
||||
; So we'll neve be able to general purpose bi-directional communication with the device over semihosting.
|
||||
debug_extra_cmds =
|
||||
echo Running .gdbinit script
|
||||
;monitor arm semihosting enable
|
||||
;monitor arm semihosting_fileio enable
|
||||
;monitor arm semihosting_redirect disable
|
||||
commands 1
|
||||
; echo Breakpoint at setup() has semihosting console, connect to it with "telnet localhost 5555"
|
||||
; set wantSemihost = 1
|
||||
set useSoftDevice = 0
|
||||
end
|
||||
|
||||
; Only reprogram the board if the code has changed
|
||||
debug_load_mode = modified
|
||||
;debug_load_mode = manual
|
||||
; We default to the stlink adapter because it is very cheap and works well, though others (such as jlink) are also supported.
|
||||
;debug_tool = jlink
|
||||
debug_tool = stlink
|
||||
debug_speed = 4000
|
||||
;debug_tool = custom
|
||||
; debug_server =
|
||||
; openocd
|
||||
; -f
|
||||
; /usr/local/share/openocd/scripts/interface/stlink.cfg
|
||||
; -f
|
||||
; /usr/local/share/openocd/scripts/target/nrf52.cfg
|
||||
; $PLATFORMIO_CORE_DIR/packages/tool-openocd/openocd/scripts/interface/cmsis-dap.cfg
|
||||
|
||||
; Allows programming and debug via the RAK NanoDAP as the default debugger tool for the RAK4631 (it is only $10!)
|
||||
; programming time is about the same as the bootloader version.
|
||||
; For information on this see the meshtastic developers documentation for "Development on the NRF52"
|
||||
; We manually pass in the elf file so that pyocd can reverse engineer FreeRTOS data (running threads, etc...)
|
||||
;debug_server =
|
||||
; pyocd
|
||||
; gdbserver
|
||||
; -j
|
||||
; ${platformio.workspace_dir}/..
|
||||
; -t
|
||||
; nrf52840
|
||||
; --semihosting
|
||||
; --elf
|
||||
; ${platformio.build_dir}/${this.__env__}/firmware.elf
|
||||
|
||||
; If you want to debug the semihosting support you can turn on extra logging in pyocd with
|
||||
; -L
|
||||
; pyocd.debug.semihost.trace=debug
|
||||
|
||||
; The following is not needed because it automatically tries do this
|
||||
;debug_server_ready_pattern = -.*GDB server started on port \d+.*
|
||||
;debug_port = localhost:3333
|
||||
@@ -1,6 +1,6 @@
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[portduino_base]
|
||||
platform = https://github.com/meshtastic/platform-native.git#ad8112adf82ce1f5b917092cf32be07a077801a0
|
||||
platform = https://github.com/meshtastic/platform-native.git#6b3796d697481c8f6e3f4aa5c111bd9979f29e64
|
||||
framework = arduino
|
||||
|
||||
build_src_filter =
|
||||
@@ -9,7 +9,7 @@ build_src_filter =
|
||||
-<nimble/>
|
||||
-<platform/nrf52/>
|
||||
-<platform/stm32wl/>
|
||||
-<platform/rp2040>
|
||||
-<platform/rp2xx0>
|
||||
-<mesh/wifi/>
|
||||
-<mesh/http/>
|
||||
+<mesh/raspihttp/>
|
||||
|
||||
@@ -8,7 +8,7 @@ board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/rp2040
|
||||
-Isrc/platform/rp2xx0
|
||||
-D__PLAT_RP2040__
|
||||
# -D _POSIX_THREADS
|
||||
build_src_filter =
|
||||
23
arch/rp2xx0/rp2350.ini
Normal file
23
arch/rp2xx0/rp2350.ini
Normal file
@@ -0,0 +1,23 @@
|
||||
; Common settings for rp2040 Processor based targets
|
||||
[rp2350_base]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9e55f6db5c56b9867c69fe473f388beea4546672
|
||||
extends = arduino_base
|
||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#a6ab6e1f95bc1428d667d55ea7173c0744acc03c ; 4.0.2+
|
||||
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
build_flags =
|
||||
${arduino_base.build_flags} -Wno-unused-variable
|
||||
-Isrc/platform/rp2xx0
|
||||
-D__PLAT_RP2040__
|
||||
# -D _POSIX_THREADS
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>
|
||||
|
||||
lib_ignore =
|
||||
BluetoothOTA
|
||||
|
||||
lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
rweather/Crypto
|
||||
37
arch/stm32/stm32.ini
Normal file
37
arch/stm32/stm32.ini
Normal file
@@ -0,0 +1,37 @@
|
||||
[stm32_base]
|
||||
extends = arduino_base
|
||||
platform = ststm32
|
||||
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#361a7fdb67e2a7104e99b4f42a802469eef8b129
|
||||
|
||||
build_type = release
|
||||
|
||||
;board_build.flash_offset = 0x08000000
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-flto
|
||||
-Isrc/platform/stm32wl -g
|
||||
-DMESHTASTIC_MINIMIZE_BUILD
|
||||
-DMESHTASTIC_EXCLUDE_GPS
|
||||
-DDEBUG_MUTE
|
||||
; -DVECT_TAB_OFFSET=0x08000000
|
||||
-DconfigUSE_CMSIS_RTOS_V2=1
|
||||
; -DSPI_MODE_0=SPI_MODE0
|
||||
-fmerge-all-constants
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/RemoteHardwareModule.cpp> -<platform/nrf52> -<platform/portduino> -<platform/rp2xx0> -<mesh/raspihttp>
|
||||
|
||||
board_upload.offset_address = 0x08000000
|
||||
upload_protocol = stlink
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
charlesbaynham/OSFS@^1.2.3
|
||||
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
|
||||
|
||||
lib_ignore =
|
||||
https://github.com/mathertel/OneButton@~2.6.1
|
||||
Wire
|
||||
@@ -1,28 +0,0 @@
|
||||
[stm32wl5e_base]
|
||||
platform_packages = platformio/framework-arduinoststm32 @ https://github.com/stm32duino/Arduino_Core_STM32.git#6e3f9910d0122e82a6c3438507dfac3d2fd80a39
|
||||
platform = ststm32
|
||||
board = generic_wl5e
|
||||
framework = arduino
|
||||
|
||||
build_type = debug
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-Isrc/platform/stm32wl -g
|
||||
-DconfigUSE_CMSIS_RTOS_V2=1
|
||||
-DVECT_TAB_OFFSET=0x08000000
|
||||
|
||||
build_src_filter =
|
||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040> -<mesh/raspihttp>
|
||||
|
||||
board_upload.offset_address = 0x08000000
|
||||
upload_protocol = stlink
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
|
||||
https://github.com/littlefs-project/littlefs.git#v2.5.1
|
||||
https://github.com/stm32duino/STM32FreeRTOS.git#10.3.1
|
||||
|
||||
lib_ignore =
|
||||
mathertel/OneButton
|
||||
Binary file not shown.
BIN
bin/Meshtastic_nRF52_factory_erase_v3_S140_6.1.0.uf2
Normal file
BIN
bin/Meshtastic_nRF52_factory_erase_v3_S140_6.1.0.uf2
Normal file
Binary file not shown.
BIN
bin/Meshtastic_nRF52_factory_erase_v3_S140_7.3.0.uf2
Normal file
BIN
bin/Meshtastic_nRF52_factory_erase_v3_S140_7.3.0.uf2
Normal file
Binary file not shown.
@@ -11,7 +11,7 @@ rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio pkg update
|
||||
platformio pkg update -e $1
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
@@ -11,7 +11,7 @@ rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio pkg update
|
||||
platformio pkg update -e $1
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
@@ -46,3 +46,8 @@ else
|
||||
cp bin/device-update.* $OUTDIR
|
||||
cp bin/*.uf2 $OUTDIR
|
||||
fi
|
||||
|
||||
if (echo $1 | grep -q "rak4631"); then
|
||||
echo "Copying hex file"
|
||||
cp .pio/build/$1/firmware.hex $OUTDIR/$basename.hex
|
||||
fi
|
||||
@@ -11,7 +11,7 @@ rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio pkg update
|
||||
platformio pkg update -e $1
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
29
bin/build-stm32.sh
Executable file
29
bin/build-stm32.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/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
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio pkg update -e $1
|
||||
|
||||
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
|
||||
|
||||
basename=firmware-$1-$VERSION
|
||||
|
||||
pio run --environment $1 # -v
|
||||
SRCELF=.pio/build/$1/firmware.elf
|
||||
cp $SRCELF $OUTDIR/$basename.elf
|
||||
|
||||
SRCBIN=.pio/build/$1/firmware.bin
|
||||
cp $SRCBIN $OUTDIR/$basename.bin
|
||||
@@ -54,6 +54,8 @@ Lora:
|
||||
|
||||
# ch341_quirk: true # Uncomment this to use the chunked SPI transfer that seems to fix the ch341
|
||||
|
||||
# spiSpeed: 2000000
|
||||
|
||||
### Set gpio chip to use in /dev/. Defaults to 0.
|
||||
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
||||
# gpiochip: 4
|
||||
@@ -111,6 +113,9 @@ Display:
|
||||
# Height: 320
|
||||
# Rotate: true
|
||||
|
||||
### You can also specify the spi device for the display to use
|
||||
# spidev: spidev0.0
|
||||
|
||||
Touchscreen:
|
||||
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
|
||||
|
||||
@@ -126,15 +131,21 @@ Touchscreen:
|
||||
# CS: 7
|
||||
# IRQ: 17
|
||||
|
||||
### Configure device for direct keyboard input
|
||||
### You can also specify the spi device for the touchscreen to use
|
||||
# spidev: spidev0.0
|
||||
|
||||
|
||||
Input:
|
||||
### Configure device for direct keyboard input
|
||||
|
||||
# KeyboardDevice: /dev/input/by-id/usb-_Raspberry_Pi_Internal_Keyboard-event-kbd
|
||||
|
||||
###
|
||||
|
||||
Logging:
|
||||
LogLevel: info # debug, info, warn, error
|
||||
# TraceFile: /var/log/meshtasticd.json
|
||||
# AsciiLogs: true # default if not specified is !isatty() on stdout
|
||||
|
||||
Webserver:
|
||||
# Port: 443 # Port for Webserver & Webservices
|
||||
@@ -142,3 +153,4 @@ Webserver:
|
||||
|
||||
General:
|
||||
MaxNodes: 200
|
||||
MaxMessageQueue: 100
|
||||
|
||||
11744
bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex
Normal file
11744
bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.zip
Normal file
BIN
bin/generic/Meshtastic_6.1.0_bootloader-0.9.2_s140_6.1.1.zip
Normal file
Binary file not shown.
11851
bin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.hex
Normal file
11851
bin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
bin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.zip
Normal file
BIN
bin/generic/Meshtastic_7.3.0_bootloader-0.9.2_s140_7.3.0.zip
Normal file
Binary file not shown.
BIN
bin/generic/update-Meshtastic_6.1.0_bootloader-0.9.2_nosd.uf2
Normal file
BIN
bin/generic/update-Meshtastic_6.1.0_bootloader-0.9.2_nosd.uf2
Normal file
Binary file not shown.
BIN
bin/generic/update-Meshtastic_7.3.0_bootloader-0.9.2_nosd.uf2
Normal file
BIN
bin/generic/update-Meshtastic_7.3.0_bootloader-0.9.2_nosd.uf2
Normal file
Binary file not shown.
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
# trunk-ignore-all(ruff/F821)
|
||||
# trunk-ignore-all(flake8/F821): For SConstruct imports
|
||||
import sys
|
||||
@@ -78,6 +79,11 @@ if platform.name == "espressif32":
|
||||
# For newer ESP32 targets, using newlib nano works better.
|
||||
env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"])
|
||||
|
||||
if platform.name == "nordicnrf52":
|
||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.hex",
|
||||
env.VerboseAction(f"{sys.executable} ./bin/uf2conv.py $BUILD_DIR/firmware.hex -c -f 0xADA52840 -o $BUILD_DIR/firmware.uf2",
|
||||
"Generating UF2 file"))
|
||||
|
||||
Import("projenv")
|
||||
|
||||
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
|
||||
|
||||
import subprocess
|
||||
import configparser
|
||||
import traceback
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
def readProps(prefsLoc):
|
||||
@@ -11,27 +7,36 @@ def readProps(prefsLoc):
|
||||
|
||||
config = configparser.RawConfigParser()
|
||||
config.read(prefsLoc)
|
||||
version = dict(config.items('VERSION'))
|
||||
verObj = dict(short = "{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
||||
long = "unset")
|
||||
version = dict(config.items("VERSION"))
|
||||
verObj = dict(
|
||||
short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
|
||||
long="unset",
|
||||
)
|
||||
|
||||
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
|
||||
try:
|
||||
sha = subprocess.check_output(
|
||||
['git', 'rev-parse', '--short', 'HEAD']).decode("utf-8").strip()
|
||||
isDirty = subprocess.check_output(
|
||||
['git', 'diff', 'HEAD']).decode("utf-8").strip()
|
||||
sha = (
|
||||
subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
isDirty = (
|
||||
subprocess.check_output(["git", "diff", "HEAD"]).decode("utf-8").strip()
|
||||
)
|
||||
suffix = sha
|
||||
# if isDirty:
|
||||
# # short for 'dirty', we want to keep our verstrings source for protobuf reasons
|
||||
# suffix = sha + "-d"
|
||||
verObj['long'] = "{}.{}.{}.{}".format(
|
||||
version["major"], version["minor"], version["build"], suffix)
|
||||
verObj["long"] = "{}.{}.{}.{}".format(
|
||||
version["major"], version["minor"], version["build"], suffix
|
||||
)
|
||||
except:
|
||||
# print("Unexpected error:", sys.exc_info()[0])
|
||||
# traceback.print_exc()
|
||||
verObj['long'] = verObj['short']
|
||||
verObj["long"] = verObj["short"]
|
||||
|
||||
# print("firmware version " + verStr)
|
||||
return verObj
|
||||
|
||||
|
||||
# print("path is" + ','.join(sys.path))
|
||||
|
||||
30
bin/wio_tracker_bootloader_update.bin
Normal file
30
bin/wio_tracker_bootloader_update.bin
Normal file
@@ -0,0 +1,30 @@
|
||||
# tips from mark on how to replace the (broken) bootloader on the red wio_tracker_1110 boards.
|
||||
|
||||
~/.platformio/penv/bin/adafruit-nrfutil --verbose dfu serial --package wio_tracker_1110_bootloader-0.9.1_s140_7.3.0.zip -p /dev/ttyACM1 -b 115200 --singlebank --touch 1200
|
||||
|
||||
exit
|
||||
|
||||
# Output should look like
|
||||
|
||||
Upgrading target on /dev/ttyACM1 with DFU package /home/kevinh/development/meshtastic/WioWM1110/wio_tracker_1110_bootloader-0.9.1_s140_7.3.0.zip. Flow control is disabled, Single bank, Touch 1200
|
||||
Touched serial port /dev/ttyACM1
|
||||
Opened serial port /dev/ttyACM1
|
||||
Starting DFU upgrade of type 3, SoftDevice size: 152728, bootloader size: 39000, application size: 0
|
||||
Sending DFU start packet
|
||||
Sending DFU init packet
|
||||
Sending firmware file
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
########################################
|
||||
###############
|
||||
Activating new firmware
|
||||
|
||||
DFU upgrade took 20.242434978485107s
|
||||
Device programmed.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"mcu": "esp32s3",
|
||||
"variant": "CDEBYTE_EoRa-S3"
|
||||
},
|
||||
"connectivity": ["wifi"],
|
||||
"connectivity": ["wifi", "bluetooth"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"mcu": "esp32s3",
|
||||
"variant": "ESP32-S3-WROOM-1-N4"
|
||||
},
|
||||
"connectivity": ["wifi"],
|
||||
"connectivity": ["wifi", "bluetooth"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
|
||||
"extra_flags": "-DHELTEC_T114 -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x4405"],
|
||||
|
||||
42
boards/heltec_vision_master_e290.json
Normal file
42
boards/heltec_vision_master_e290.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
["0x303A", "0x1001"],
|
||||
["0x303A", "0x0002"]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "heltec_vision_master_e290"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "Heltec Vision Master E290",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://heltec.org/project/vision-master-e290/",
|
||||
"vendor": "Heltec"
|
||||
}
|
||||
42
boards/heltec_vision_master_t190.json
Normal file
42
boards/heltec_vision_master_t190.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_8MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [
|
||||
["0x303A", "0x1001"],
|
||||
["0x303A", "0x0002"]
|
||||
],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "heltec_vision_master_t190"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "Heltec Vision Master t190",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://heltec.org/project/vision-master-t190/",
|
||||
"vendor": "Heltec"
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52832_s132_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DNRF52832_XXAA -DNRF52",
|
||||
"f_cpu": "64000000L",
|
||||
"mcu": "nrf52832",
|
||||
"variant": "lora_isp4520",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS132",
|
||||
"sd_name": "s132",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B7"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52832_xxAA",
|
||||
"svd_path": "nrf52.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "lora ISP4520",
|
||||
"upload": {
|
||||
"maximum_ram_size": 65536,
|
||||
"maximum_size": 524288,
|
||||
"require_upload_port": true,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
|
||||
},
|
||||
"url": "",
|
||||
"vendor": "PsiSoft"
|
||||
}
|
||||
58
boards/me25ls01-4y10td.json
Normal file
58
boards/me25ls01-4y10td.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v7.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DME25LS01_4Y10TD -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "ME25LS01-BOOT",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "MINEWSEMI_ME25LS01",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "7.3.0",
|
||||
"sd_fwid": "0x0123"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "Minesemi ME25LS01",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink",
|
||||
"cmsis-dap",
|
||||
"blackmagic"
|
||||
],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://en.minewsemi.com/lora-module/lr1110-nrf52840-me25LS01l",
|
||||
"vendor": "Minesemi"
|
||||
}
|
||||
58
boards/ms24sf1.json
Normal file
58
boards/ms24sf1.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v7.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DMS24SF1 -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "MS24SF1-BOOT",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "MINEWSEMI_MS24SF1_SX1262",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "7.3.0",
|
||||
"sd_fwid": "0x0123"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "MINEWSEMI_MS24SF1_SX1262",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink",
|
||||
"cmsis-dap",
|
||||
"blackmagic"
|
||||
],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://en.minewsemi.com/lora-module/nrf52840-sx1262-ms24sf1",
|
||||
"vendor": "Minesemi"
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"extra_flags": "-DNORDIC_PCA10059 -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
|
||||
42
boards/seeed-sensecap-indicator.json
Normal file
42
boards/seeed-sensecap-indicator.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld",
|
||||
"partitions": "default_8MB.csv",
|
||||
"memory_type": "qio_opi"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=0",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x1A86", "0x7523"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "esp32s3r8"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "Seeed Studio SenseCAP Indicator",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 8388608,
|
||||
"require_upload_port": true,
|
||||
"use_1200bps_touch": true,
|
||||
"wait_for_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://www.seeedstudio.com/Indicator-for-Meshtastic.html",
|
||||
"vendor": "Seeed Studio"
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"mcu": "esp32s3",
|
||||
"variant": "tlora-t3s3-v1"
|
||||
},
|
||||
"connectivity": ["wifi"],
|
||||
"connectivity": ["wifi", "bluetooth"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
|
||||
58
boards/tracker-t1000-e.json
Normal file
58
boards/tracker-t1000-e.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v7.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "T1000-E-BOOT",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "Seeed_T1000-E",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "7.3.0",
|
||||
"sd_fwid": "0x0123"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "Seeed T1000-E",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink",
|
||||
"cmsis-dap",
|
||||
"blackmagic"
|
||||
],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://www.seeedstudio.com/SenseCAP-Card-Tracker-T1000-E-for-Meshtastic-p-5913.html",
|
||||
"vendor": "Seeed Studio"
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"variant_h": "variant_RAK3172_MODULE.h"
|
||||
},
|
||||
"core": "stm32",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DSTM32WLxx -DSTM32WLE5xx -DARDUINO_GENERIC_WLE5CCUX",
|
||||
@@ -5,16 +5,24 @@ Import("env")
|
||||
|
||||
# NOTE: This is not currently used, but can serve as an example on how to write extra_scripts
|
||||
|
||||
print("Current CLI targets", COMMAND_LINE_TARGETS)
|
||||
print("Current Build targets", BUILD_TARGETS)
|
||||
print("CPP defs", env.get("CPPDEFINES"))
|
||||
# print("Current CLI targets", COMMAND_LINE_TARGETS)
|
||||
# print("Current Build targets", BUILD_TARGETS)
|
||||
# print("CPP defs", env.get("CPPDEFINES"))
|
||||
# print(env.Dump())
|
||||
|
||||
# Adafruit.py in the platformio build tree is a bit naive and always enables their USB stack for building. We don't want this.
|
||||
# So come in after that python script has run and disable it. This hack avoids us having to fork that big project and send in a PR
|
||||
# which might not be accepted. -@geeksville
|
||||
|
||||
env["CPPDEFINES"].remove("USBCON")
|
||||
env["CPPDEFINES"].remove("USE_TINYUSB")
|
||||
lib_builders = env.get("__PIO_LIB_BUILDERS", None)
|
||||
if lib_builders is not None:
|
||||
print("Disabling Adafruit USB stack")
|
||||
for k in lib_builders:
|
||||
if k.name == "Adafruit TinyUSB Library":
|
||||
libenv = k.env
|
||||
# print(f"{k.name }: { libenv.Dump() } ")
|
||||
# libenv["CPPDEFINES"].remove("USBCON")
|
||||
libenv["CPPDEFINES"].remove("USE_TINYUSB")
|
||||
|
||||
# Custom actions when building program/firmware
|
||||
# env.AddPreAction("buildprog", callback...)
|
||||
|
||||
1
meshtestic
Submodule
1
meshtestic
Submodule
Submodule meshtestic added at 37245b3d61
@@ -18,10 +18,7 @@ import subprocess
|
||||
import sys
|
||||
|
||||
from platformio.project.exception import PlatformioException
|
||||
from platformio.public import (
|
||||
DeviceMonitorFilterBase,
|
||||
load_build_metadata,
|
||||
)
|
||||
from platformio.public import DeviceMonitorFilterBase, load_build_metadata
|
||||
|
||||
# By design, __init__ is called inside miniterm and we can't pass context to it.
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
@@ -32,7 +29,7 @@ IS_WINDOWS = sys.platform.startswith("win")
|
||||
class Esp32C3ExceptionDecoder(DeviceMonitorFilterBase):
|
||||
NAME = "esp32_c3_exception_decoder"
|
||||
|
||||
PCADDR_PATTERN = re.compile(r'0x4[0-9a-f]{7}', re.IGNORECASE)
|
||||
PCADDR_PATTERN = re.compile(r"0x4[0-9a-f]{7}", re.IGNORECASE)
|
||||
|
||||
def __call__(self):
|
||||
self.buffer = ""
|
||||
@@ -75,14 +72,14 @@ See https://docs.platformio.org/page/projectconf/build_configurations.html
|
||||
% self.__class__.__name__
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
if not os.path.isfile(self.addr2line_path):
|
||||
sys.stderr.write(
|
||||
"%s: disabling, addr2line at %s does not exist\n"
|
||||
% (self.__class__.__name__, self.addr2line_path)
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
return True
|
||||
except PlatformioException as e:
|
||||
sys.stderr.write(
|
||||
@@ -117,7 +114,7 @@ See https://docs.platformio.org/page/projectconf/build_configurations.html
|
||||
|
||||
trace = self.get_backtrace(m)
|
||||
if len(trace) != "":
|
||||
text = text[: last] + trace + text[last :]
|
||||
text = text[:last] + trace + text[last:]
|
||||
last += len(trace)
|
||||
|
||||
return text
|
||||
@@ -125,14 +122,10 @@ See https://docs.platformio.org/page/projectconf/build_configurations.html
|
||||
def get_backtrace(self, match):
|
||||
trace = "\n"
|
||||
enc = "mbcs" if IS_WINDOWS else "utf-8"
|
||||
args = [self.addr2line_path, u"-fipC", u"-e", self.firmware_path]
|
||||
args = [self.addr2line_path, "-fipC", "-e", self.firmware_path]
|
||||
try:
|
||||
addr = match.group()
|
||||
output = (
|
||||
subprocess.check_output(args + [addr])
|
||||
.decode(enc)
|
||||
.strip()
|
||||
)
|
||||
output = subprocess.check_output(args + [addr]).decode(enc).strip()
|
||||
output = output.replace(
|
||||
"\n", "\n "
|
||||
) # newlines happen with inlined methods
|
||||
|
||||
@@ -34,6 +34,7 @@ default_envs = tbeam
|
||||
;default_envs = wio-e5
|
||||
;default_envs = radiomaster_900_bandit_nano
|
||||
;default_envs = radiomaster_900_bandit_micro
|
||||
;default_envs = radiomaster_900_bandit
|
||||
;default_envs = heltec_capsule_sensor_v3
|
||||
;default_envs = heltec_vision_master_t190
|
||||
;default_envs = heltec_vision_master_e213
|
||||
@@ -45,6 +46,7 @@ extra_configs =
|
||||
variants/*/platformio.ini
|
||||
|
||||
[env]
|
||||
test_build_src = true
|
||||
extra_scripts = bin/platformio-custom.py
|
||||
|
||||
; note: we add src to our include search path so that lmic_project_config can override
|
||||
@@ -79,14 +81,16 @@ build_flags = -Wno-missing-field-initializers
|
||||
-DRADIOLIB_EXCLUDE_APRS
|
||||
-DRADIOLIB_EXCLUDE_LORAWAN
|
||||
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
||||
-DBUILD_EPOCH=$UNIX_TIME
|
||||
;-D OLED_PL
|
||||
|
||||
monitor_speed = 115200
|
||||
monitor_filters = direct
|
||||
|
||||
lib_deps =
|
||||
jgromes/RadioLib@~6.6.0
|
||||
jgromes/RadioLib@~7.0.0
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
||||
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||
@@ -128,6 +132,7 @@ lib_deps =
|
||||
adafruit/Adafruit BMP280 Library@^2.6.8
|
||||
adafruit/Adafruit BMP085 Library@^1.2.4
|
||||
adafruit/Adafruit BME280 Library@^2.2.2
|
||||
adafruit/Adafruit BMP3XX Library@^2.1.5
|
||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||
adafruit/Adafruit INA260 Library@^1.5.0
|
||||
adafruit/Adafruit INA219@^1.2.0
|
||||
@@ -151,8 +156,9 @@ lib_deps =
|
||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
||||
boschsensortec/BME68x Sensor Library@^1.1.40407
|
||||
https://github.com/KodinLanewave/INA3221@^1.0.0
|
||||
lewisxhe/SensorLib@^0.2.0
|
||||
lewisxhe/SensorLib@0.2.0
|
||||
mprograms/QMC5883LCompass@^1.2.0
|
||||
|
||||
|
||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
|
||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
|
||||
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1
|
||||
|
||||
Submodule protobufs updated: 7f90178f18...9651aa59ea
@@ -11,6 +11,9 @@
|
||||
#include <Adafruit_LIS3DH.h>
|
||||
#include <Adafruit_LSM6DS3TRC.h>
|
||||
#include <Adafruit_MPU6050.h>
|
||||
#ifdef STK8XXX_INT
|
||||
#include <stk8baxx.h>
|
||||
#endif
|
||||
#include <Arduino.h>
|
||||
#include <SensorBMA423.hpp>
|
||||
#include <Wire.h>
|
||||
@@ -24,6 +27,8 @@
|
||||
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
|
||||
#define ACCELEROMETER_CLICK_THRESHOLD 40
|
||||
|
||||
volatile static bool STK_IRQ;
|
||||
|
||||
static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len)
|
||||
{
|
||||
Wire.beginTransmission(address);
|
||||
@@ -79,6 +84,11 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
|
||||
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
|
||||
wakeScreen();
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && STK_IRQ) {
|
||||
STK_IRQ = false;
|
||||
if (config.display.wake_on_tap_or_motion) {
|
||||
wakeScreen();
|
||||
}
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
|
||||
uint8_t click = lis.getClick();
|
||||
if (!config.device.double_tap_as_button_press) {
|
||||
@@ -188,6 +198,15 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
mpu.setMotionDetectionDuration(20);
|
||||
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
|
||||
mpu.setInterruptPinPolarity(true);
|
||||
#ifdef STK8XXX_INT
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::STK8BAXX && stk8baxx.STK8xxx_Initialization(STK8xxx_VAL_RANGE_2G)) {
|
||||
STK_IRQ = false;
|
||||
LOG_DEBUG("STX8BAxx initialized\n");
|
||||
stk8baxx.STK8xxx_Anymotion_init();
|
||||
pinMode(STK8XXX_INT, INPUT_PULLUP);
|
||||
attachInterrupt(
|
||||
digitalPinToInterrupt(STK8XXX_INT), [] { STK_IRQ = true; }, RISING);
|
||||
#endif
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
|
||||
LOG_DEBUG("LIS3DH initializing\n");
|
||||
lis.setRange(LIS3DH_RANGE_2_G);
|
||||
@@ -262,6 +281,9 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
ScanI2C::DeviceType acceleremoter_type;
|
||||
Adafruit_MPU6050 mpu;
|
||||
Adafruit_LIS3DH lis;
|
||||
#ifdef STK8XXX_INT
|
||||
STK8xxx stk8baxx;
|
||||
#endif
|
||||
Adafruit_LSM6DS3TRC lsm;
|
||||
SensorBMA423 bmaSensor;
|
||||
bool BMA_IRQ = false;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "Observer.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef HAS_NCP5623
|
||||
@@ -22,10 +23,18 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
public:
|
||||
explicit AmbientLightingThread(ScanI2C::DeviceType type) : OSThread("AmbientLightingThread")
|
||||
{
|
||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep); // Let us know when shutdown() is issued.
|
||||
|
||||
// Enables Ambient Lighting by default if conditions are meet.
|
||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||
#ifdef ENABLE_AMBIENTLIGHTING
|
||||
moduleConfig.ambient_lighting.led_state = true;
|
||||
#endif
|
||||
#endif
|
||||
// Uncomment to test module
|
||||
// moduleConfig.ambient_lighting.led_state = true;
|
||||
// moduleConfig.ambient_lighting.current = 10;
|
||||
// // Default to a color based on our node number
|
||||
// Default to a color based on our node number
|
||||
// moduleConfig.ambient_lighting.red = (myNodeInfo.my_node_num & 0xFF0000) >> 16;
|
||||
// moduleConfig.ambient_lighting.green = (myNodeInfo.my_node_num & 0x00FF00) >> 8;
|
||||
// moduleConfig.ambient_lighting.blue = myNodeInfo.my_node_num & 0x0000FF;
|
||||
@@ -82,9 +91,46 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
return disable();
|
||||
}
|
||||
|
||||
// When shutdown() is issued, setLightingOff will be called.
|
||||
CallbackObserver<AmbientLightingThread, void *> notifyDeepSleepObserver =
|
||||
CallbackObserver<AmbientLightingThread, void *>(this, &AmbientLightingThread::setLightingOff);
|
||||
|
||||
private:
|
||||
ScanI2C::DeviceType _type = ScanI2C::DeviceType::NONE;
|
||||
|
||||
// Turn RGB lighting off, is used in junction to shutdown()
|
||||
int setLightingOff(void *unused)
|
||||
{
|
||||
#ifdef HAS_NCP5623
|
||||
rgb.setCurrent(0);
|
||||
rgb.setRed(0);
|
||||
rgb.setGreen(0);
|
||||
rgb.setBlue(0);
|
||||
LOG_INFO("Turn Off NCP5623 Ambient lighting.\n");
|
||||
#endif
|
||||
#ifdef HAS_NEOPIXEL
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
LOG_INFO("Turn Off NeoPixel Ambient lighting.\n");
|
||||
#endif
|
||||
#ifdef RGBLED_CA
|
||||
analogWrite(RGBLED_RED, 255 - 0);
|
||||
analogWrite(RGBLED_GREEN, 255 - 0);
|
||||
analogWrite(RGBLED_BLUE, 255 - 0);
|
||||
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.\n");
|
||||
#elif defined(RGBLED_RED)
|
||||
analogWrite(RGBLED_RED, 0);
|
||||
analogWrite(RGBLED_GREEN, 0);
|
||||
analogWrite(RGBLED_BLUE, 0);
|
||||
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.\n");
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
unphone.rgb(0, 0, 0);
|
||||
LOG_INFO("Turn Off unPhone Ambient lighting.\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setLighting()
|
||||
{
|
||||
#ifdef HAS_NCP5623
|
||||
@@ -100,6 +146,17 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||
moduleConfig.ambient_lighting.blue),
|
||||
0, NEOPIXEL_COUNT);
|
||||
|
||||
// RadioMaster Bandit has addressable LED at the two buttons
|
||||
// this allow us to set different lighting for them in variant.h file.
|
||||
#ifdef RADIOMASTER_900_BANDIT
|
||||
#if defined(BUTTON1_COLOR) && defined(BUTTON1_COLOR_INDEX)
|
||||
pixels.fill(BUTTON1_COLOR, BUTTON1_COLOR_INDEX, 1);
|
||||
#endif
|
||||
#if defined(BUTTON2_COLOR) && defined(BUTTON2_COLOR_INDEX)
|
||||
pixels.fill(BUTTON2_COLOR, BUTTON1_COLOR_INDEX, 1);
|
||||
#endif
|
||||
#endif
|
||||
pixels.show();
|
||||
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
|
||||
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||
|
||||
@@ -29,7 +29,6 @@ volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BU
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
OneButton ButtonThread::userButton; // Get reference to static member
|
||||
#endif
|
||||
|
||||
ButtonThread::ButtonThread() : OSThread("Button")
|
||||
{
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
@@ -43,7 +42,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
|
||||
#if defined(HELTEC_CAPSULE_SENSOR_V3)
|
||||
this->userButton = OneButton(pin, false, false);
|
||||
#elif defined(BUTTON_ACTIVE_LOW) // change by WayenWeng
|
||||
#elif defined(BUTTON_ACTIVE_LOW)
|
||||
this->userButton = OneButton(pin, BUTTON_ACTIVE_LOW, BUTTON_ACTIVE_PULLUP);
|
||||
#else
|
||||
this->userButton = OneButton(pin, true, true);
|
||||
@@ -53,7 +52,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
|
||||
#ifdef INPUT_PULLUP_SENSE
|
||||
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
||||
#ifdef BUTTON_SENSE_TYPE // change by WayenWeng
|
||||
#ifdef BUTTON_SENSE_TYPE
|
||||
pinMode(pin, BUTTON_SENSE_TYPE);
|
||||
#else
|
||||
pinMode(pin, INPUT_PULLUP_SENSE);
|
||||
@@ -145,8 +144,8 @@ int32_t ButtonThread::runOnce()
|
||||
|
||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||
LOG_BUTTON("Double press!\n");
|
||||
service.refreshLocalMeshNode();
|
||||
auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
|
||||
service->refreshLocalMeshNode();
|
||||
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
||||
if (screen) {
|
||||
if (sentPosition)
|
||||
screen->print("Sent ad-hoc position\n");
|
||||
@@ -225,7 +224,6 @@ int32_t ButtonThread::runOnce()
|
||||
btnEvent = BUTTON_EVENT_NONE;
|
||||
}
|
||||
|
||||
runASAP = false;
|
||||
return 50;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef BUTTON_TOUCH_MS
|
||||
#define BUTTON_TOCH_MS 400
|
||||
#define BUTTON_TOUCH_MS 400
|
||||
#endif
|
||||
|
||||
class ButtonThread : public concurrency::OSThread
|
||||
|
||||
@@ -26,6 +26,20 @@ SOFTWARE.*/
|
||||
|
||||
#include "DebugConfiguration.h"
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
/// A C wrapper for LOG_DEBUG that can be used from arduino C libs that don't know about C++ or meshtastic
|
||||
extern "C" void logLegacy(const char *level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
if (console)
|
||||
console->vprintf(level, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#if HAS_NETWORKING
|
||||
|
||||
Syslog::Syslog(UDP &client)
|
||||
@@ -83,12 +97,14 @@ Syslog &Syslog::logMask(uint8_t priMask)
|
||||
|
||||
void Syslog::enable()
|
||||
{
|
||||
this->_client->begin(this->_port);
|
||||
this->_enabled = true;
|
||||
}
|
||||
|
||||
void Syslog::disable()
|
||||
{
|
||||
this->_enabled = false;
|
||||
this->_client->stop();
|
||||
}
|
||||
|
||||
bool Syslog::isEnabled()
|
||||
@@ -129,6 +145,11 @@ bool Syslog::vlogf(uint16_t pri, const char *appName, const char *fmt, va_list a
|
||||
inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *message)
|
||||
{
|
||||
int result;
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool utf = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool utf = true;
|
||||
#endif
|
||||
|
||||
if (!this->_enabled)
|
||||
return false;
|
||||
@@ -159,7 +180,12 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
|
||||
this->_client->print(this->_deviceHostname);
|
||||
this->_client->print(' ');
|
||||
this->_client->print(appName);
|
||||
this->_client->print(F(" - - - \xEF\xBB\xBF"));
|
||||
this->_client->print(F(" - - - "));
|
||||
if (utf) {
|
||||
this->_client->print(F("\xEF\xBB\xBF"));
|
||||
} else {
|
||||
this->_client->print(F(" "));
|
||||
}
|
||||
this->_client->print(F("["));
|
||||
this->_client->print(int(millis() / 1000));
|
||||
this->_client->print(F("]: "));
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "configuration.h"
|
||||
|
||||
// DEBUG LED
|
||||
#ifndef LED_INVERTED
|
||||
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
|
||||
#ifndef LED_STATE_ON
|
||||
#define LED_STATE_ON 1
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -45,7 +45,7 @@
|
||||
#define LOG_CRIT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||
#define LOG_TRACE(...) SEGGER_RTT_printf(0, __VA_ARGS__)
|
||||
#else
|
||||
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
|
||||
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) && !defined(PIO_UNIT_TESTING)
|
||||
#define LOG_DEBUG(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#define LOG_INFO(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_INFO, __VA_ARGS__)
|
||||
#define LOG_WARN(...) DEBUG_PORT.log(MESHTASTIC_LOG_LEVEL_WARN, __VA_ARGS__)
|
||||
@@ -62,6 +62,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// A C wrapper for LOG_DEBUG that can be used from arduino C libs that don't know about C++ or meshtastic
|
||||
extern "C" void logLegacy(const char *level, const char *fmt, ...);
|
||||
|
||||
#define SYSLOG_NILVALUE "-"
|
||||
|
||||
#define SYSLOG_CRIT 2 /* critical conditions */
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
|
||||
{
|
||||
switch (preset) {
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
|
||||
return useShortName ? "ShortT" : "ShortTurbo";
|
||||
break;
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
return useShortName ? "ShortS" : "ShortSlow";
|
||||
break;
|
||||
|
||||
163
src/FSCommon.cpp
163
src/FSCommon.cpp
@@ -24,6 +24,39 @@ SPIClass SPI1(HSPI);
|
||||
|
||||
#endif // HAS_SDCARD
|
||||
|
||||
#if defined(ARCH_STM32WL)
|
||||
|
||||
uint16_t OSFS::startOfEEPROM = 1;
|
||||
uint16_t OSFS::endOfEEPROM = 2048;
|
||||
|
||||
// 3) How do I read from the medium?
|
||||
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output)
|
||||
{
|
||||
for (uint16_t i = address; i < address + num; i++) {
|
||||
*output = EEPROM.read(i);
|
||||
output++;
|
||||
}
|
||||
}
|
||||
|
||||
// 4) How to I write to the medium?
|
||||
void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
|
||||
{
|
||||
for (uint16_t i = address; i < address + num; i++) {
|
||||
EEPROM.update(i, *input);
|
||||
input++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool lfs_assert_failed =
|
||||
false; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our modified lfs_util.h)
|
||||
|
||||
extern "C" void lfs_assert(const char *reason)
|
||||
{
|
||||
LOG_ERROR("LFS assert: %s\n", reason);
|
||||
lfs_assert_failed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copies a file from one location to another.
|
||||
*
|
||||
@@ -33,7 +66,33 @@ SPIClass SPI1(HSPI);
|
||||
*/
|
||||
bool copyFile(const char *from, const char *to)
|
||||
{
|
||||
#ifdef FSCom
|
||||
#ifdef ARCH_STM32WL
|
||||
unsigned char cbuffer[2048];
|
||||
|
||||
// Var to hold the result of actions
|
||||
OSFS::result r;
|
||||
|
||||
r = OSFS::getFile(from, cbuffer);
|
||||
|
||||
if (r == notfound) {
|
||||
LOG_ERROR("Failed to open source file %s\n", from);
|
||||
return false;
|
||||
} else if (r == noerr) {
|
||||
r = OSFS::newFile(to, cbuffer, true);
|
||||
if (r == noerr) {
|
||||
return true;
|
||||
} else {
|
||||
LOG_ERROR("OSFS Error %d\n", r);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
LOG_ERROR("OSFS Error %d\n", r);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
#elif defined(FSCom)
|
||||
unsigned char cbuffer[16];
|
||||
|
||||
File f1 = FSCom.open(from, FILE_O_READ);
|
||||
@@ -70,7 +129,13 @@ bool copyFile(const char *from, const char *to)
|
||||
*/
|
||||
bool renameFile(const char *pathFrom, const char *pathTo)
|
||||
{
|
||||
#ifdef FSCom
|
||||
#ifdef ARCH_STM32WL
|
||||
if (copyFile(pathFrom, pathTo) && (OSFS::deleteFile(pathFrom) == OSFS::result::NO_ERROR)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#elif defined(FSCom)
|
||||
#ifdef ARCH_ESP32
|
||||
// rename was fixed for ESP32 IDF LittleFS in April
|
||||
return FSCom.rename(pathFrom, pathTo);
|
||||
@@ -143,7 +208,7 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
|
||||
* @param levels The number of levels of subdirectories to list.
|
||||
* @param del Whether or not to delete the contents of the directory after listing.
|
||||
*/
|
||||
void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
void listDir(const char *dirname, uint8_t levels, bool del)
|
||||
{
|
||||
#ifdef FSCom
|
||||
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||
@@ -158,7 +223,9 @@ void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
}
|
||||
|
||||
File file = root.openNextFile();
|
||||
while (file) {
|
||||
while (
|
||||
file &&
|
||||
file.name()[0]) { // This file.name() check is a workaround for a bug in the Adafruit LittleFS nrf52 glue (see issue 4395)
|
||||
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
|
||||
if (levels) {
|
||||
#ifdef ARCH_ESP32
|
||||
@@ -182,6 +249,7 @@ void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
LOG_DEBUG(" %s (directory)\n", file.name());
|
||||
listDir(file.name(), levels - 1, del);
|
||||
file.close();
|
||||
#endif
|
||||
@@ -208,7 +276,7 @@ void listDir(const char *dirname, uint8_t levels, bool del = false)
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
|
||||
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
|
||||
file.close();
|
||||
#endif
|
||||
}
|
||||
@@ -257,62 +325,6 @@ void rmDir(const char *dirname)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fsCheck()
|
||||
{
|
||||
#if defined(ARCH_NRF52)
|
||||
size_t write_size = 0;
|
||||
size_t read_size = 0;
|
||||
char buf[32] = {0};
|
||||
|
||||
Adafruit_LittleFS_Namespace::File file(FSCom);
|
||||
const char *text = "meshtastic fs test";
|
||||
size_t text_length = strlen(text);
|
||||
const char *filename = "/meshtastic.txt";
|
||||
|
||||
LOG_DEBUG("Try create file .\n");
|
||||
if (file.open(filename, FILE_O_WRITE)) {
|
||||
write_size = file.write(text);
|
||||
} else {
|
||||
LOG_DEBUG("Open file failed .\n");
|
||||
goto FORMAT_FS;
|
||||
}
|
||||
|
||||
if (write_size != text_length) {
|
||||
LOG_DEBUG("Text bytes do not match .\n");
|
||||
file.close();
|
||||
goto FORMAT_FS;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
if (!file.open(filename, FILE_O_READ)) {
|
||||
LOG_DEBUG("Open file failed .\n");
|
||||
goto FORMAT_FS;
|
||||
}
|
||||
|
||||
read_size = file.readBytes(buf, text_length);
|
||||
if (read_size != text_length) {
|
||||
LOG_DEBUG("Text bytes do not match .\n");
|
||||
file.close();
|
||||
goto FORMAT_FS;
|
||||
}
|
||||
|
||||
if (memcmp(buf, text, text_length) != 0) {
|
||||
LOG_DEBUG("The written bytes do not match the read bytes .\n");
|
||||
file.close();
|
||||
goto FORMAT_FS;
|
||||
}
|
||||
return true;
|
||||
FORMAT_FS:
|
||||
LOG_DEBUG("Format FS ....\n");
|
||||
FSCom.format();
|
||||
FSCom.begin();
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fsInit()
|
||||
{
|
||||
#ifdef FSCom
|
||||
@@ -322,35 +334,6 @@ void fsInit()
|
||||
}
|
||||
#if defined(ARCH_ESP32)
|
||||
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
|
||||
#elif defined(ARCH_NRF52)
|
||||
/*
|
||||
* nRF52840 has a certain chance of automatic formatting failure.
|
||||
* Try to create a file after initializing the file system. If the creation fails,
|
||||
* it means that the file system is not working properly. Please format it manually again.
|
||||
* To check the normality of the file system, you need to disable the LFS_NO_ASSERT assertion.
|
||||
* Otherwise, the assertion will be entered at the moment of reading or opening, and the FS will not be formatted.
|
||||
* */
|
||||
bool ret = false;
|
||||
uint8_t retry = 3;
|
||||
|
||||
while (retry--) {
|
||||
ret = fsCheck();
|
||||
if (ret) {
|
||||
LOG_DEBUG("File system check is OK.\n");
|
||||
break;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
|
||||
// It may not be possible to reach this step.
|
||||
// Add a loop here to prevent unpredictable situations from happening.
|
||||
// Can add a screen to display error status later.
|
||||
if (!ret) {
|
||||
while (1) {
|
||||
LOG_ERROR("The file system is damaged and cannot proceed to the next step.\n");
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
LOG_DEBUG("Filesystem files:\n");
|
||||
#endif
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_STM32WL)
|
||||
#include "platform/stm32wl/InternalFileSystem.h" // STM32WL version
|
||||
#define FSCom InternalFS
|
||||
#define FSBegin() FSCom.begin()
|
||||
using namespace LittleFS_Namespace;
|
||||
// STM32WL series 2 Kbytes (8 rows of 256 bytes)
|
||||
#include <EEPROM.h>
|
||||
#include <OSFS.h>
|
||||
|
||||
// Useful consts
|
||||
const OSFS::result noerr = OSFS::result::NO_ERROR;
|
||||
const OSFS::result notfound = OSFS::result::FILE_NOT_FOUND;
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_RP2040)
|
||||
@@ -48,9 +51,13 @@ using namespace Adafruit_LittleFS_Namespace;
|
||||
#endif
|
||||
|
||||
void fsInit();
|
||||
void fsListFiles();
|
||||
bool copyFile(const char *from, const char *to);
|
||||
bool renameFile(const char *pathFrom, const char *pathTo);
|
||||
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
|
||||
void listDir(const char *dirname, uint8_t levels, bool del);
|
||||
void listDir(const char *dirname, uint8_t levels, bool del = false);
|
||||
void rmDir(const char *dirname);
|
||||
void setupSDCard();
|
||||
void setupSDCard();
|
||||
|
||||
extern bool lfs_assert_failed; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our
|
||||
// modified lfs_util.h)
|
||||
|
||||
104
src/GpioLogic.cpp
Normal file
104
src/GpioLogic.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "GpioLogic.h"
|
||||
#include <assert.h>
|
||||
|
||||
void GpioVirtPin::set(bool value)
|
||||
{
|
||||
if (value != this->value) {
|
||||
this->value = value ? PinState::On : PinState::Off;
|
||||
if (dependentPin)
|
||||
dependentPin->update();
|
||||
}
|
||||
}
|
||||
|
||||
void GpioHwPin::set(bool value)
|
||||
{
|
||||
// if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value);
|
||||
pinMode(num, OUTPUT);
|
||||
digitalWrite(num, value);
|
||||
}
|
||||
|
||||
GpioTransformer::GpioTransformer(GpioPin *outPin) : outPin(outPin) {}
|
||||
|
||||
void GpioTransformer::set(bool value)
|
||||
{
|
||||
outPin->set(value);
|
||||
}
|
||||
|
||||
GpioUnaryTransformer::GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioTransformer(outPin), inPin(inPin)
|
||||
{
|
||||
assert(!inPin->dependentPin); // We only allow one dependent pin
|
||||
inPin->dependentPin = this;
|
||||
|
||||
// Don't update at construction time, because various GpioPins might be global constructor based not yet initied because
|
||||
// order of operations for global constructors is not defined.
|
||||
// update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pin.
|
||||
*/
|
||||
void GpioUnaryTransformer::update()
|
||||
{
|
||||
auto p = inPin->get();
|
||||
if (p == GpioVirtPin::PinState::Unset)
|
||||
return; // Not yet fully initialized
|
||||
|
||||
set(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pin.
|
||||
*/
|
||||
void GpioNotTransformer::update()
|
||||
{
|
||||
auto p = inPin->get();
|
||||
if (p == GpioVirtPin::PinState::Unset)
|
||||
return; // Not yet fully initialized
|
||||
|
||||
set(!p);
|
||||
}
|
||||
|
||||
GpioBinaryTransformer::GpioBinaryTransformer(GpioVirtPin *inPin1, GpioVirtPin *inPin2, GpioPin *outPin, Operation operation)
|
||||
: GpioTransformer(outPin), inPin1(inPin1), inPin2(inPin2), operation(operation)
|
||||
{
|
||||
assert(!inPin1->dependentPin); // We only allow one dependent pin
|
||||
inPin1->dependentPin = this;
|
||||
assert(!inPin2->dependentPin); // We only allow one dependent pin
|
||||
inPin2->dependentPin = this;
|
||||
|
||||
// Don't update at construction time, because various GpioPins might be global constructor based not yet initied because
|
||||
// order of operations for global constructors is not defined.
|
||||
// update();
|
||||
}
|
||||
|
||||
void GpioBinaryTransformer::update()
|
||||
{
|
||||
auto p1 = inPin1->get(), p2 = inPin2->get();
|
||||
GpioVirtPin::PinState newValue = GpioVirtPin::PinState::Unset;
|
||||
|
||||
if (p1 == GpioVirtPin::PinState::Unset)
|
||||
newValue = p2; // Not yet fully initialized
|
||||
else if (p2 == GpioVirtPin::PinState::Unset)
|
||||
newValue = p1; // Not yet fully initialized
|
||||
|
||||
// If we've already found our value just use it, otherwise need to do the operation
|
||||
if (newValue == GpioVirtPin::PinState::Unset) {
|
||||
switch (operation) {
|
||||
case And:
|
||||
newValue = (GpioVirtPin::PinState)(p1 && p2);
|
||||
break;
|
||||
case Or:
|
||||
// LOG_DEBUG("Doing GPIO OR\n");
|
||||
newValue = (GpioVirtPin::PinState)(p1 || p2);
|
||||
break;
|
||||
case Xor:
|
||||
newValue = (GpioVirtPin::PinState)(p1 != p2);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
set(newValue);
|
||||
}
|
||||
|
||||
GpioSplitter::GpioSplitter(GpioPin *outPin1, GpioPin *outPin2) : outPin1(outPin1), outPin2(outPin2) {}
|
||||
160
src/GpioLogic.h
Normal file
160
src/GpioLogic.h
Normal file
@@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
/**This is a set of classes to mediate access to GPIOs in a structured way. Most usage of GPIOs do not
|
||||
require these classes! But if your hardware has a GPIO that is 'shared' between multiple devices (i.e. a shared power enable)
|
||||
then using these classes might be able to let you cleanly turn on that enable when either dependent device is needed.
|
||||
|
||||
Note: these classes are intended to be 99% inline for the common case so should have minimal impact on flash or RAM
|
||||
requirements.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A logical GPIO pin (not necessary raw hardware).
|
||||
*/
|
||||
class GpioPin
|
||||
{
|
||||
public:
|
||||
virtual void set(bool value) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A physical GPIO hw pin.
|
||||
*/
|
||||
class GpioHwPin : public GpioPin
|
||||
{
|
||||
uint32_t num;
|
||||
|
||||
public:
|
||||
explicit GpioHwPin(uint32_t num) : num(num) {}
|
||||
|
||||
void set(bool value);
|
||||
};
|
||||
|
||||
class GpioTransformer;
|
||||
class GpioNotTransformer;
|
||||
class GpioBinaryTransformer;
|
||||
|
||||
/**
|
||||
* A virtual GPIO pin.
|
||||
*/
|
||||
class GpioVirtPin : public GpioPin
|
||||
{
|
||||
friend class GpioBinaryTransformer;
|
||||
friend class GpioUnaryTransformer;
|
||||
|
||||
public:
|
||||
enum PinState { On = true, Off = false, Unset = 2 };
|
||||
|
||||
void set(bool value);
|
||||
PinState get() const { return value; }
|
||||
|
||||
private:
|
||||
PinState value = PinState::Unset;
|
||||
GpioTransformer *dependentPin = NULL;
|
||||
};
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* A 'smart' trigger that can depend in a fake GPIO and if that GPIO changes, drive some other downstream GPIO to change.
|
||||
* notably: the set method is not public (because it always is calculated by a subclass)
|
||||
*/
|
||||
class GpioTransformer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pin.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
protected:
|
||||
GpioTransformer(GpioPin *outPin);
|
||||
|
||||
void set(bool value);
|
||||
|
||||
private:
|
||||
GpioPin *outPin;
|
||||
};
|
||||
|
||||
/**
|
||||
* A transformer that just drives a hw pin based on a virtual pin.
|
||||
*/
|
||||
class GpioUnaryTransformer : public GpioTransformer
|
||||
{
|
||||
public:
|
||||
GpioUnaryTransformer(GpioVirtPin *inPin, GpioPin *outPin);
|
||||
|
||||
protected:
|
||||
friend class GpioVirtPin;
|
||||
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pin.
|
||||
*/
|
||||
virtual void update();
|
||||
|
||||
GpioVirtPin *inPin;
|
||||
};
|
||||
|
||||
/**
|
||||
* A transformer that performs a unary NOT operation from an input.
|
||||
*/
|
||||
class GpioNotTransformer : public GpioUnaryTransformer
|
||||
{
|
||||
public:
|
||||
GpioNotTransformer(GpioVirtPin *inPin, GpioPin *outPin) : GpioUnaryTransformer(inPin, outPin) {}
|
||||
|
||||
protected:
|
||||
friend class GpioVirtPin;
|
||||
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pin.
|
||||
*/
|
||||
void update();
|
||||
};
|
||||
|
||||
/**
|
||||
* A transformer that combines multiple virtual pins to drive an output pin
|
||||
*/
|
||||
class GpioBinaryTransformer : public GpioTransformer
|
||||
{
|
||||
|
||||
public:
|
||||
enum Operation { And, Or, Xor };
|
||||
|
||||
GpioBinaryTransformer(GpioVirtPin *inPin1, GpioVirtPin *inPin2, GpioPin *outPin, Operation operation);
|
||||
|
||||
protected:
|
||||
friend class GpioVirtPin;
|
||||
|
||||
/**
|
||||
* Update the output pin based on the current state of the input pins.
|
||||
*/
|
||||
void update();
|
||||
|
||||
private:
|
||||
GpioVirtPin *inPin1;
|
||||
GpioVirtPin *inPin2;
|
||||
Operation operation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sometimes a single output GPIO single needs to drive multiple physical GPIOs. This class provides that.
|
||||
*/
|
||||
class GpioSplitter : public GpioPin
|
||||
{
|
||||
|
||||
public:
|
||||
GpioSplitter(GpioPin *outPin1, GpioPin *outPin2);
|
||||
|
||||
void set(bool value)
|
||||
{
|
||||
outPin1->set(value);
|
||||
outPin2->set(value);
|
||||
}
|
||||
|
||||
private:
|
||||
GpioPin *outPin1;
|
||||
GpioPin *outPin2;
|
||||
};
|
||||
66
src/Led.cpp
Normal file
66
src/Led.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "Led.h"
|
||||
#include "PowerMon.h"
|
||||
#include "main.h"
|
||||
#include "power.h"
|
||||
|
||||
GpioVirtPin ledForceOn, ledBlink;
|
||||
|
||||
#if defined(LED_PIN)
|
||||
// Most boards have a GPIO for LED control
|
||||
static GpioHwPin ledRawHwPin(LED_PIN);
|
||||
#else
|
||||
static GpioVirtPin ledRawHwPin; // Dummy pin for no hardware
|
||||
#endif
|
||||
|
||||
#if LED_STATE_ON == 0
|
||||
static GpioVirtPin ledHwPin;
|
||||
static GpioNotTransformer ledInverter(&ledHwPin, &ledRawHwPin);
|
||||
#else
|
||||
static GpioPin &ledHwPin = ledRawHwPin;
|
||||
#endif
|
||||
|
||||
#if defined(HAS_PMU)
|
||||
/**
|
||||
* A GPIO controlled by the PMU
|
||||
*/
|
||||
class GpioPmuPin : public GpioPin
|
||||
{
|
||||
public:
|
||||
void set(bool value)
|
||||
{
|
||||
if (pmu_found && PMU) {
|
||||
// blink the axp led
|
||||
PMU->setChargingLedMode(value ? XPOWERS_CHG_LED_ON : XPOWERS_CHG_LED_OFF);
|
||||
}
|
||||
}
|
||||
} ledPmuHwPin;
|
||||
|
||||
// In some cases we need to drive a PMU LED and a normal LED
|
||||
static GpioSplitter ledFinalPin(&ledHwPin, &ledPmuHwPin);
|
||||
#else
|
||||
static GpioPin &ledFinalPin = ledHwPin;
|
||||
#endif
|
||||
|
||||
#ifdef USE_POWERMON
|
||||
/**
|
||||
* We monitor changes to the LED drive output because we use that as a sanity test in our power monitor stuff.
|
||||
*/
|
||||
class MonitoredLedPin : public GpioPin
|
||||
{
|
||||
public:
|
||||
void set(bool value)
|
||||
{
|
||||
if (powerMon) {
|
||||
if (value)
|
||||
powerMon->setState(meshtastic_PowerMon_State_LED_On);
|
||||
else
|
||||
powerMon->clearState(meshtastic_PowerMon_State_LED_On);
|
||||
}
|
||||
ledFinalPin.set(value);
|
||||
}
|
||||
} monitoredLedPin;
|
||||
#else
|
||||
static GpioPin &monitoredLedPin = ledFinalPin;
|
||||
#endif
|
||||
|
||||
static GpioBinaryTransformer ledForcer(&ledForceOn, &ledBlink, &monitoredLedPin, GpioBinaryTransformer::Or);
|
||||
7
src/Led.h
Normal file
7
src/Led.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "GpioLogic.h"
|
||||
#include "configuration.h"
|
||||
|
||||
/**
|
||||
* ledForceOn and ledForceOff both override the normal ledBlinker behavior (which is controlled by main)
|
||||
*/
|
||||
extern GpioVirtPin ledForceOn, ledBlink;
|
||||
@@ -1,60 +0,0 @@
|
||||
#include "OSTimer.h"
|
||||
#include "configuration.h"
|
||||
|
||||
/**
|
||||
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
|
||||
*
|
||||
* NOTE! xTimerPend... seems to ignore the time passed in on ESP32 and on NRF52
|
||||
* The reason this didn't work is because xTimerPednFunctCall really isn't a timer function at all - it just means run the
|
||||
callback
|
||||
* from the timer thread the next time you have spare cycles.
|
||||
*
|
||||
* @return true if successful, false if the timer fifo is too full.
|
||||
|
||||
bool scheduleOSCallback(PendableFunction callback, void *param1, uint32_t param2, uint32_t delayMsec)
|
||||
{
|
||||
return xTimerPendFunctionCall(callback, param1, param2, pdMS_TO_TICKS(delayMsec));
|
||||
} */
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
|
||||
// Super skanky quick hack to use hardware timers of the ESP32
|
||||
static hw_timer_t *timer;
|
||||
static PendableFunction tCallback;
|
||||
static void *tParam1;
|
||||
static uint32_t tParam2;
|
||||
|
||||
static void IRAM_ATTR onTimer()
|
||||
{
|
||||
(*tCallback)(tParam1, tParam2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a hardware callback function to be executed after a specified delay.
|
||||
*
|
||||
* @param callback The function to be executed.
|
||||
* @param param1 The first parameter to be passed to the function.
|
||||
* @param param2 The second parameter to be passed to the function.
|
||||
* @param delayMsec The delay time in milliseconds before the function is executed.
|
||||
*
|
||||
* @return True if the function was successfully scheduled, false otherwise.
|
||||
*/
|
||||
bool scheduleHWCallback(PendableFunction callback, void *param1, uint32_t param2, uint32_t delayMsec)
|
||||
{
|
||||
if (!timer) {
|
||||
timer = timerBegin(0, 80, true); // one usec per tick (main clock is 80MhZ on ESP32)
|
||||
assert(timer);
|
||||
timerAttachInterrupt(timer, &onTimer, true);
|
||||
}
|
||||
|
||||
tCallback = callback;
|
||||
tParam1 = param1;
|
||||
tParam2 = param2;
|
||||
|
||||
timerAlarmWrite(timer, delayMsec * 1000UL, false); // Do not reload, we want it to be a single shot timer
|
||||
timerRestart(timer);
|
||||
timerAlarmEnable(timer);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef void (*PendableFunction)(void *pvParameter1, uint32_t ulParameter2);
|
||||
|
||||
/// Uses a hardware timer, but calls the handler in _interrupt_ context
|
||||
bool scheduleHWCallback(PendableFunction callback, void *param1, uint32_t param2, uint32_t delayMsec);
|
||||
230
src/Power.cpp
230
src/Power.cpp
@@ -13,6 +13,7 @@
|
||||
#include "power.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "Throttle.h"
|
||||
#include "buzz/buzz.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#if HAS_WIFI
|
||||
#include <WiFi.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DELAY_FOREVER
|
||||
@@ -80,9 +82,6 @@ RAK9154Sensor rak9154Sensor;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_PMU
|
||||
#include "XPowersAXP192.tpp"
|
||||
#include "XPowersAXP2101.tpp"
|
||||
#include "XPowersLibInterface.hpp"
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
#else
|
||||
|
||||
@@ -139,6 +138,30 @@ using namespace meshtastic;
|
||||
*/
|
||||
static HasBatteryLevel *batteryLevel; // Default to NULL for no battery level sensor
|
||||
|
||||
static void adcEnable()
|
||||
{
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
pinMode(ADC_CTRL, INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
delay(10);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void adcDisable()
|
||||
{
|
||||
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
|
||||
#ifdef ADC_USE_PULLUP
|
||||
pinMode(ADC_CTRL, INPUT_PULLDOWN);
|
||||
#else
|
||||
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
|
||||
*/
|
||||
@@ -200,7 +223,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
|
||||
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (hasINA()) {
|
||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
||||
return getINAVoltage();
|
||||
@@ -222,31 +246,25 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
|
||||
// Do not call analogRead() often.
|
||||
const uint32_t min_read_interval = 5000;
|
||||
if (millis() - last_read_time_ms > min_read_interval) {
|
||||
if (!Throttle::isWithinTimespanMs(last_read_time_ms, min_read_interval)) {
|
||||
last_read_time_ms = millis();
|
||||
|
||||
uint32_t raw = 0;
|
||||
float scaled = 0;
|
||||
|
||||
adcEnable();
|
||||
#ifdef ARCH_ESP32 // ADC block for espressif platforms
|
||||
raw = espAdcRead();
|
||||
scaled = esp_adc_cal_raw_to_voltage(raw, adc_characs);
|
||||
scaled *= operativeAdcMultiplier;
|
||||
#else // block for all other platforms
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
|
||||
delay(10);
|
||||
#endif
|
||||
#else // block for all other platforms
|
||||
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
raw += analogRead(BATTERY_PIN);
|
||||
}
|
||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
||||
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
|
||||
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
#endif
|
||||
adcDisable();
|
||||
|
||||
if (!initial_read_done) {
|
||||
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
|
||||
@@ -277,11 +295,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
uint8_t raw_c = 0; // raw reading counter
|
||||
|
||||
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
||||
#ifdef ADC_CTRL // enable adc voltage divider when we need to read
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, ADC_CTRL_ENABLED);
|
||||
delay(10);
|
||||
#endif
|
||||
for (int i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
int val_ = adc1_get_raw(adc_channel);
|
||||
if (val_ >= 0) { // save only valid readings
|
||||
@@ -290,18 +303,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
// delayMicroseconds(100);
|
||||
}
|
||||
#ifdef ADC_CTRL // disable adc voltage divider when we need to read
|
||||
digitalWrite(ADC_CTRL, !ADC_CTRL_ENABLED);
|
||||
#endif
|
||||
#else // ADC2
|
||||
#ifdef ADC_CTRL
|
||||
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
|
||||
pinMode(ADC_CTRL, OUTPUT);
|
||||
digitalWrite(ADC_CTRL, LOW); // ACTIVE LOW
|
||||
delay(10);
|
||||
#endif
|
||||
#endif // End ADC_CTRL
|
||||
|
||||
#else // ADC2
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S3 // ESP32S3
|
||||
// ADC2 wifi bug workaround not required, breaks compile
|
||||
// On ESP32S3, ADC2 can take turns with Wifi (?)
|
||||
@@ -336,12 +338,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
#endif // BAT_MEASURE_ADC_UNIT
|
||||
|
||||
#ifdef ADC_CTRL
|
||||
#if defined(HELTEC_WIRELESS_PAPER) || defined(HELTEC_WIRELESS_PAPER_V1_0)
|
||||
digitalWrite(ADC_CTRL, HIGH);
|
||||
#endif
|
||||
#endif // End ADC_CTRL
|
||||
|
||||
#endif // End BAT_MEASURE_ADC_UNIT
|
||||
return (raw / (raw_c < 1 ? 1 : raw_c));
|
||||
}
|
||||
@@ -420,7 +416,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
uint16_t getINAVoltage()
|
||||
{
|
||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||
@@ -460,7 +456,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
#endif
|
||||
};
|
||||
|
||||
AnalogBatteryLevel analogLevel;
|
||||
static AnalogBatteryLevel analogLevel;
|
||||
|
||||
Power::Power() : OSThread("Power")
|
||||
{
|
||||
@@ -559,6 +555,10 @@ bool Power::setup()
|
||||
{
|
||||
bool found = axpChipInit() || analogInit();
|
||||
|
||||
#ifdef NRF_APM
|
||||
found = true;
|
||||
#endif
|
||||
|
||||
enabled = found;
|
||||
low_voltage_counter = 0;
|
||||
|
||||
@@ -588,10 +588,16 @@ void Power::shutdown()
|
||||
// TODO(girts): move this and other axp stuff to power.h/power.cpp.
|
||||
void Power::readPowerStatus()
|
||||
{
|
||||
int32_t batteryVoltageMv = -1; // Assume unknown
|
||||
int8_t batteryChargePercent = -1;
|
||||
OptionalBool usbPowered = OptUnknown;
|
||||
OptionalBool hasBattery = OptUnknown; // These must be static because NRF_APM code doesn't run every time
|
||||
OptionalBool isCharging = OptUnknown;
|
||||
|
||||
if (batteryLevel) {
|
||||
bool hasBattery = batteryLevel->isBatteryConnect();
|
||||
uint32_t batteryVoltageMv = 0;
|
||||
int8_t batteryChargePercent = 0;
|
||||
hasBattery = batteryLevel->isBatteryConnect() ? OptTrue : OptFalse;
|
||||
usbPowered = batteryLevel->isVbusIn() ? OptTrue : OptFalse;
|
||||
isCharging = batteryLevel->isCharging() ? OptTrue : OptFalse;
|
||||
if (hasBattery) {
|
||||
batteryVoltageMv = batteryLevel->getBattVoltage();
|
||||
// If the AXP192 returns a valid battery percentage, use it
|
||||
@@ -606,102 +612,90 @@ void Power::readPowerStatus()
|
||||
0, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OptionalBool NRF_USB = OptFalse;
|
||||
|
||||
// FIXME: IMO we shouldn't be littering our code with all these ifdefs. Way better instead to make a Nrf52IsUsbPowered subclass
|
||||
// (which shares a superclass with the BatteryLevel stuff)
|
||||
// that just provides a few methods. But in the interest of fixing this bug I'm going to follow current
|
||||
// practice.
|
||||
#ifdef NRF_APM // Section of code detects USB power on the RAK4631 and updates the power states. Takes 20 seconds or so to detect
|
||||
// changes.
|
||||
|
||||
static nrfx_power_usb_state_t prev_nrf_usb_state = (nrfx_power_usb_state_t)-1; // -1 so that state detected at boot
|
||||
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
||||
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
||||
// LOG_DEBUG("NRF Power %d\n", nrf_usb_state);
|
||||
|
||||
// If state changed
|
||||
if (nrf_usb_state != prev_nrf_usb_state) {
|
||||
// If changed to DISCONNECTED
|
||||
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED) {
|
||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||
NRF_USB = OptFalse;
|
||||
}
|
||||
// If changed to CONNECTED / READY
|
||||
else {
|
||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||
NRF_USB = OptTrue;
|
||||
}
|
||||
// If changed to DISCONNECTED
|
||||
if (nrf_usb_state == NRFX_POWER_USB_STATE_DISCONNECTED)
|
||||
isCharging = usbPowered = OptFalse;
|
||||
// If changed to CONNECTED / READY
|
||||
else
|
||||
isCharging = usbPowered = OptTrue;
|
||||
|
||||
// Cache the current state
|
||||
prev_nrf_usb_state = nrf_usb_state;
|
||||
}
|
||||
#endif
|
||||
// Notify any status instances that are observing us
|
||||
const PowerStatus powerStatus2 = PowerStatus(
|
||||
hasBattery ? OptTrue : OptFalse, batteryLevel->isVbusIn() || NRF_USB == OptTrue ? OptTrue : OptFalse,
|
||||
batteryLevel->isCharging() || NRF_USB == OptTrue ? OptTrue : OptFalse, batteryVoltageMv, batteryChargePercent);
|
||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
|
||||
// Notify any status instances that are observing us
|
||||
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isCharging, batteryVoltageMv, batteryChargePercent);
|
||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
|
||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
#ifdef DEBUG_HEAP
|
||||
if (lastheap != memGet.getFreeHeap()) {
|
||||
LOG_DEBUG("Threads running:");
|
||||
int running = 0;
|
||||
for (int i = 0; i < MAX_THREADS; i++) {
|
||||
auto thread = concurrency::mainController.get(i);
|
||||
if ((thread != nullptr) && (thread->enabled)) {
|
||||
LOG_DEBUG(" %s", thread->ThreadName.c_str());
|
||||
running++;
|
||||
}
|
||||
if (lastheap != memGet.getFreeHeap()) {
|
||||
LOG_DEBUG("Threads running:");
|
||||
int running = 0;
|
||||
for (int i = 0; i < MAX_THREADS; i++) {
|
||||
auto thread = concurrency::mainController.get(i);
|
||||
if ((thread != nullptr) && (thread->enabled)) {
|
||||
LOG_DEBUG(" %s", thread->ThreadName.c_str());
|
||||
running++;
|
||||
}
|
||||
LOG_DEBUG("\n");
|
||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
|
||||
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||
lastheap = memGet.getFreeHeap();
|
||||
}
|
||||
LOG_DEBUG("\n");
|
||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
|
||||
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||
lastheap = memGet.getFreeHeap();
|
||||
}
|
||||
#ifdef DEBUG_HEAP_MQTT
|
||||
if (mqtt) {
|
||||
// send MQTT-Packet with Heap-Size
|
||||
uint8_t dmac[6];
|
||||
getMacAddr(dmac); // Get our hardware ID
|
||||
char mac[18];
|
||||
sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]);
|
||||
if (mqtt) {
|
||||
// send MQTT-Packet with Heap-Size
|
||||
uint8_t dmac[6];
|
||||
getMacAddr(dmac); // Get our hardware ID
|
||||
char mac[18];
|
||||
sprintf(mac, "!%02x%02x%02x%02x", dmac[2], dmac[3], dmac[4], dmac[5]);
|
||||
|
||||
auto newHeap = memGet.getFreeHeap();
|
||||
std::string heapTopic =
|
||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac);
|
||||
std::string heapString = std::to_string(newHeap);
|
||||
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false);
|
||||
auto wifiRSSI = WiFi.RSSI();
|
||||
std::string wifiTopic =
|
||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac);
|
||||
std::string wifiString = std::to_string(wifiRSSI);
|
||||
mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false);
|
||||
}
|
||||
auto newHeap = memGet.getFreeHeap();
|
||||
std::string heapTopic =
|
||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/heap/") + std::string(mac);
|
||||
std::string heapString = std::to_string(newHeap);
|
||||
mqtt->pubSub.publish(heapTopic.c_str(), heapString.c_str(), false);
|
||||
auto wifiRSSI = WiFi.RSSI();
|
||||
std::string wifiTopic =
|
||||
(*moduleConfig.mqtt.root ? moduleConfig.mqtt.root : "msh") + std::string("/2/wifi/") + std::string(mac);
|
||||
std::string wifiString = std::to_string(wifiRSSI);
|
||||
mqtt->pubSub.publish(wifiTopic.c_str(), wifiString.c_str(), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in
|
||||
// a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough.
|
||||
//
|
||||
if (powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
||||
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
|
||||
low_voltage_counter++;
|
||||
LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
|
||||
if (low_voltage_counter > 10) {
|
||||
// If we have a battery at all and it is less than 0%, force deep sleep if we have more than 10 low readings in
|
||||
// a row. NOTE: min LiIon/LiPo voltage is 2.0 to 2.5V, current OCV min is set to 3100 that is large enough.
|
||||
//
|
||||
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
||||
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
|
||||
low_voltage_counter++;
|
||||
LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
|
||||
if (low_voltage_counter > 10) {
|
||||
#ifdef ARCH_NRF52
|
||||
// We can't trigger deep sleep on NRF52, it's freezing the board
|
||||
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
|
||||
// We can't trigger deep sleep on NRF52, it's freezing the board
|
||||
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
|
||||
#else
|
||||
LOG_INFO("Low voltage detected, triggering deep sleep\n");
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
LOG_INFO("Low voltage detected, triggering deep sleep\n");
|
||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
}
|
||||
} else {
|
||||
// No power sensing on this board - tell everyone else we have no idea what is happening
|
||||
const PowerStatus powerStatus3 = PowerStatus(OptUnknown, OptUnknown, OptUnknown, -1, -1);
|
||||
newStatus.notifyObservers(&powerStatus3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1050,4 +1044,4 @@ bool Power::axpChipInit()
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include "PowerFSM.h"
|
||||
#include "Default.h"
|
||||
#include "Led.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerMon.h"
|
||||
@@ -21,12 +22,15 @@
|
||||
#ifndef SLEEP_TIME
|
||||
#define SLEEP_TIME 30
|
||||
#endif
|
||||
|
||||
#if EXCLUDE_POWER_FSM
|
||||
FakeFsm powerFSM;
|
||||
void PowerFSM_setup(){};
|
||||
#else
|
||||
/// Should we behave as if we have AC power now?
|
||||
static bool isPowered()
|
||||
{
|
||||
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
|
||||
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101)
|
||||
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101) && !defined(NRF_APM)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
@@ -50,7 +54,6 @@ static bool isPowered()
|
||||
static void sdsEnter()
|
||||
{
|
||||
LOG_DEBUG("Enter state: SDS\n");
|
||||
powerMon->setState(meshtastic_PowerMon_State_CPU_DeepSleep);
|
||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false);
|
||||
}
|
||||
@@ -70,7 +73,6 @@ static uint32_t secsSlept;
|
||||
static void lsEnter()
|
||||
{
|
||||
LOG_INFO("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
|
||||
powerMon->clearState(meshtastic_PowerMon_State_Screen_On);
|
||||
screen->setOn(false);
|
||||
secsSlept = 0; // How long have we been sleeping this time
|
||||
|
||||
@@ -91,7 +93,7 @@ static void lsIdle()
|
||||
uint32_t sleepTime = SLEEP_TIME;
|
||||
|
||||
powerMon->setState(meshtastic_PowerMon_State_CPU_LightSleep);
|
||||
setLed(false); // Never leave led on while in light sleep
|
||||
ledBlink.set(false); // Never leave led on while in light sleep
|
||||
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
|
||||
powerMon->clearState(meshtastic_PowerMon_State_CPU_LightSleep);
|
||||
|
||||
@@ -99,7 +101,7 @@ static void lsIdle()
|
||||
case ESP_SLEEP_WAKEUP_TIMER:
|
||||
// Normal case: timer expired, we should just go back to sleep ASAP
|
||||
|
||||
setLed(true); // briefly turn on led
|
||||
ledBlink.set(true); // briefly turn on led
|
||||
wakeCause2 = doLightSleep(100); // leave led on for 1ms
|
||||
|
||||
secsSlept += sleepTime;
|
||||
@@ -134,7 +136,7 @@ static void lsIdle()
|
||||
}
|
||||
} else {
|
||||
// Time to stop sleeping!
|
||||
setLed(false);
|
||||
ledBlink.set(false);
|
||||
LOG_INFO("Reached ls_secs, servicing loop()\n");
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
}
|
||||
@@ -149,7 +151,6 @@ static void lsExit()
|
||||
static void nbEnter()
|
||||
{
|
||||
LOG_DEBUG("Enter state: NB\n");
|
||||
powerMon->clearState(meshtastic_PowerMon_State_BT_On);
|
||||
screen->setOn(false);
|
||||
#ifdef ARCH_ESP32
|
||||
// Only ESP32 should turn off bluetooth
|
||||
@@ -161,8 +162,6 @@ static void nbEnter()
|
||||
|
||||
static void darkEnter()
|
||||
{
|
||||
powerMon->clearState(meshtastic_PowerMon_State_BT_On);
|
||||
powerMon->clearState(meshtastic_PowerMon_State_Screen_On);
|
||||
setBluetoothEnable(true);
|
||||
screen->setOn(false);
|
||||
}
|
||||
@@ -170,8 +169,6 @@ static void darkEnter()
|
||||
static void serialEnter()
|
||||
{
|
||||
LOG_DEBUG("Enter state: SERIAL\n");
|
||||
powerMon->clearState(meshtastic_PowerMon_State_BT_On);
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
setBluetoothEnable(false);
|
||||
screen->setOn(true);
|
||||
screen->print("Serial connected\n");
|
||||
@@ -180,7 +177,6 @@ static void serialEnter()
|
||||
static void serialExit()
|
||||
{
|
||||
// Turn bluetooth back on when we leave serial stream API
|
||||
powerMon->setState(meshtastic_PowerMon_State_BT_On);
|
||||
setBluetoothEnable(true);
|
||||
screen->print("Serial disconnected\n");
|
||||
}
|
||||
@@ -193,8 +189,6 @@ static void powerEnter()
|
||||
LOG_INFO("Loss of power in Powered\n");
|
||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||
} else {
|
||||
powerMon->setState(meshtastic_PowerMon_State_BT_On);
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
// within enter() the function getState() returns the state we came from
|
||||
@@ -218,8 +212,6 @@ static void powerIdle()
|
||||
|
||||
static void powerExit()
|
||||
{
|
||||
powerMon->setState(meshtastic_PowerMon_State_BT_On);
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
|
||||
@@ -231,8 +223,6 @@ static void powerExit()
|
||||
static void onEnter()
|
||||
{
|
||||
LOG_DEBUG("Enter state: ON\n");
|
||||
powerMon->setState(meshtastic_PowerMon_State_BT_On);
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
}
|
||||
@@ -408,4 +398,5 @@ void PowerFSM_setup()
|
||||
#endif
|
||||
|
||||
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Fsm.h>
|
||||
#include "configuration.h"
|
||||
|
||||
// See sw-design.md for documentation
|
||||
|
||||
@@ -22,7 +22,30 @@
|
||||
#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
|
||||
|
||||
#if EXCLUDE_POWER_FSM
|
||||
class FakeFsm
|
||||
{
|
||||
public:
|
||||
void trigger(int event)
|
||||
{
|
||||
if (event == EVENT_SERIAL_CONNECTED) {
|
||||
serialConnected = true;
|
||||
} else if (event == EVENT_SERIAL_DISCONNECTED) {
|
||||
serialConnected = false;
|
||||
}
|
||||
};
|
||||
bool getState() { return serialConnected; };
|
||||
|
||||
private:
|
||||
bool serialConnected = false;
|
||||
};
|
||||
extern FakeFsm powerFSM;
|
||||
void PowerFSM_setup();
|
||||
|
||||
#else
|
||||
#include <Fsm.h>
|
||||
extern Fsm powerFSM;
|
||||
extern State stateON, statePOWER, stateSERIAL, stateDARK;
|
||||
|
||||
void PowerFSM_setup();
|
||||
#endif
|
||||
@@ -18,6 +18,7 @@ class PowerFSMThread : public OSThread
|
||||
protected:
|
||||
int32_t runOnce() override
|
||||
{
|
||||
#if !EXCLUDE_POWER_FSM
|
||||
powerFSM.run_machine();
|
||||
|
||||
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
|
||||
@@ -35,6 +36,9 @@ class PowerFSMThread : public OSThread
|
||||
}
|
||||
|
||||
return 100;
|
||||
#else
|
||||
return INT32_MAX;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#include "NodeDB.h"
|
||||
|
||||
// Use the 'live' config flag to figure out if we should be showing this message
|
||||
static bool is_power_enabled(uint64_t m)
|
||||
bool PowerMon::is_power_enabled(uint64_t m)
|
||||
{
|
||||
return (m & config.power.powermon_enables) ? true : false;
|
||||
// FIXME: VERY STRANGE BUG: if I or in "force_enabled || " the flashed image on a rak4631 is not accepted by the bootloader as
|
||||
// valid!!! Possibly a linker/gcc/bootloader bug somewhere?
|
||||
return ((m & config.power.powermon_enables) ? true : false);
|
||||
}
|
||||
|
||||
void PowerMon::setState(_meshtastic_PowerMon_State state, const char *reason)
|
||||
|
||||
@@ -17,6 +17,13 @@ class PowerMon
|
||||
{
|
||||
uint64_t states = 0UL;
|
||||
|
||||
friend class PowerStressModule;
|
||||
|
||||
/**
|
||||
* If stress testing we always want all events logged
|
||||
*/
|
||||
bool force_enabled = false;
|
||||
|
||||
public:
|
||||
PowerMon() {}
|
||||
|
||||
@@ -27,6 +34,9 @@ class PowerMon
|
||||
private:
|
||||
// Emit the coded log message
|
||||
void emitLog(const char *reason);
|
||||
|
||||
// Use the 'live' config flag to figure out if we should be showing this message
|
||||
bool is_power_enabled(uint64_t m);
|
||||
};
|
||||
|
||||
extern PowerMon *powerMon;
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
#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, but used for pure SX127x
|
||||
#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -38,8 +38,9 @@ size_t RedirectablePrint::write(uint8_t c)
|
||||
#ifdef USE_SEGGER
|
||||
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
|
||||
#endif
|
||||
|
||||
if (!config.has_lora || config.device.serial_enabled)
|
||||
// Account for legacy config transition
|
||||
bool serialEnabled = config.has_security ? config.security.serial_enabled : config.device.serial_enabled;
|
||||
if (!config.has_lora || serialEnabled)
|
||||
dest->write(c);
|
||||
|
||||
return 1; // We always claim one was written, rather than trusting what the
|
||||
@@ -49,7 +50,17 @@ size_t RedirectablePrint::write(uint8_t c)
|
||||
size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_list arg)
|
||||
{
|
||||
va_list copy;
|
||||
#if ENABLE_JSON_LOGGING || ARCH_PORTDUINO
|
||||
static char printBuf[512];
|
||||
#else
|
||||
static char printBuf[160];
|
||||
#endif
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool color = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool color = true;
|
||||
#endif
|
||||
|
||||
va_copy(copy, arg);
|
||||
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
|
||||
@@ -66,7 +77,7 @@ size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_l
|
||||
if (!std::isprint(static_cast<unsigned char>(printBuf[f])) && printBuf[f] != '\n')
|
||||
printBuf[f] = '#';
|
||||
}
|
||||
if (logLevel != nullptr) {
|
||||
if (color && logLevel != nullptr) {
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||
Print::write("\u001b[34m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||
@@ -77,7 +88,9 @@ size_t RedirectablePrint::vprintf(const char *logLevel, const char *format, va_l
|
||||
Print::write("\u001b[31m", 6);
|
||||
}
|
||||
len = Print::write(printBuf, len);
|
||||
Print::write("\u001b[0m", 5);
|
||||
if (color && logLevel != nullptr) {
|
||||
Print::write("\u001b[0m", 5);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -87,17 +100,27 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
|
||||
// Cope with 0 len format strings, but look for new line terminator
|
||||
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
|
||||
#ifdef ARCH_PORTDUINO
|
||||
bool color = !settingsMap[ascii_logs];
|
||||
#else
|
||||
bool color = true;
|
||||
#endif
|
||||
|
||||
// If we are the first message on a report, include the header
|
||||
if (!isContinuationMessage) {
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||
Print::write("\u001b[34m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||
Print::write("\u001b[32m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
||||
Print::write("\u001b[33m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
|
||||
Print::write("\u001b[31m", 6);
|
||||
if (color) {
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||
Print::write("\u001b[34m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||
Print::write("\u001b[32m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
||||
Print::write("\u001b[33m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
|
||||
Print::write("\u001b[31m", 6);
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
|
||||
Print::write("\u001b[35m", 6);
|
||||
}
|
||||
|
||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
|
||||
if (rtc_sec > 0) {
|
||||
long hms = rtc_sec % SEC_PER_DAY;
|
||||
@@ -111,17 +134,33 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
||||
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||
#ifdef ARCH_PORTDUINO
|
||||
::printf("%s \u001b[0m| %02d:%02d:%02d %u ", logLevel, hour, min, sec, millis() / 1000);
|
||||
::printf("%s ", logLevel);
|
||||
if (color) {
|
||||
::printf("\u001b[0m");
|
||||
}
|
||||
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||
#else
|
||||
printf("%s \u001b[0m| %02d:%02d:%02d %u ", logLevel, hour, min, sec, millis() / 1000);
|
||||
printf("%s ", logLevel);
|
||||
if (color) {
|
||||
printf("\u001b[0m");
|
||||
}
|
||||
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||
#endif
|
||||
} else
|
||||
} else {
|
||||
#ifdef ARCH_PORTDUINO
|
||||
::printf("%s \u001b[0m| ??:??:?? %u ", logLevel, millis() / 1000);
|
||||
::printf("%s ", logLevel);
|
||||
if (color) {
|
||||
::printf("\u001b[0m");
|
||||
}
|
||||
::printf("| ??:??:?? %u ", millis() / 1000);
|
||||
#else
|
||||
printf("%s \u001b[0m| ??:??:?? %u ", logLevel, millis() / 1000);
|
||||
printf("%s ", logLevel);
|
||||
if (color) {
|
||||
printf("\u001b[0m");
|
||||
}
|
||||
printf("| ??:??:?? %u ", millis() / 1000);
|
||||
#endif
|
||||
|
||||
}
|
||||
auto thread = concurrency::OSThread::currentThread;
|
||||
if (thread) {
|
||||
print("[");
|
||||
@@ -174,7 +213,7 @@ void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format,
|
||||
void RedirectablePrint::log_to_ble(const char *logLevel, const char *format, va_list arg)
|
||||
{
|
||||
#if !MESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
if (config.bluetooth.device_logging_enabled && !pauseBluetoothLogging) {
|
||||
if (config.security.debug_log_api_enabled && !pauseBluetoothLogging) {
|
||||
bool isBleConnected = false;
|
||||
#ifdef ARCH_ESP32
|
||||
isBleConnected = nimbleBluetooth && nimbleBluetooth->isActive() && nimbleBluetooth->isConnected();
|
||||
@@ -244,7 +283,21 @@ meshtastic_LogRecord_Level RedirectablePrint::getLogLevel(const char *logLevel)
|
||||
|
||||
void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
{
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#if ARCH_PORTDUINO
|
||||
// level trace is special, two possible ways to handle it.
|
||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||
if (settingsStrings[traceFilename] != "") {
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
try {
|
||||
traceFile << va_arg(arg, char *) << std::endl;
|
||||
} catch (const std::ios_base::failure &e) {
|
||||
}
|
||||
va_end(arg);
|
||||
}
|
||||
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
|
||||
return;
|
||||
}
|
||||
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||
return;
|
||||
else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||
@@ -330,4 +383,4 @@ std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)
|
||||
break;
|
||||
}
|
||||
return std::string(formatted.get());
|
||||
}
|
||||
}
|
||||
|
||||
105
src/SafeFile.cpp
Normal file
105
src/SafeFile.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#include "SafeFile.h"
|
||||
|
||||
#ifdef FSCom
|
||||
|
||||
// Only way to work on both esp32 and nrf52
|
||||
static File openFile(const char *filename, bool fullAtomic)
|
||||
{
|
||||
if (!fullAtomic)
|
||||
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
|
||||
|
||||
String filenameTmp = filename;
|
||||
filenameTmp += ".tmp";
|
||||
|
||||
// clear any previous LFS errors
|
||||
lfs_assert_failed = false;
|
||||
|
||||
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||
}
|
||||
|
||||
SafeFile::SafeFile(const char *_filename, bool fullAtomic)
|
||||
: filename(_filename), f(openFile(_filename, fullAtomic)), fullAtomic(fullAtomic)
|
||||
{
|
||||
}
|
||||
|
||||
size_t SafeFile::write(uint8_t ch)
|
||||
{
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
hash ^= ch;
|
||||
return f.write(ch);
|
||||
}
|
||||
|
||||
size_t SafeFile::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
hash ^= buffer[i];
|
||||
}
|
||||
return f.write((uint8_t const *)buffer, size); // This nasty cast is _IMPORTANT_ otherwise the correct adafruit method does
|
||||
// not get used (they made a mistake in their typing)
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically close the file (deleting any old versions) and readback the contents to confirm the hash matches
|
||||
*
|
||||
* @return false for failure
|
||||
*/
|
||||
bool SafeFile::close()
|
||||
{
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
f.close();
|
||||
if (!testReadback())
|
||||
return false;
|
||||
|
||||
// brief window of risk here ;-)
|
||||
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
||||
LOG_ERROR("Can't remove old pref file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
String filenameTmp = filename;
|
||||
filenameTmp += ".tmp";
|
||||
if (!renameFile(filenameTmp.c_str(), filename.c_str())) {
|
||||
LOG_ERROR("Error: can't rename new pref file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Read our (closed) tempfile back in and compare the hash
|
||||
bool SafeFile::testReadback()
|
||||
{
|
||||
bool lfs_failed = lfs_assert_failed;
|
||||
lfs_assert_failed = false;
|
||||
|
||||
String filenameTmp = filename;
|
||||
filenameTmp += ".tmp";
|
||||
auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ);
|
||||
if (!f2) {
|
||||
LOG_ERROR("Can't open tmp file for readback\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
uint8_t test_hash = 0;
|
||||
while ((c = f2.read()) >= 0) {
|
||||
test_hash ^= (uint8_t)c;
|
||||
}
|
||||
f2.close();
|
||||
|
||||
if (test_hash != hash) {
|
||||
LOG_ERROR("Readback failed hash mismatch\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return !lfs_failed;
|
||||
}
|
||||
|
||||
#endif
|
||||
49
src/SafeFile.h
Normal file
49
src/SafeFile.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include "FSCommon.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef FSCom
|
||||
|
||||
/**
|
||||
* This class provides 'safe'/paranoid file writing.
|
||||
*
|
||||
* Some of our filesystems (in particular the nrf52) may have bugs beneath our layer. Therefore we want to
|
||||
* be very careful about how we write files. This class provides a restricted (Stream only) writing API for writing to files.
|
||||
*
|
||||
* Notably:
|
||||
* - we keep a simple xor hash of all characters that were written.
|
||||
* - We do not allow seeking (because we want to maintain our hash)
|
||||
* - we provide an close() method which is similar to close but returns false if we were unable to successfully write the
|
||||
* file. Also this method
|
||||
* - atomically replaces any old version of the file on the disk with our new file (after first rereading the file from the disk
|
||||
* to confirm the hash matches)
|
||||
* - Some files are super huge so we can't do the full atomic rename/copy (because of filesystem size limits). If !fullAtomic
|
||||
* then we still do the readback to verify file is valid so higher level code can handle failures.
|
||||
*/
|
||||
class SafeFile : public Print
|
||||
{
|
||||
public:
|
||||
SafeFile(char const *filepath, bool fullAtomic = false);
|
||||
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Atomically close the file (deleting any old versions) and readback the contents to confirm the hash matches
|
||||
*
|
||||
* @return false for failure
|
||||
*/
|
||||
bool close();
|
||||
|
||||
private:
|
||||
/// Read our (closed) tempfile back in and compare the hash
|
||||
bool testReadback();
|
||||
|
||||
String filename;
|
||||
File f;
|
||||
bool fullAtomic;
|
||||
uint8_t hash = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "SerialConsole.h"
|
||||
#include "Default.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "Throttle.h"
|
||||
#include "configuration.h"
|
||||
#include "time.h"
|
||||
|
||||
@@ -47,7 +49,7 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
|
||||
#if defined(ARCH_NRF52) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARCH_RP2040)
|
||||
time_t timeout = millis();
|
||||
while (!Port) {
|
||||
if ((millis() - timeout) < 5000) {
|
||||
if (Throttle::isWithinTimespanMs(timeout, FIVE_SECONDS_MS)) {
|
||||
delay(100);
|
||||
} else {
|
||||
break;
|
||||
@@ -72,8 +74,7 @@ void SerialConsole::flush()
|
||||
// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
|
||||
bool SerialConsole::checkIsConnected()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT;
|
||||
return Throttle::isWithinTimespanMs(lastContactMsec, SERIAL_CONNECTION_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +84,7 @@ bool SerialConsole::checkIsConnected()
|
||||
bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
|
||||
{
|
||||
// only talk to the API once the configuration has been loaded and we're sure the serial port is not disabled.
|
||||
if (config.has_lora && config.device.serial_enabled) {
|
||||
if (config.has_lora && config.security.serial_enabled) {
|
||||
// Switch to protobufs for log messages
|
||||
usingProtobufs = true;
|
||||
canWrite = true;
|
||||
@@ -96,7 +97,7 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
|
||||
|
||||
void SerialConsole::log_to_serial(const char *logLevel, const char *format, va_list arg)
|
||||
{
|
||||
if (usingProtobufs) {
|
||||
if (usingProtobufs && config.security.debug_log_api_enabled) {
|
||||
meshtastic_LogRecord_Level ll = meshtastic_LogRecord_Level_UNSET; // default to unset
|
||||
switch (logLevel[0]) {
|
||||
case 'D':
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user